On Fri, 23 Feb 2024 11:41:55 -0600 John Groves <John@xxxxxxxxxx> wrote: > This commit introduces the famfs fs_context_operations and > famfs_get_inode() which is used by the context operations. > > Signed-off-by: John Groves <john@xxxxxxxxxx> Trivial comments inline. > --- > fs/famfs/famfs_inode.c | 178 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 178 insertions(+) > > diff --git a/fs/famfs/famfs_inode.c b/fs/famfs/famfs_inode.c > index 82c861998093..f98f82962d7b 100644 > --- a/fs/famfs/famfs_inode.c > +++ b/fs/famfs/famfs_inode.c > @@ -41,6 +41,50 @@ static const struct super_operations famfs_ops; > static const struct inode_operations famfs_file_inode_operations; > static const struct inode_operations famfs_dir_inode_operations; > > +static struct inode *famfs_get_inode( > + struct super_block *sb, > + const struct inode *dir, > + umode_t mode, > + dev_t dev) > +{ > + struct inode *inode = new_inode(sb); > + > + if (inode) { reverse logic would be simpler and reduce indent. if (!inode) return NULL; > + struct timespec64 tv; > + > + inode->i_ino = get_next_ino(); > + inode_init_owner(&nop_mnt_idmap, inode, dir, mode); > + inode->i_mapping->a_ops = &ram_aops; > + mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); > + mapping_set_unevictable(inode->i_mapping); > + tv = inode_set_ctime_current(inode); > + inode_set_mtime_to_ts(inode, tv); > + inode_set_atime_to_ts(inode, tv); > + > + switch (mode & S_IFMT) { > + default: > + init_special_inode(inode, mode, dev); > + break; > + case S_IFREG: > + inode->i_op = &famfs_file_inode_operations; > + inode->i_fop = &famfs_file_operations; > + break; > + case S_IFDIR: > + inode->i_op = &famfs_dir_inode_operations; > + inode->i_fop = &simple_dir_operations; > + > + /* Directory inodes start off with i_nlink == 2 (for "." entry) */ > + inc_nlink(inode); > + break; > + case S_IFLNK: > + inode->i_op = &page_symlink_inode_operations; > + inode_nohighmem(inode); > + break; > + } > + } > + return inode; > +} > + > /********************************************************************************** > * famfs super_operations > * > @@ -150,6 +194,140 @@ famfs_open_device( > return 0; > } > > +/***************************************************************************************** > + * fs_context_operations > + */ > +static int > +famfs_fill_super( > + struct super_block *sb, > + struct fs_context *fc) > +{ > + struct famfs_fs_info *fsi = sb->s_fs_info; > + struct inode *inode; > + int rc = 0; Always initialized so no need to do it here. > + > + sb->s_maxbytes = MAX_LFS_FILESIZE; > + sb->s_blocksize = PAGE_SIZE; > + sb->s_blocksize_bits = PAGE_SHIFT; > + sb->s_magic = FAMFS_MAGIC; > + sb->s_op = &famfs_ops; > + sb->s_time_gran = 1; > + > + rc = famfs_open_device(sb, fc); > + if (rc) > + goto out; return rc; //unless you need to do more in out in later patch.. > + > + inode = famfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0); > + sb->s_root = d_make_root(inode); > + if (!sb->s_root) > + rc = -ENOMEM; return -ENOMEM; return 0; > + > +out: > + return rc; > +} > + > +enum famfs_param { > + Opt_mode, > + Opt_dax, Why capital O? > +}; > + ... > + > +static DEFINE_MUTEX(famfs_context_mutex); > +static LIST_HEAD(famfs_context_list); > + > +static int famfs_get_tree(struct fs_context *fc) > +{ > + struct famfs_fs_info *fsi_entry; > + struct famfs_fs_info *fsi = fc->s_fs_info; > + > + fsi->rootdev = kstrdup(fc->source, GFP_KERNEL); > + if (!fsi->rootdev) > + return -ENOMEM; > + > + /* Fail if famfs is already mounted from the same device */ > + mutex_lock(&famfs_context_mutex); New toys might be good to use from start to avoid need for explicit unlocks in error paths. scoped_guard(mutex, &famfs_context_mutex) { list_for_each_entry(fsi_entry, &famfs_context_list, fsi_list) { if (strcmp(fsi_entry->rootdev, cs_source) == 0) { //could invert with a continue to reduce indent // or factor this out as a little helper. // famfs_check_not_mounted() pr_err(); return -EALREADY; } } list_add(&fsi->fs_list, &famfs_context_list); } return get_tree_nodev(... > + list_for_each_entry(fsi_entry, &famfs_context_list, fsi_list) { > + if (strcmp(fsi_entry->rootdev, fc->source) == 0) { > + mutex_unlock(&famfs_context_mutex); > + pr_err("%s: already mounted from rootdev %s\n", __func__, fc->source); > + return -EALREADY; > + } > + } > + > + list_add(&fsi->fsi_list, &famfs_context_list); > + mutex_unlock(&famfs_context_mutex); > + > + return get_tree_nodev(fc, famfs_fill_super); > + > +} > > MODULE_LICENSE("GPL");