pnfs: Fix manipulation of NFS_LAYOUT_FIRST_LAYOUTGET
authorFred Isaman <fred.isaman@gmail.com>
Tue, 18 Oct 2016 17:39:51 +0000 (13:39 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 31 May 2018 19:03:11 +0000 (15:03 -0400)
The flag was not always being cleared after LAYOUTGET on OPEN.

Signed-off-by: Fred Isaman <fred.isaman@gmail.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index 05454cbc473df7950ae8b650263165a67156879c..d18447d11b065b9d2bfbd2e19d9ffe3d0eb96c74 100644 (file)
@@ -1249,8 +1249,7 @@ static void nfs4_opendata_free(struct kref *kref)
                        struct nfs4_opendata, kref);
        struct super_block *sb = p->dentry->d_sb;
 
-       if (p->lgp)
-               nfs4_layoutget_release(p->lgp);
+       nfs4_lgopen_release(p->lgp);
        nfs_free_seqid(p->o_arg.seqid);
        nfs4_sequence_free_slot(&p->o_res.seq_res);
        if (p->state != NULL)
index a29fdea2db910a216dd798bd1e457a13cf160ee3..b0e42fd07cb108016dd12b99137ec514c231f3f9 100644 (file)
@@ -2129,13 +2129,11 @@ void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
                lgp->args.inode = ino;
        } else
                lo = NFS_I(lgp->args.inode)->layout;
-       pnfs_get_layout_hdr(lo);
 
        if (read_seqcount_retry(&srv->nfs_client->cl_callback_count,
                                lgp->callback_count))
-               goto out;
+               return;
        lseg = pnfs_layout_process(lgp);
-       atomic_dec(&lo->plh_outstanding);
        if (IS_ERR(lseg)) {
                /* ignore lseg, but would like to mark not to try lgopen */
                /* clear some lo flags - first and fail ???? */
@@ -2144,9 +2142,19 @@ void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
                pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
                pnfs_put_lseg(lseg);
        }
-out:
-       pnfs_clear_first_layoutget(lo);
-       pnfs_put_layout_hdr(lo);
+}
+
+void nfs4_lgopen_release(struct nfs4_layoutget *lgp)
+{
+       if (lgp != NULL) {
+               struct inode *inode = lgp->args.inode;
+               if (inode) {
+                       struct pnfs_layout_hdr *lo = NFS_I(inode)->layout;
+                       atomic_dec(&lo->plh_outstanding);
+                       pnfs_clear_first_layoutget(lo);
+               }
+               pnfs_layoutget_free(lgp);
+       }
 }
 
 struct pnfs_layout_segment *
index 9941df824ca905492108c4aae11297e2a87fcc20..a8f5e6b167491e3746a921f1f611fbb06b7d5f45 100644 (file)
@@ -384,6 +384,7 @@ void pnfs_lgopen_prepare(struct nfs4_opendata *data,
                         struct nfs_open_context *ctx);
 void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
                       struct nfs_open_context *ctx);
+void nfs4_lgopen_release(struct nfs4_layoutget *lgp);
 
 static inline bool nfs_have_layout(struct inode *inode)
 {
@@ -795,6 +796,11 @@ static inline void pnfs_parse_lgopen(struct inode *ino,
                struct nfs_open_context *ctx)
 {
 }
+
+static inline void nfs4_lgopen_release(struct nfs4_layoutget *lgp)
+{
+}
+
 #endif /* CONFIG_NFS_V4_1 */
 
 #if IS_ENABLED(CONFIG_NFS_V4_2)