Refer to tmpfs use inode number and generation number to construct the 
filehandle for nfs-export

Without this patch, when run exportfs for nfs-kernel-server to export
ramfs, it will report "not support NFS export"

Signed-off-by: Haodong Wong <haydenw.ker...@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 733c6b4193dc..7a60dfefa6fd 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

Reply via email to