NFSv4/pnfs: pnfs_set_layout_stateid() should update the layout cred
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 27 Jan 2020 18:07:26 +0000 (13:07 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 16 Mar 2020 12:34:28 +0000 (08:34 -0400)
If the cred assigned to the layout that we're updating differs from
the one used to retrieve the new layout segment, then we need to
update the layout plh_lc_cred field.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/callback_proc.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index cd4c6bc..b6ffac9 100644 (file)
@@ -280,7 +280,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
                goto unlock;
        }
 
-       pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
+       pnfs_set_layout_stateid(lo, &args->cbl_stateid, NULL, true);
        switch (pnfs_mark_matching_lsegs_return(lo, &free_me_list,
                                &args->cbl_range,
                                be32_to_cpu(args->cbl_stateid.seqid))) {
index 542ea8d..b21eb48 100644 (file)
@@ -903,10 +903,21 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
        pnfs_destroy_layouts_byclid(clp, false);
 }
 
+static void
+pnfs_set_layout_cred(struct pnfs_layout_hdr *lo, const struct cred *cred)
+{
+       const struct cred *old;
+
+       if (cred && cred_fscmp(lo->plh_lc_cred, cred) != 0) {
+               old = xchg(&lo->plh_lc_cred, get_cred(cred));
+               put_cred(old);
+       }
+}
+
 /* update lo->plh_stateid with new if is more recent */
 void
 pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
-                       bool update_barrier)
+                       const struct cred *cred, bool update_barrier)
 {
        u32 oldseq, newseq, new_barrier = 0;
 
@@ -914,6 +925,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
        newseq = be32_to_cpu(new->seqid);
 
        if (!pnfs_layout_is_valid(lo)) {
+               pnfs_set_layout_cred(lo, cred);
                nfs4_stateid_copy(&lo->plh_stateid, new);
                lo->plh_barrier = newseq;
                pnfs_clear_layoutreturn_info(lo);
@@ -1109,7 +1121,7 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
 
                pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);
                pnfs_free_returned_lsegs(lo, &freeme, range, seq);
-               pnfs_set_layout_stateid(lo, stateid, true);
+               pnfs_set_layout_stateid(lo, stateid, NULL, true);
        } else
                pnfs_mark_layout_stateid_invalid(lo, &freeme);
 out_unlock:
@@ -2323,14 +2335,14 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
 
        if (!pnfs_layout_is_valid(lo)) {
                /* We have a completely new layout */
-               pnfs_set_layout_stateid(lo, &res->stateid, true);
+               pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
        } else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
                /* existing state ID, make sure the sequence number matches. */
                if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
                        dprintk("%s forget reply due to sequence\n", __func__);
                        goto out_forget;
                }
-               pnfs_set_layout_stateid(lo, &res->stateid, false);
+               pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, false);
        } else {
                /*
                 * We got an entirely new state ID.  Mark all segments for the
index 0fafdad..cfb89d4 100644 (file)
@@ -267,6 +267,7 @@ bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
 void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
 void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
                             const nfs4_stateid *new,
+                            const struct cred *cred,
                             bool update_barrier);
 int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
                                struct list_head *tmp_list,