From 0495fe27a1b950d5d1cefb2d7ec962d666fc8f45 Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Sat, 21 May 2016 23:57:00 -0400 Subject: [PATCH] Wrapfs: support NFS exports Based on patch from Sandeep Joshi . Signed-off-by: Erez Zadok --- fs/wrapfs/lookup.c | 2 +- fs/wrapfs/main.c | 2 ++ fs/wrapfs/super.c | 40 ++++++++++++++++++++++++++++++++++++++++ fs/wrapfs/wrapfs.h | 2 ++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/fs/wrapfs/lookup.c b/fs/wrapfs/lookup.c index 118e879f52cc..eae79babf5fa 100644 --- a/fs/wrapfs/lookup.c +++ b/fs/wrapfs/lookup.c @@ -280,7 +280,7 @@ setup_lower: * the VFS will continue the process of making this negative dentry * into a positive one. */ - if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET)) + if (err == -ENOENT || (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET))) err = 0; out: diff --git a/fs/wrapfs/main.c b/fs/wrapfs/main.c index 88113cd0bb75..c39ef09d3769 100644 --- a/fs/wrapfs/main.c +++ b/fs/wrapfs/main.c @@ -64,6 +64,8 @@ static int wrapfs_read_super(struct super_block *sb, void *raw_data, int silent) sb->s_op = &wrapfs_sops; + sb->s_export_op = &wrapfs_export_ops; /* adding NFS support */ + /* get a new inode and allocate our root dentry */ inode = wrapfs_iget(sb, d_inode(lower_path.dentry)); if (IS_ERR(inode)) { diff --git a/fs/wrapfs/super.c b/fs/wrapfs/super.c index 9f90f57be769..5c99c47eed0b 100644 --- a/fs/wrapfs/super.c +++ b/fs/wrapfs/super.c @@ -166,3 +166,43 @@ const struct super_operations wrapfs_sops = { .destroy_inode = wrapfs_destroy_inode, .drop_inode = generic_delete_inode, }; + +/* NFS support */ + +static struct inode *wrapfs_nfs_get_inode(struct super_block *sb, u64 ino, + u32 generation) +{ + struct super_block *lower_sb; + struct inode *inode; + struct inode *lower_inode; + + lower_sb = wrapfs_lower_super(sb); + lower_inode = ilookup(lower_sb, ino); + inode = wrapfs_iget(sb, lower_inode); + return inode; +} + +static struct dentry *wrapfs_fh_to_dentry(struct super_block *sb, + struct fid *fid, int fh_len, + int fh_type) +{ + return generic_fh_to_dentry(sb, fid, fh_len, fh_type, + wrapfs_nfs_get_inode); +} + +static struct dentry *wrapfs_fh_to_parent(struct super_block *sb, + struct fid *fid, int fh_len, + int fh_type) +{ + return generic_fh_to_parent(sb, fid, fh_len, fh_type, + wrapfs_nfs_get_inode); +} + +/* + * all other funcs are default as defined in exportfs/expfs.c + */ + +const struct export_operations wrapfs_export_ops = { + .fh_to_dentry = wrapfs_fh_to_dentry, + .fh_to_parent = wrapfs_fh_to_parent +}; diff --git a/fs/wrapfs/wrapfs.h b/fs/wrapfs/wrapfs.h index c5b9fdeb86d5..149b27a453c7 100644 --- a/fs/wrapfs/wrapfs.h +++ b/fs/wrapfs/wrapfs.h @@ -26,6 +26,7 @@ #include #include #include +#include /* the file system name */ #define WRAPFS_NAME "wrapfs" @@ -46,6 +47,7 @@ extern const struct super_operations wrapfs_sops; extern const struct dentry_operations wrapfs_dops; extern const struct address_space_operations wrapfs_aops, wrapfs_dummy_aops; extern const struct vm_operations_struct wrapfs_vm_ops; +extern const struct export_operations wrapfs_export_ops; extern int wrapfs_init_inode_cache(void); extern void wrapfs_destroy_inode_cache(void); -- 2.34.1