Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
#if SIMPLEFS_AT_LEAST(6, 18, 0)
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#endif
#include <linux/fs.h>
#include <linux/kernel.h>
Expand All @@ -14,14 +15,33 @@ static int simplefs_get_tree(struct fs_context *fc)
{
return get_tree_bdev(fc, simplefs_fill_super);
}
static void simplefs_free_context(struct fs_context *fc)
{
struct simplefs_fs_context *ctx = fc->fs_private;

if (!ctx)
return;

kfree(ctx->journal_path);
kfree(ctx);
}
static const struct fs_context_operations simplefs_context_ops = {
.get_tree = simplefs_get_tree,
.parse_param = simplefs_parse_param,
.free = simplefs_free_context,
};
static int init_simplefs_context(struct fs_context *fc)
{
struct simplefs_fs_context *ctx;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
fc->fs_private = ctx;
fc->ops = &simplefs_context_ops;

return 0;
}
extern const struct fs_parameter_spec simplefs_param_specs;
#else
/* Mount a simplefs partition */
struct dentry *simplefs_mount(struct file_system_type *fs_type,
Expand Down Expand Up @@ -60,6 +80,7 @@ static struct file_system_type simplefs_file_system_type = {
.name = "simplefs",
#if SIMPLEFS_AT_LEAST(6, 18, 0)
.init_fs_context = init_simplefs_context,
.parameters = &simplefs_param_specs,
#else
.mount = simplefs_mount,
#endif
Expand Down
13 changes: 11 additions & 2 deletions simplefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,24 @@ struct simplefs_dir_block {
uint32_t nr_files;
struct simplefs_file files[SIMPLEFS_FILES_PER_BLOCK];
};

#if SIMPLEFS_AT_LEAST(6, 18, 0)
struct simplefs_fs_context {
u32 journal_dev;
char *journal_path;
};
#endif
/* superblock functions */
#if SIMPLEFS_AT_LEAST(6, 18, 0)
int simplefs_fill_super(struct super_block *sb, struct fs_context *fc);
#else
int simplefs_fill_super(struct super_block *sb, void *data, int silent);
#endif
void simplefs_kill_sb(struct super_block *sb);

#if SIMPLEFS_AT_LEAST(6, 18, 0)
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
int simplefs_parse_param(struct fs_context *fc, struct fs_parameter *param);
#endif
/* inode functions */
int simplefs_init_inode_cache(void);
void simplefs_destroy_inode_cache(void);
Expand Down
81 changes: 73 additions & 8 deletions super.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "simplefs.h"
#if SIMPLEFS_AT_LEAST(6, 18, 0)
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#endif
struct dentry *simplefs_mount(struct file_system_type *fs_type,
int flags,
Expand Down Expand Up @@ -449,6 +450,39 @@ static const match_table_t tokens = {
{SIMPLEFS_OPT_JOURNAL_DEV, "journal_dev=%u"},
{SIMPLEFS_OPT_JOURNAL_PATH, "journal_path=%s"},
};
#if SIMPLEFS_AT_LEAST(6, 18, 0)
const struct fs_parameter_spec simplefs_param_specs[] = {
fsparam_u32("journal_dev", SIMPLEFS_OPT_JOURNAL_DEV),
fsparam_string("journal_path", SIMPLEFS_OPT_JOURNAL_PATH),
{}};
int simplefs_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
struct simplefs_fs_context *ctx = fc->fs_private;
struct fs_parse_result result;
int opt;

opt = fs_parse(fc, simplefs_param_specs, param, &result);
if (opt < 0)
return opt;

switch (opt) {
case SIMPLEFS_OPT_JOURNAL_DEV:
ctx->journal_dev = result.uint_32;
break;

case SIMPLEFS_OPT_JOURNAL_PATH: {
kfree(ctx->journal_path);
ctx->journal_path = kstrdup(param->string, GFP_KERNEL);
if (!ctx->journal_path)
return -ENOMEM;
break;
default:
return -EINVAL;
}
}
return 0;
}
#else
static int simplefs_parse_options(struct super_block *sb, char *options)
{
substring_t args[MAX_OPT_ARGS];
Expand Down Expand Up @@ -496,12 +530,9 @@ static int simplefs_parse_options(struct super_block *sb, char *options)
kfree(journal_path);
return ret;
}

journal_inode = path.dentry->d_inode;

path_put(&path);
kfree(journal_path);

journal_inode = path.dentry->d_inode;
if (S_ISBLK(journal_inode->i_mode)) {
unsigned long journal_devnum =
new_encode_dev(journal_inode->i_rdev);
Expand All @@ -513,14 +544,15 @@ static int simplefs_parse_options(struct super_block *sb, char *options)
return ret;
}
}
path_put(&path);
break;
}
}
}

return 0;
}

#endif
static struct super_operations simplefs_super_ops = {
.put_super = simplefs_put_super,
.alloc_inode = simplefs_alloc_inode,
Expand All @@ -534,6 +566,7 @@ static struct super_operations simplefs_super_ops = {
#if SIMPLEFS_AT_LEAST(6, 18, 0)
int simplefs_fill_super(struct super_block *sb, struct fs_context *fc)
{
struct simplefs_fs_context *ctx = fc->fs_private;
#else
int simplefs_fill_super(struct super_block *sb, void *data, int silent)
{
Expand Down Expand Up @@ -651,9 +684,41 @@ inode_init_owner(root_inode, NULL, root_inode->i_mode);
ret = -ENOMEM;
goto iput;
}
/* Since parse_options is not available at fill_super stage at kernels
* v6.18+, it is disabled for now. */
#if SIMPLEFS_LESS_EQUAL(6, 17, 0)

#if SIMPLEFS_AT_LEAST(6, 18, 0)
if (ctx->journal_dev) {
ret = simplefs_load_journal(sb, ctx->journal_dev);
if (ret) {
pr_err(
"simplefs_parse_options: simplefs_load_journal failed with "
"%d\n",
ret);
return ret;
}
}
if (ctx->journal_path) {
struct path path;
struct inode *inode;
ret = kern_path(ctx->journal_path, LOOKUP_FOLLOW, &path);
if (ret) {
pr_err("simplefs_parse_options: kern_path failed with error %d\n",
ret);
return ret;
}
inode = d_inode(path.dentry);
path_put(&path);
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
if (S_ISBLK(inode->i_mode)) {
unsigned long journal_devnum = new_encode_dev(inode->i_rdev);
if ((ret = simplefs_load_journal(sb, journal_devnum))) {
pr_err(
"simplefs_parse_options: simplefs_load_journal failed "
"with %d\n",
ret);
return ret;
}
}
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
}
#else
ret = simplefs_parse_options(sb, data);
if (ret) {
pr_err("simplefs_fill_super: Failed to parse options, error code: %d\n",
Expand Down
Loading