[RFC PATCH 3/3] erofs: add rust options
Yiyang Wu
toolmanp at tlmp.cc
Thu Aug 8 04:47:03 AEST 2024
This commit adds rust option in Kconfig. Note that currently when enabling
rust support, all extended features are disabled only basic operations
are supported.
Signed-off-by: Yiyang Wu <toolmanp at tlmp.cc>
---
fs/erofs/Kconfig | 11 +++
fs/erofs/Makefile | 1 +
fs/erofs/data.c | 83 +++++++++++++----
fs/erofs/dir.c | 20 +++-
fs/erofs/inode.c | 51 ++++++----
fs/erofs/internal.h | 3 +
fs/erofs/namei.c | 30 ++++--
fs/erofs/super.c | 223 ++++++++++++++++++++++++++++++++------------
8 files changed, 312 insertions(+), 110 deletions(-)
diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig
index 7dcdce660cac..46702df0b3d8 100644
--- a/fs/erofs/Kconfig
+++ b/fs/erofs/Kconfig
@@ -158,3 +158,14 @@ config EROFS_FS_PCPU_KTHREAD_HIPRI
at higher priority.
If unsure, say N.
+
+config EROFS_FS_RUST
+ bool "EROFS use RUST Replacement (EXPERIMENTAL)"
+ depends on EROFS_FS && RUST && !EROFS_FS_ZIP && !EROFS_FS_ONDEMAND && !EROFS_FS_XATTR
+ default n
+ help
+ This permits EROFS to use EXPERIMENTAL rust implementation for
+ EROFS. This is highly unstable and buggy and should be considered
+ as an experimental feature only.
+
+ IF SURE, say Y.
diff --git a/fs/erofs/Makefile b/fs/erofs/Makefile
index 097d672e6b14..a6e4f7f4d570 100644
--- a/fs/erofs/Makefile
+++ b/fs/erofs/Makefile
@@ -8,3 +8,4 @@ erofs-$(CONFIG_EROFS_FS_ZIP_LZMA) += decompressor_lzma.o
erofs-$(CONFIG_EROFS_FS_ZIP_DEFLATE) += decompressor_deflate.o
erofs-$(CONFIG_EROFS_FS_ZIP_ZSTD) += decompressor_zstd.o
erofs-$(CONFIG_EROFS_FS_ONDEMAND) += fscache.o
+erofs-$(CONFIG_EROFS_FS_RUST) += erofs_rust_helper.o erofs_rust.o
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index 1b7eba38ba1e..b45660112fd9 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -4,6 +4,10 @@
* https://www.huawei.com/
* Copyright (C) 2021, Alibaba Cloud
*/
+
+#ifdef CONFIG_EROFS_FS_RUST
+#include "erofs_rust_bindings.h"
+#endif
#include "internal.h"
#include <linux/sched/mm.h>
#include <trace/events/erofs.h>
@@ -189,6 +193,8 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
return err;
}
+#ifndef CONFIG_EROFS_FS_RUST
+
int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
{
struct erofs_dev_context *devs = EROFS_SB(sb)->devs;
@@ -230,8 +236,10 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
if (map->m_pa >= startoff &&
map->m_pa < startoff + length) {
map->m_pa -= startoff;
- map->m_bdev = dif->bdev_file ?
- file_bdev(dif->bdev_file) : NULL;
+ map->m_bdev =
+ dif->bdev_file ?
+ file_bdev(dif->bdev_file) :
+ NULL;
map->m_daxdev = dif->dax_dev;
map->m_dax_part_off = dif->dax_part_off;
map->m_fscache = dif->fscache;
@@ -244,7 +252,8 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
}
static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
- unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
+ unsigned int flags, struct iomap *iomap,
+ struct iomap *srcmap)
{
int ret;
struct super_block *sb = inode->i_sb;
@@ -258,7 +267,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
if (ret < 0)
return ret;
- mdev = (struct erofs_map_dev) {
+ mdev = (struct erofs_map_dev){
.m_deviceid = map.m_deviceid,
.m_pa = map.m_pa,
};
@@ -303,7 +312,8 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
}
static int erofs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
- ssize_t written, unsigned int flags, struct iomap *iomap)
+ ssize_t written, unsigned int flags,
+ struct iomap *iomap)
{
void *ptr = iomap->private;
@@ -322,6 +332,45 @@ static int erofs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
return written;
}
+#else
+
+static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
+ unsigned int flags, struct iomap *iomap,
+ struct iomap *srcmap)
+{
+ struct erofs_rust_map m;
+ m.m_la = offset;
+ erofs_iomap_begin_rust(inode, &m);
+
+ iomap->bdev = inode->i_sb->s_bdev;
+ iomap->flags = 0;
+ iomap->offset = m.m_la;
+ iomap->length = m.m_llen;
+
+ if (m.inline_data != NULL) {
+ iomap->type = IOMAP_INLINE;
+ iomap->inline_data = m.inline_data;
+ iomap->private = m.private;
+ } else {
+ iomap->type = IOMAP_MAPPED;
+ iomap->addr = m.m_pa;
+ iomap->private = NULL;
+ }
+ return 0;
+}
+
+static int erofs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
+ ssize_t written, unsigned int flags,
+ struct iomap *iomap)
+{
+ struct erofs_rust_map m = {
+ .private = iomap->private,
+ };
+ erofs_iomap_end_rust(&m);
+ return written;
+}
+#endif
+
static const struct iomap_ops erofs_iomap_ops = {
.iomap_begin = erofs_iomap_begin,
.iomap_end = erofs_iomap_end,
@@ -382,11 +431,12 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
blksize_mask = i_blocksize(inode) - 1;
if ((iocb->ki_pos | iov_iter_count(to) |
- iov_iter_alignment(to)) & blksize_mask)
+ iov_iter_alignment(to)) &
+ blksize_mask)
return -EINVAL;
- return iomap_dio_rw(iocb, to, &erofs_iomap_ops,
- NULL, 0, NULL, 0);
+ return iomap_dio_rw(iocb, to, &erofs_iomap_ops, NULL, 0, NULL,
+ 0);
}
return filemap_read(iocb, to, 0);
}
@@ -402,8 +452,7 @@ const struct address_space_operations erofs_raw_access_aops = {
};
#ifdef CONFIG_FS_DAX
-static vm_fault_t erofs_dax_huge_fault(struct vm_fault *vmf,
- unsigned int order)
+static vm_fault_t erofs_dax_huge_fault(struct vm_fault *vmf, unsigned int order)
{
return dax_iomap_fault(vmf, order, NULL, NULL, &erofs_iomap_ops);
}
@@ -414,8 +463,8 @@ static vm_fault_t erofs_dax_fault(struct vm_fault *vmf)
}
static const struct vm_operations_struct erofs_dax_vm_ops = {
- .fault = erofs_dax_fault,
- .huge_fault = erofs_dax_huge_fault,
+ .fault = erofs_dax_fault,
+ .huge_fault = erofs_dax_huge_fault,
};
static int erofs_file_mmap(struct file *file, struct vm_area_struct *vma)
@@ -431,13 +480,13 @@ static int erofs_file_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
#else
-#define erofs_file_mmap generic_file_readonly_mmap
+#define erofs_file_mmap generic_file_readonly_mmap
#endif
const struct file_operations erofs_file_fops = {
- .llseek = generic_file_llseek,
- .read_iter = erofs_file_read_iter,
- .mmap = erofs_file_mmap,
+ .llseek = generic_file_llseek,
+ .read_iter = erofs_file_read_iter,
+ .mmap = erofs_file_mmap,
.get_unmapped_area = thp_get_unmapped_area,
- .splice_read = filemap_splice_read,
+ .splice_read = filemap_splice_read,
};
diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c
index c3b90abdee37..b91e26181f5b 100644
--- a/fs/erofs/dir.c
+++ b/fs/erofs/dir.c
@@ -4,8 +4,15 @@
* https://www.huawei.com/
* Copyright (C) 2022, Alibaba Cloud
*/
+
+#ifdef CONFIG_EROFS_FS_RUST
+#include "erofs_rust_bindings.h"
+#endif
+
#include "internal.h"
+#ifndef CONFIG_EROFS_FS_RUST
+
static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
void *dentry_blk, struct erofs_dirent *de,
unsigned int nameoff0, unsigned int maxsize)
@@ -93,8 +100,15 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
return err < 0 ? err : 0;
}
+#endif
+
const struct file_operations erofs_dir_fops = {
- .llseek = generic_file_llseek,
- .read = generic_read_dir,
- .iterate_shared = erofs_readdir,
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+#ifdef CONFIG_EROFS_FS_RUST
+ .iterate_shared = erofs_readdir_rust,
+#else
+
+ .iterate_shared = erofs_readdir,
+#endif
};
diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
index 43c09aae2afc..22a9b5b24c31 100644
--- a/fs/erofs/inode.c
+++ b/fs/erofs/inode.c
@@ -8,8 +8,8 @@
#include <trace/events/erofs.h>
-static void *erofs_read_inode(struct erofs_buf *buf,
- struct inode *inode, unsigned int *ofs)
+static void *erofs_read_inode(struct erofs_buf *buf, struct inode *inode,
+ unsigned int *ofs)
{
struct super_block *sb = inode->i_sb;
struct erofs_sb_info *sbi = EROFS_SB(sb);
@@ -36,8 +36,8 @@ static void *erofs_read_inode(struct erofs_buf *buf,
dic = kaddr + *ofs;
ifmt = le16_to_cpu(dic->i_format);
if (ifmt & ~EROFS_I_ALL) {
- erofs_err(sb, "unsupported i_format %u of nid %llu",
- ifmt, vi->nid);
+ erofs_err(sb, "unsupported i_format %u of nid %llu", ifmt,
+ vi->nid);
err = -EOPNOTSUPP;
goto err_out;
}
@@ -66,11 +66,14 @@ static void *erofs_read_inode(struct erofs_buf *buf,
goto err_out;
}
memcpy(copied, dic, gotten);
- kaddr = erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr + 1),
+ kaddr = erofs_read_metabuf(buf, sb,
+ erofs_pos(sb, blkaddr + 1),
EROFS_KMAP);
if (IS_ERR(kaddr)) {
- erofs_err(sb, "failed to get inode payload block (nid: %llu), err %ld",
- vi->nid, PTR_ERR(kaddr));
+ erofs_err(
+ sb,
+ "failed to get inode payload block (nid: %llu), err %ld",
+ vi->nid, PTR_ERR(kaddr));
kfree(copied);
return kaddr;
}
@@ -105,11 +108,11 @@ static void *erofs_read_inode(struct erofs_buf *buf,
set_nlink(inode, le16_to_cpu(dic->i_nlink));
/* use build time for compact inodes */
inode_set_ctime(inode, sbi->build_time, sbi->build_time_nsec);
-
inode->i_size = le32_to_cpu(dic->i_size);
break;
default:
- erofs_err(sb, "unsupported on-disk inode version %u of nid %llu",
+ erofs_err(sb,
+ "unsupported on-disk inode version %u of nid %llu",
erofs_inode_version(ifmt), vi->nid);
err = -EOPNOTSUPP;
goto err_out;
@@ -148,11 +151,12 @@ static void *erofs_read_inode(struct erofs_buf *buf,
err = -EOPNOTSUPP;
goto err_out;
}
- vi->chunkbits = sb->s_blocksize_bits +
+ vi->chunkbits =
+ sb->s_blocksize_bits +
(vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
}
- inode_set_mtime_to_ts(inode,
- inode_set_atime_to_ts(inode, inode_get_ctime(inode)));
+ inode_set_mtime_to_ts(
+ inode, inode_set_atime_to_ts(inode, inode_get_ctime(inode)));
inode->i_flags &= ~S_DAX;
if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
@@ -182,8 +186,8 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
char *lnk;
/* if it cannot be handled with fast symlink scheme */
- if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
- inode->i_size >= bsz || inode->i_size < 0) {
+ if (vi->datalayout != EROFS_INODE_FLAT_INLINE || inode->i_size >= bsz ||
+ inode->i_size < 0) {
inode->i_op = &erofs_symlink_iops;
return 0;
}
@@ -226,6 +230,7 @@ static int erofs_fill_inode(struct inode *inode)
return PTR_ERR(kaddr);
/* setup the new inode */
+
switch (inode->i_mode & S_IFMT) {
case S_IFREG:
inode->i_op = &erofs_generic_iops;
@@ -259,9 +264,9 @@ static int erofs_fill_inode(struct inode *inode)
if (erofs_inode_is_data_compressed(vi->datalayout)) {
#ifdef CONFIG_EROFS_FS_ZIP
- DO_ONCE_LITE_IF(inode->i_blkbits != PAGE_SHIFT,
- erofs_info, inode->i_sb,
- "EXPERIMENTAL EROFS subpage compressed block support in use. Use at your own risk!");
+ DO_ONCE_LITE_IF(
+ inode->i_blkbits != PAGE_SHIFT, erofs_info, inode->i_sb,
+ "EXPERIMENTAL EROFS subpage compressed block support in use. Use at your own risk!");
inode->i_mapping->a_ops = &z_erofs_aops;
err = 0;
goto out_unlock;
@@ -334,14 +339,14 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
unsigned int query_flags)
{
struct inode *const inode = d_inode(path->dentry);
+#ifndef CONFIG_EROFS_FS_RUST
bool compressed =
erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout);
if (compressed)
stat->attributes |= STATX_ATTR_COMPRESSED;
stat->attributes |= STATX_ATTR_IMMUTABLE;
- stat->attributes_mask |= (STATX_ATTR_COMPRESSED |
- STATX_ATTR_IMMUTABLE);
+ stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_IMMUTABLE);
/*
* Return the DIO alignment restrictions if requested.
@@ -357,27 +362,35 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
stat->dio_offset_align = stat->dio_mem_align;
}
}
+
+#endif
generic_fillattr(idmap, request_mask, inode, stat);
return 0;
}
const struct inode_operations erofs_generic_iops = {
.getattr = erofs_getattr,
+#ifndef CONFIG_EROFS_FS_RUST
.listxattr = erofs_listxattr,
.get_inode_acl = erofs_get_acl,
+#endif
.fiemap = erofs_fiemap,
};
const struct inode_operations erofs_symlink_iops = {
.get_link = page_get_link,
.getattr = erofs_getattr,
+#ifndef CONFIG_EROFS_FS_RUST
.listxattr = erofs_listxattr,
.get_inode_acl = erofs_get_acl,
+#endif
};
const struct inode_operations erofs_fast_symlink_iops = {
.get_link = simple_get_link,
.getattr = erofs_getattr,
+#ifndef CONFIG_EROFS_FS_RUST
.listxattr = erofs_listxattr,
.get_inode_acl = erofs_get_acl,
+#endif
};
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 45dc15ebd870..aa48f8abc724 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -19,6 +19,9 @@
#include <linux/vmalloc.h>
#include <linux/iomap.h>
#include "erofs_fs.h"
+#ifdef CONFIG_EROFS_FS_RUST
+#include "erofs_rust_bindings.h"
+#endif
/* redefine pr_fmt "erofs: " */
#undef pr_fmt
diff --git a/fs/erofs/namei.c b/fs/erofs/namei.c
index c94d0c1608a8..12fd429adad4 100644
--- a/fs/erofs/namei.c
+++ b/fs/erofs/namei.c
@@ -4,6 +4,7 @@
* https://www.huawei.com/
* Copyright (C) 2022, Alibaba Cloud
*/
+
#include "xattr.h"
#include <trace/events/erofs.h>
@@ -40,7 +41,7 @@ static inline int erofs_dirnamecmp(const struct erofs_qstr *qn,
return qn->name[i] == '\0' ? 0 : 1;
}
-#define nameoff_from_disk(off, sz) (le16_to_cpu(off) & ((sz) - 1))
+#define nameoff_from_disk(off, sz) (le16_to_cpu(off) & ((sz) - 1))
static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
u8 *data,
@@ -58,15 +59,16 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
while (head <= back) {
const int mid = head + (back - head) / 2;
- const int nameoff = nameoff_from_disk(de[mid].nameoff,
- dirblksize);
+ const int nameoff =
+ nameoff_from_disk(de[mid].nameoff, dirblksize);
unsigned int matched = min(startprfx, endprfx);
struct erofs_qstr dname = {
.name = data + nameoff,
.end = mid >= ndirents - 1 ?
- data + dirblksize :
- data + nameoff_from_disk(de[mid + 1].nameoff,
- dirblksize)
+ data + dirblksize :
+ data + nameoff_from_disk(
+ de[mid + 1].nameoff,
+ dirblksize)
};
/* string comparison without already matched prefix */
@@ -87,7 +89,8 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
}
static void *erofs_find_target_block(struct erofs_buf *target,
- struct inode *dir, struct erofs_qstr *name, int *_ndirents)
+ struct inode *dir, struct erofs_qstr *name,
+ int *_ndirents)
{
unsigned int bsz = i_blocksize(dir);
int head = 0, back = erofs_iblks(dir) - 1;
@@ -124,7 +127,8 @@ static void *erofs_find_target_block(struct erofs_buf *target,
if (ndirents == 1)
dname.end = (u8 *)de + bsz;
else
- dname.end = (u8 *)de +
+ dname.end =
+ (u8 *)de +
nameoff_from_disk(de[1].nameoff, bsz);
/* string comparison without already matched prefix */
@@ -150,7 +154,7 @@ static void *erofs_find_target_block(struct erofs_buf *target,
*_ndirents = ndirents;
continue;
}
-out: /* free if the candidate is valid */
+out: /* free if the candidate is valid */
if (!IS_ERR(candidate))
erofs_put_metabuf(target);
return de;
@@ -190,6 +194,7 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
return PTR_ERR_OR_ZERO(de);
}
+#ifndef CONFIG_EROFS_FS_RUST
static struct dentry *erofs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags)
{
@@ -214,11 +219,16 @@ static struct dentry *erofs_lookup(struct inode *dir, struct dentry *dentry,
inode = erofs_iget(dir->i_sb, nid);
return d_splice_alias(inode, dentry);
}
+#endif
const struct inode_operations erofs_dir_iops = {
- .lookup = erofs_lookup,
.getattr = erofs_getattr,
+#ifdef CONFIG_EROFS_FS_RUST
+ .lookup = erofs_lookup_rust,
+#else
.listxattr = erofs_listxattr,
.get_inode_acl = erofs_get_acl,
+ .lookup = erofs_lookup,
+#endif
.fiemap = erofs_fiemap,
};
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 6cb5c8916174..f6963e31d516 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -4,6 +4,7 @@
* https://www.huawei.com/
* Copyright (C) 2021, Alibaba Cloud
*/
+#include "erofs_rust_bindings.h"
#include <linux/statfs.h>
#include <linux/seq_file.h>
#include <linux/crc32c.h>
@@ -51,6 +52,7 @@ void _erofs_info(struct super_block *sb, const char *func, const char *fmt, ...)
va_end(args);
}
+#ifndef CONFIG_EROFS_FS_RUST
static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
{
size_t len = 1 << EROFS_SB(sb)->blkszbits;
@@ -71,8 +73,8 @@ static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
kfree(dsb);
if (crc != expected_crc) {
- erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected",
- crc, expected_crc);
+ erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected", crc,
+ expected_crc);
return -EBADMSG;
}
return 0;
@@ -85,27 +87,35 @@ static void erofs_inode_init_once(void *ptr)
inode_init_once(&vi->vfs_inode);
}
+#endif
+
static struct inode *erofs_alloc_inode(struct super_block *sb)
{
- struct erofs_inode *vi =
- alloc_inode_sb(sb, erofs_inode_cachep, GFP_KERNEL);
+ void *vi = alloc_inode_sb(sb, erofs_inode_cachep, GFP_KERNEL);
if (!vi)
return NULL;
- /* zero out everything except vfs_inode */
+ /* zero out everything except vfs_inode */
+#ifdef CONFIG_EROFS_FS_RUST
+ return (struct inode *)(vi + EROFS_INODE_OFFSET);
+#else
memset(vi, 0, offsetof(struct erofs_inode, vfs_inode));
- return &vi->vfs_inode;
+ return &((struct erofs_inode *)vi)->vfs_inode;
+#endif
}
static void erofs_free_inode(struct inode *inode)
{
- struct erofs_inode *vi = EROFS_I(inode);
-
if (inode->i_op == &erofs_fast_symlink_iops)
kfree(inode->i_link);
+#ifndef CONFIG_EROFS_FS_RUST
+ struct erofs_inode *vi = EROFS_I(inode);
kfree(vi->xattr_shared_xattrs);
kmem_cache_free(erofs_inode_cachep, vi);
+#else
+ kmem_cache_free(erofs_inode_cachep, (void *)inode - EROFS_INODE_OFFSET);
+#endif
}
/* read variable-sized metadata, offset will be aligned by 4-byte */
@@ -143,6 +153,8 @@ void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
return buffer;
}
+#ifndef CONFIG_EROFS_FS_RUST
+
#ifndef CONFIG_EROFS_FS_ZIP
static int z_erofs_parse_cfgs(struct super_block *sb,
struct erofs_super_block *dsb)
@@ -184,12 +196,12 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
dif->fscache = fscache;
} else if (!sbi->devs->flatdev) {
bdev_file = bdev_file_open_by_path(dif->path, BLK_OPEN_READ,
- sb->s_type, NULL);
+ sb->s_type, NULL);
if (IS_ERR(bdev_file))
return PTR_ERR(bdev_file);
dif->bdev_file = bdev_file;
- dif->dax_dev = fs_dax_get_by_bdev(file_bdev(bdev_file),
- &dif->dax_part_off, NULL, NULL);
+ dif->dax_dev = fs_dax_get_by_bdev(
+ file_bdev(bdev_file), &dif->dax_part_off, NULL, NULL);
}
dif->blocks = le32_to_cpu(dis->blocks);
@@ -244,7 +256,8 @@ static int erofs_scan_devices(struct super_block *sb,
break;
}
- err = idr_alloc(&sbi->devs->tree, dif, 0, 0, GFP_KERNEL);
+ err = idr_alloc(&sbi->devs->tree, dif, 0, 0,
+ GFP_KERNEL);
if (err < 0) {
kfree(dif);
break;
@@ -282,7 +295,7 @@ static int erofs_read_superblock(struct super_block *sb)
goto out;
}
- sbi->blkszbits = dsb->blkszbits;
+ sbi->blkszbits = dsb->blkszbits;
if (sbi->blkszbits < 9 || sbi->blkszbits > PAGE_SHIFT) {
erofs_err(sb, "blkszbits %u isn't supported", sbi->blkszbits);
goto out;
@@ -333,7 +346,7 @@ static int erofs_read_superblock(struct super_block *sb)
ret = strscpy(sbi->volume_name, dsb->volume_name,
sizeof(dsb->volume_name));
- if (ret < 0) { /* -E2BIG */
+ if (ret < 0) { /* -E2BIG */
erofs_err(sb, "bad volume name without NIL terminator");
ret = -EFSCORRUPTED;
goto out;
@@ -348,7 +361,9 @@ static int erofs_read_superblock(struct super_block *sb)
ret = erofs_scan_devices(sb, dsb);
if (erofs_is_fscache_mode(sb))
- erofs_info(sb, "EXPERIMENTAL fscache-based on-demand read feature in use. Use at your own risk!");
+ erofs_info(
+ sb,
+ "EXPERIMENTAL fscache-based on-demand read feature in use. Use at your own risk!");
out:
erofs_put_metabuf(&buf);
return ret;
@@ -369,6 +384,8 @@ static void erofs_default_options(struct erofs_sb_info *sbi)
#endif
}
+#endif
+
enum {
Opt_user_xattr,
Opt_acl,
@@ -382,31 +399,32 @@ enum {
};
static const struct constant_table erofs_param_cache_strategy[] = {
- {"disabled", EROFS_ZIP_CACHE_DISABLED},
- {"readahead", EROFS_ZIP_CACHE_READAHEAD},
- {"readaround", EROFS_ZIP_CACHE_READAROUND},
+ { "disabled", EROFS_ZIP_CACHE_DISABLED },
+ { "readahead", EROFS_ZIP_CACHE_READAHEAD },
+ { "readaround", EROFS_ZIP_CACHE_READAROUND },
{}
};
static const struct constant_table erofs_dax_param_enums[] = {
- {"always", EROFS_MOUNT_DAX_ALWAYS},
- {"never", EROFS_MOUNT_DAX_NEVER},
+ { "always", EROFS_MOUNT_DAX_ALWAYS },
+ { "never", EROFS_MOUNT_DAX_NEVER },
{}
};
static const struct fs_parameter_spec erofs_fs_parameters[] = {
- fsparam_flag_no("user_xattr", Opt_user_xattr),
- fsparam_flag_no("acl", Opt_acl),
- fsparam_enum("cache_strategy", Opt_cache_strategy,
+ fsparam_flag_no("user_xattr", Opt_user_xattr),
+ fsparam_flag_no("acl", Opt_acl),
+ fsparam_enum("cache_strategy", Opt_cache_strategy,
erofs_param_cache_strategy),
- fsparam_flag("dax", Opt_dax),
- fsparam_enum("dax", Opt_dax_enum, erofs_dax_param_enums),
- fsparam_string("device", Opt_device),
- fsparam_string("fsid", Opt_fsid),
- fsparam_string("domain_id", Opt_domain_id),
+ fsparam_flag("dax", Opt_dax),
+ fsparam_enum("dax", Opt_dax_enum, erofs_dax_param_enums),
+ fsparam_string("device", Opt_device),
+ fsparam_string("fsid", Opt_fsid),
+ fsparam_string("domain_id", Opt_domain_id),
{}
};
+#ifndef CONFIG_EROFS_FS_RUST
static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode)
{
#ifdef CONFIG_FS_DAX
@@ -431,19 +449,25 @@ static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode)
#endif
}
+#endif
+
static int erofs_fc_parse_param(struct fs_context *fc,
struct fs_parameter *param)
{
+#ifndef CONFIG_EROFS_FS_RUST
+
struct erofs_sb_info *sbi = fc->s_fs_info;
- struct fs_parse_result result;
struct erofs_device_info *dif;
- int opt, ret;
+#endif
+ struct fs_parse_result result;
+ int opt, ret;
opt = fs_parse(fc, erofs_fs_parameters, param, &result);
if (opt < 0)
return opt;
-
switch (opt) {
+#ifndef CONFIG_EROFS_FS_RUST
+
case Opt_user_xattr:
#ifdef CONFIG_EROFS_FS_XATTR
if (result.boolean)
@@ -468,7 +492,8 @@ static int erofs_fc_parse_param(struct fs_context *fc,
#ifdef CONFIG_EROFS_FS_ZIP
sbi->opt.cache_strategy = result.uint_32;
#else
- errorfc(fc, "compression not supported, cache_strategy ignored");
+ errorfc(fc,
+ "compression not supported, cache_strategy ignored");
#endif
break;
case Opt_dax:
@@ -514,35 +539,51 @@ static int erofs_fc_parse_param(struct fs_context *fc,
#else
case Opt_fsid:
case Opt_domain_id:
- errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
+ errorfc(fc, "%s option not supported",
+ erofs_fs_parameters[opt].name);
break;
+
+ default:
+
#endif
+#else
default:
+ (void)ret;
+#endif
return -ENOPARAM;
}
return 0;
}
-static struct inode *erofs_nfs_get_inode(struct super_block *sb,
- u64 ino, u32 generation)
+static struct inode *erofs_nfs_get_inode(struct super_block *sb, u64 ino,
+ u32 generation)
{
+#ifdef CONFIG_EROFS_FS_RUST
+ return erofs_iget_rust(sb, ino);
+#else
return erofs_iget(sb, ino);
+#endif
}
static struct dentry *erofs_fh_to_dentry(struct super_block *sb,
- struct fid *fid, int fh_len, int fh_type)
+ struct fid *fid, int fh_len,
+ int fh_type)
{
return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
erofs_nfs_get_inode);
}
static struct dentry *erofs_fh_to_parent(struct super_block *sb,
- struct fid *fid, int fh_len, int fh_type)
+ struct fid *fid, int fh_len,
+ int fh_type)
{
return generic_fh_to_parent(sb, fid, fh_len, fh_type,
erofs_nfs_get_inode);
}
+#ifdef CONFIG_EROFS_FS_RUST
+
+#else
static struct dentry *erofs_get_parent(struct dentry *child)
{
erofs_nid_t nid;
@@ -555,21 +596,29 @@ static struct dentry *erofs_get_parent(struct dentry *child)
return d_obtain_alias(erofs_iget(child->d_sb, nid));
}
+#endif
+
static const struct export_operations erofs_export_ops = {
.encode_fh = generic_encode_ino32_fh,
.fh_to_dentry = erofs_fh_to_dentry,
.fh_to_parent = erofs_fh_to_parent,
+#ifdef CONFIG_EROFS_FS_RUST
+ .get_parent = erofs_get_parent_rust,
+#else
.get_parent = erofs_get_parent,
+#endif
};
+#ifndef CONFIG_EROFS_FS_RUST
+
static void erofs_set_sysfs_name(struct super_block *sb)
{
struct erofs_sb_info *sbi = EROFS_SB(sb);
if (erofs_is_fscache_mode(sb)) {
if (sbi->domain_id)
- super_set_sysfs_name_generic(sb, "%s,%s",sbi->domain_id,
- sbi->fsid);
+ super_set_sysfs_name_generic(sb, "%s,%s",
+ sbi->domain_id, sbi->fsid);
else
super_set_sysfs_name_generic(sb, "%s", sbi->fsid);
return;
@@ -606,9 +655,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
return -EINVAL;
}
- sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev,
- &sbi->dax_part_off,
- NULL, NULL);
+ sbi->dax_dev = fs_dax_get_by_bdev(
+ sb->s_bdev, &sbi->dax_part_off, NULL, NULL);
}
err = erofs_read_superblock(sb);
@@ -628,7 +676,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
if (test_opt(&sbi->opt, DAX_ALWAYS)) {
if (!sbi->dax_dev) {
- errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
+ errorfc(fc,
+ "DAX unsupported by block device. Turning off DAX.");
clear_opt(&sbi->opt, DAX_ALWAYS);
} else if (sbi->blkszbits != PAGE_SHIFT) {
errorfc(fc, "unsupported blocksize for DAX");
@@ -679,6 +728,7 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
return err;
err = erofs_xattr_prefixes_init(sb);
+
if (err)
return err;
@@ -690,18 +740,38 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
return 0;
}
+#else
+static int erofs_fc_fill_super_rust(struct super_block *sb,
+ struct fs_context *fc)
+{
+ sb->s_magic = EROFS_SUPER_MAGIC;
+ sb->s_flags |= SB_RDONLY | SB_NOATIME;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_op = &erofs_sops;
+ sb->s_time_gran = 1;
+ sb->s_xattr = NULL;
+ sb->s_export_op = &erofs_export_ops;
+ sb->s_fs_info = erofs_alloc_sbi_rust(sb, sb->s_bdev->bd_mapping);
+ sb->s_root = erofs_make_root_rust(sb);
+ return 0;
+}
+#define erofs_fc_fill_super erofs_fc_fill_super_rust
+#endif
+
static int erofs_fc_get_tree(struct fs_context *fc)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct erofs_sb_info *sbi = fc->s_fs_info;
-
if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
return get_tree_nodev(fc, erofs_fc_fill_super);
+#endif
return get_tree_bdev(fc, erofs_fc_fill_super);
}
static int erofs_fc_reconfigure(struct fs_context *fc)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct super_block *sb = fc->root->d_sb;
struct erofs_sb_info *sbi = EROFS_SB(sb);
struct erofs_sb_info *new_sbi = fc->s_fs_info;
@@ -718,10 +788,12 @@ static int erofs_fc_reconfigure(struct fs_context *fc)
sbi->opt = new_sbi->opt;
+#endif
fc->sb_flags |= SB_RDONLY;
return 0;
}
+#ifndef CONFIG_EROFS_FS_RUST
static int erofs_release_device_info(int id, void *ptr, void *data)
{
struct erofs_device_info *dif = ptr;
@@ -758,15 +830,23 @@ static void erofs_fc_free(struct fs_context *fc)
kfree(sbi);
}
+#else
+
+static void erofs_fc_free(struct fs_context *fc)
+{
+}
+
+#endif
static const struct fs_context_operations erofs_context_ops = {
- .parse_param = erofs_fc_parse_param,
- .get_tree = erofs_fc_get_tree,
- .reconfigure = erofs_fc_reconfigure,
- .free = erofs_fc_free,
+ .parse_param = erofs_fc_parse_param,
+ .get_tree = erofs_fc_get_tree,
+ .reconfigure = erofs_fc_reconfigure,
+ .free = erofs_fc_free,
};
static int erofs_init_fs_context(struct fs_context *fc)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct erofs_sb_info *sbi;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
@@ -783,12 +863,14 @@ static int erofs_init_fs_context(struct fs_context *fc)
idr_init(&sbi->devs->tree);
init_rwsem(&sbi->devs->rwsem);
erofs_default_options(sbi);
+#endif
fc->ops = &erofs_context_ops;
return 0;
}
static void erofs_kill_sb(struct super_block *sb)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct erofs_sb_info *sbi = EROFS_SB(sb);
if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
@@ -802,11 +884,15 @@ static void erofs_kill_sb(struct super_block *sb)
kfree(sbi->fsid);
kfree(sbi->domain_id);
kfree(sbi);
+#else
+ erofs_free_sbi_rust(sb);
sb->s_fs_info = NULL;
+#endif
}
static void erofs_put_super(struct super_block *sb)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct erofs_sb_info *const sbi = EROFS_SB(sb);
DBG_BUGON(!sbi);
@@ -823,14 +909,15 @@ static void erofs_put_super(struct super_block *sb)
erofs_free_dev_context(sbi->devs);
sbi->devs = NULL;
erofs_fscache_unregister_fs(sb);
+#endif
}
static struct file_system_type erofs_fs_type = {
- .owner = THIS_MODULE,
- .name = "erofs",
+ .owner = THIS_MODULE,
+ .name = "erofs",
.init_fs_context = erofs_init_fs_context,
- .kill_sb = erofs_kill_sb,
- .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
+ .kill_sb = erofs_kill_sb,
+ .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
};
MODULE_ALIAS_FS("erofs");
@@ -840,10 +927,17 @@ static int __init erofs_module_init(void)
erofs_check_ondisk_layout_definitions();
- erofs_inode_cachep = kmem_cache_create("erofs_inode",
- sizeof(struct erofs_inode), 0,
- SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT,
- erofs_inode_init_once);
+#ifdef CONFIG_EROFS_FS_RUST
+ erofs_inode_cachep =
+ kmem_cache_create("erofs_inode", EROFS_INODE_SIZE, 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT,
+ erofs_inode_init_once_rust);
+#else
+ erofs_inode_cachep = kmem_cache_create(
+ "erofs_inode", sizeof(struct erofs_inode), 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT, erofs_inode_init_once);
+#endif
+
if (!erofs_inode_cachep)
return -ENOMEM;
@@ -891,6 +985,7 @@ static void __exit erofs_module_exit(void)
static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct super_block *sb = dentry->d_sb;
struct erofs_sb_info *sbi = EROFS_SB(sb);
@@ -903,26 +998,31 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_namelen = EROFS_NAME_LEN;
if (uuid_is_null(&sb->s_uuid))
- buf->f_fsid = u64_to_fsid(erofs_is_fscache_mode(sb) ? 0 :
+ buf->f_fsid = u64_to_fsid(
+ erofs_is_fscache_mode(sb) ?
+ 0 :
huge_encode_dev(sb->s_bdev->bd_dev));
else
buf->f_fsid = uuid_to_fsid(sb->s_uuid.b);
+#endif
return 0;
}
static int erofs_show_options(struct seq_file *seq, struct dentry *root)
{
+#ifndef CONFIG_EROFS_FS_RUST
struct erofs_sb_info *sbi = EROFS_SB(root->d_sb);
struct erofs_mount_opts *opt = &sbi->opt;
if (IS_ENABLED(CONFIG_EROFS_FS_XATTR))
- seq_puts(seq, test_opt(opt, XATTR_USER) ?
- ",user_xattr" : ",nouser_xattr");
+ seq_puts(seq, test_opt(opt, XATTR_USER) ? ",user_xattr" :
+ ",nouser_xattr");
if (IS_ENABLED(CONFIG_EROFS_FS_POSIX_ACL))
seq_puts(seq, test_opt(opt, POSIX_ACL) ? ",acl" : ",noacl");
if (IS_ENABLED(CONFIG_EROFS_FS_ZIP))
- seq_printf(seq, ",cache_strategy=%s",
- erofs_param_cache_strategy[opt->cache_strategy].name);
+ seq_printf(
+ seq, ",cache_strategy=%s",
+ erofs_param_cache_strategy[opt->cache_strategy].name);
if (test_opt(opt, DAX_ALWAYS))
seq_puts(seq, ",dax=always");
if (test_opt(opt, DAX_NEVER))
@@ -932,6 +1032,7 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
seq_printf(seq, ",fsid=%s", sbi->fsid);
if (sbi->domain_id)
seq_printf(seq, ",domain_id=%s", sbi->domain_id);
+#endif
#endif
return 0;
}
--
2.45.2
More information about the Linux-erofs
mailing list