[RFC PATCH 12/20] famfs: Add inode_operations and file_system_type

John Groves
2024-02-23T17:42:52Z

This commit introduces the famfs inode_operations. There is nothing really
unique to famfs here in the inode_operations..

This commit also introduces the famfs_file_system_type struct and the
famfs_kill_sb() function.

Signed-off-by: John Groves <john@groves.net>
---
fs/famfs/famfs_inode.c | 132 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 132 insertions(+)

diff --git a/fs/famfs/famfs_inode.c b/fs/famfs/famfs_inode.c
index f98f82962d7b..ab46ec50b70d 100644
--- a/fs/famfs/famfs_inode.c
+++ b/fs/famfs/famfs_inode.c
@@ -85,6 +85,109 @@ static struct inode *famfs_get_inode(
return inode;
}

+/***************************************************************************
+ * famfs inode_operations: these are currently pretty much boilerplate
+ */
+
+static const struct inode_operations famfs_file_inode_operations = {
+ /* All generic */
+ .setattr = simple_setattr,
+ .getattr = simple_getattr,
+};
+
+
+/*
+ * File creation. Allocate an inode, and we're done..
+ */
+/* SMP-safe */
+static int
+famfs_mknod(
+ struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ umode_t mode,
+ dev_t dev)
+{
+ struct inode *inode = famfs_get_inode(dir->i_sb, dir, mode, dev);
+ int error = -ENOSPC;
+
+ if (inode) {
+ struct timespec64 tv;
+
+ d_instantiate(dentry, inode);
+ dget(dentry); /* Extra count - pin the dentry in core */
+ error = 0;
+ tv = inode_set_ctime_current(inode);
+ inode_set_mtime_to_ts(inode, tv);
+ inode_set_atime_to_ts(inode, tv);
+ }
+ return error;
+}
+
+static int famfs_mkdir(
+ struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ umode_t mode)
+{
+ int retval = famfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFDIR, 0);
+
+ if (!retval)
+ inc_nlink(dir);
+
+ return retval;
+}
+
+static int famfs_create(
+ struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ umode_t mode,
+ bool excl)
+{
+ return famfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFREG, 0);
+}
+
+static int famfs_symlink(
+ struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ const char *symname)
+{
+ struct inode *inode;
+ int error = -ENOSPC;
+
+ inode = famfs_get_inode(dir->i_sb, dir, S_IFLNK | 0777, 0);
+ if (inode) {
+ int l = strlen(symname)+1;
+
+ error = page_symlink(inode, symname, l);
+ if (!error) {
+ struct timespec64 tv;
+
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ tv = inode_set_ctime_current(inode);
+ inode_set_mtime_to_ts(inode, tv);
+ inode_set_atime_to_ts(inode, tv);
+ } else
+ iput(inode);
+ }
+ return error;
+}
+
+static const struct inode_operations famfs_dir_inode_operations = {
+ .create = famfs_create,
+ .lookup = simple_lookup,
+ .link = simple_link,
+ .unlink = simple_unlink,
+ .symlink = famfs_symlink,
+ .mkdir = famfs_mkdir,
+ .rmdir = simple_rmdir,
+ .mknod = famfs_mknod,
+ .rename = simple_rename,
+};
+
/**********************************************************************************
* famfs super_operations
*
@@ -329,5 +432,34 @@ static int famfs_init_fs_context(struct fs_context *fc)
return 0;
}

+static void famfs_kill_sb(struct super_block *sb)
+{
+ struct famfs_fs_info *fsi = sb->s_fs_info;
+
+ mutex_lock(&famfs_context_mutex);
+ list_del(&fsi->fsi_list);
+ mutex_unlock(&famfs_context_mutex);
+
+ if (fsi->bdev_handle)
+ bdev_release(fsi->bdev_handle);
+ if (fsi->dax_devp)
+ fs_put_dax(fsi->dax_devp, fsi);
+ if (fsi->dax_filp) /* This only happens if it's char dax */
+ filp_close(fsi->dax_filp, NULL);
+
+ if (fsi && fsi->rootdev)
+ kfree(fsi->rootdev);
+ kfree(fsi);
+ kill_litter_super(sb);
+}
+
+#define MODULE_NAME "famfs"
+static struct file_system_type famfs_fs_type = {
+ .name = MODULE_NAME,
+ .init_fs_context = famfs_init_fs_context,
+ .parameters = famfs_fs_parameters,
+ .kill_sb = famfs_kill_sb,
+ .fs_flags = FS_USERNS_MOUNT,
+};

MODULE_LICENSE("GPL");
--
2.43.0