diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-05 23:13:24 +0300 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-06 05:31:06 +0300 |
commit | ea7c38fef0b774a5dc16fb0ca5935f0ae8568176 (patch) | |
tree | beab8b32b90a57d54293eb83bd8d5f3f75c3be2c /fs/nfs/internal.h | |
parent | 6ae373394c4257bad562817aa60464ff7fe8f9c4 (diff) | |
download | linux-ea7c38fef0b774a5dc16fb0ca5935f0ae8568176.tar.xz |
NFSv4: Ensure we reference the inode for return-on-close in delegreturn
If we have to do a return-on-close in the delegreturn code, then
we must ensure that the inode and super block remain referenced.
Cc: Peng Tao <tao.peng@primarydata.com>
Cc: stable@vger.kernel.org # 3.17.x
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Peng Tao <tao.peng@primarydata.com>
Diffstat (limited to 'fs/nfs/internal.h')
-rw-r--r-- | fs/nfs/internal.h | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index a98cf2006179..21469e6e3834 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -391,7 +391,7 @@ extern struct rpc_stat nfs_rpcstat; extern int __init register_nfs_fs(void); extern void __exit unregister_nfs_fs(void); -extern void nfs_sb_active(struct super_block *sb); +extern bool nfs_sb_active(struct super_block *sb); extern void nfs_sb_deactive(struct super_block *sb); /* namespace.c */ @@ -514,6 +514,26 @@ extern int nfs41_walk_client_list(struct nfs_client *clp, struct nfs_client **result, struct rpc_cred *cred); +static inline struct inode *nfs_igrab_and_active(struct inode *inode) +{ + inode = igrab(inode); + if (inode != NULL && !nfs_sb_active(inode->i_sb)) { + iput(inode); + inode = NULL; + } + return inode; +} + +static inline void nfs_iput_and_deactive(struct inode *inode) +{ + if (inode != NULL) { + struct super_block *sb = inode->i_sb; + + iput(inode); + nfs_sb_deactive(sb); + } +} + /* * Determine the device name as a string */ |