NFSv4.x: Don't return NFS4ERR_NOMATCHING_LAYOUT if we're unmounting
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 15 Apr 2021 19:09:41 +0000 (15:09 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Fri, 16 Apr 2021 12:50:21 +0000 (08:50 -0400)
If the NFS super block is being unmounted, then we currently may end up
telling the server that we've forgotten the layout while it is actually
still in use by the client.
In that case, just assume that the client will soon return the layout
anyway, and so return NFS4ERR_DELAY in response to the layout recall.

Fixes: 58ac3e59235f ("NFSv4/pnfs: Clean up nfs_layout_find_inode()")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/callback_proc.c

index f7786e0..ed9d580 100644 (file)
@@ -137,12 +137,12 @@ static struct inode *nfs_layout_find_inode_by_stateid(struct nfs_client *clp,
                list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
                        if (!pnfs_layout_is_valid(lo))
                                continue;
-                       if (stateid != NULL &&
-                           !nfs4_stateid_match_other(stateid, &lo->plh_stateid))
+                       if (!nfs4_stateid_match_other(stateid, &lo->plh_stateid))
                                continue;
-                       if (!nfs_sb_active(server->super))
-                               continue;
-                       inode = igrab(lo->plh_inode);
+                       if (nfs_sb_active(server->super))
+                               inode = igrab(lo->plh_inode);
+                       else
+                               inode = ERR_PTR(-EAGAIN);
                        rcu_read_unlock();
                        if (inode)
                                return inode;
@@ -176,9 +176,10 @@ static struct inode *nfs_layout_find_inode_by_fh(struct nfs_client *clp,
                                continue;
                        if (nfsi->layout != lo)
                                continue;
-                       if (!nfs_sb_active(server->super))
-                               continue;
-                       inode = igrab(lo->plh_inode);
+                       if (nfs_sb_active(server->super))
+                               inode = igrab(lo->plh_inode);
+                       else
+                               inode = ERR_PTR(-EAGAIN);
                        rcu_read_unlock();
                        if (inode)
                                return inode;