Messages in this thread Patch in this message | | | From | Haodong Wong <> | Subject | [PATCH] knfsd: add nfs-export support to ramfs | Date | Tue, 21 May 2019 23:25:25 +0800 |
| |
Refer to tmpfs, use inode number and generation number to construct the filehandle for nfs-export
Signed-off-by: Haodong Wong <haydenw.kernel@gmail.com> --- fs/ramfs/inode.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 11201b2d06b9..418b2551f6fd 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -36,6 +36,7 @@ #include <linux/magic.h> #include <linux/slab.h> #include <linux/uaccess.h> +#include <linux/exportfs.h> #include "internal.h" struct ramfs_mount_opts { @@ -66,6 +67,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, if (inode) { inode->i_ino = get_next_ino(); inode_init_owner(inode, dir, mode); + inode->i_generation = get_seconds(); inode->i_mapping->a_ops = &ramfs_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); mapping_set_unevictable(inode->i_mapping); @@ -217,6 +219,75 @@ static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) return 0; } +static struct dentry *ramfs_get_parent(struct dentry *child) +{ + return ERR_PTR(-ESTALE); +} + +static int ramfs_match(struct inode *ino, void *vfh) +{ + __u32 *fh = vfh; + __u64 inum = fh[2]; + + inum = (inum << 32) | fh[1]; + return ino->i_ino == inum && fh[0] == ino->i_generation; +} + +static struct dentry *ramfs_fh_to_dentry(struct super_block *sb, + struct fid *fid, int fh_len, int fh_type) + +{ + struct inode *inode; + struct dentry *dentry = NULL; + u64 inum; + + if (fh_len < 3) + return NULL; + + inum = fid->raw[2]; + inum = (inum << 32) | fid->raw[1]; + inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]), + ramfs_match, fid->raw); + + if (inode) { + dentry = d_find_alias(inode); + iput(inode); + } + + return dentry; +} + +static int ramfs_encode_fh(struct inode *inode, __u32 *fh, int *len, + struct inode *parent) +{ + if (*len < 3) { + *len = 3; + return FILEID_INVALID; + } + + if (inode_unhashed(inode)) { + static DEFINE_SPINLOCK(lock); + + spin_lock(&lock); + if (inode_unhashed(inode)) + __insert_inode_hash(inode, + inode->i_ino + inode->i_generation); + spin_unlock(&lock); + } + fh[0] = inode->i_generation; + fh[1] = inode->i_ino; + fh[2] = ((__u64)inode->i_ino) >> 32; + + *len = 3; + return 1; +} + +static const struct export_operations ramfs_export_ops = { + .get_parent = ramfs_get_parent, + .encode_fh = ramfs_encode_fh, + .fh_to_dentry = ramfs_fh_to_dentry, +}; + int ramfs_fill_super(struct super_block *sb, void *data, int silent) { struct ramfs_fs_info *fsi; @@ -238,6 +309,7 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = RAMFS_MAGIC; sb->s_op = &ramfs_ops; sb->s_time_gran = 1; + sb->s_export_op = &ramfs_export_ops; inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0); sb->s_root = d_make_root(inode); -- 2.17.1
| |