NFSv4: Ensure we reference the inode for return-on-close in delegreturn
authorTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 5 Feb 2015 20:13:24 +0000 (15:13 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Fri, 6 Feb 2015 02:31:06 +0000 (21:31 -0500)
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>
fs/nfs/internal.h
fs/nfs/nfs4proc.c
fs/nfs/super.c

index a98cf20..21469e6 100644 (file)
@@ -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
  */
Simple merge
diff --cc fs/nfs/super.c
Simple merge