Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83026d80 authored by Jeff Layton's avatar Jeff Layton Committed by Anna Schumaker
Browse files

pnfs: lift retry logic from send_layoutget to pnfs_update_layout



If we get back something like NFS4ERR_OLD_STATEID, that will be
translated into -EAGAIN, and the do/while loop in send_layoutget
will drive the call again.

This is not quite what we want, I think. An error like that is a
sign that something has changed. That something could have been a
concurrent LAYOUTGET that would give us a usable lseg.

Lift the retry logic into pnfs_update_layout instead. That allows
us to redo the layout search, and may spare us from having to issue
an RPC.

Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent d03ab29d
Loading
Loading
Loading
Loading
+36 −36
Original line number Diff line number Diff line
@@ -839,7 +839,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
	struct inode *ino = lo->plh_inode;
	struct nfs_server *server = NFS_SERVER(ino);
	struct nfs4_layoutget *lgp;
	struct pnfs_layout_segment *lseg;
	loff_t i_size;

	dprintk("--> %s\n", __func__);
@@ -849,10 +848,9 @@ send_layoutget(struct pnfs_layout_hdr *lo,
	 * store in lseg. If we race with a concurrent seqid morphing
	 * op, then re-send the LAYOUTGET.
	 */
	do {
	lgp = kzalloc(sizeof(*lgp), gfp_flags);
	if (lgp == NULL)
			return NULL;
		return ERR_PTR(-ENOMEM);

	i_size = i_size_read(ino);

@@ -873,21 +871,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
	lgp->gfp_flags = gfp_flags;
	lgp->cred = lo->plh_lc_cred;

		lseg = nfs4_proc_layoutget(lgp, gfp_flags);
	} while (lseg == ERR_PTR(-EAGAIN));

	if (IS_ERR(lseg)) {
		if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
			pnfs_layout_clear_fail_bit(lo,
					pnfs_iomode_to_fail_bit(range->iomode));
			lseg = NULL;
		}
	} else {
		pnfs_layout_clear_fail_bit(lo,
				pnfs_iomode_to_fail_bit(range->iomode));
	}

	return lseg;
	return nfs4_proc_layoutget(lgp, gfp_flags);
}

static void pnfs_clear_layoutcommit(struct inode *inode,
@@ -1649,6 +1633,22 @@ pnfs_update_layout(struct inode *ino,
		arg.length = PAGE_ALIGN(arg.length);

	lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
	if (IS_ERR(lseg)) {
		if (lseg == ERR_PTR(-EAGAIN)) {
			if (first)
				pnfs_clear_first_layoutget(lo);
			pnfs_put_layout_hdr(lo);
			goto lookup_again;
		}

		if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
			pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
			lseg = NULL;
		}
	} else {
		pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
	}

	atomic_dec(&lo->plh_outstanding);
	trace_pnfs_update_layout(ino, pos, count, iomode, lo,
				 PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);