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

Commit 193e3aa2 authored by Peng Tao's avatar Peng Tao Committed by Tom Haynes
Browse files

nfs41: introduce NFS_LAYOUT_RETURN_BEFORE_CLOSE



When it is set, generic pnfs would try to send layoutreturn right
before last close/delegation_return regard less NFS_LAYOUT_ROC is
set or not. LD can then make sure layoutreturn is always sent
rather than being omitted.

The difference against NFS_LAYOUT_RETURN is that
NFS_LAYOUT_RETURN_BEFORE_CLOSE does not block usage of the layout so
LD can set it and expect generic layer to try pnfs path at the
same time.

Signed-off-by: default avatarPeng Tao <tao.peng@primarydata.com>
Signed-off-by: default avatarTom Haynes <loghyr@primarydata.com>
parent 6c16605d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -7797,6 +7797,8 @@ static void nfs4_layoutreturn_release(void *calldata)
	if (lrp->res.lrs_present)
		pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
	clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
	clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags);
	rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
	lo->plh_block_lgets--;
	spin_unlock(&lo->plh_inode->i_lock);
	pnfs_put_layout_hdr(lrp->args.layout);
+33 −7
Original line number Diff line number Diff line
@@ -909,6 +909,7 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid,
		status = -ENOMEM;
		spin_lock(&ino->i_lock);
		lo->plh_block_lgets--;
		rpc_wake_up(&NFS_SERVER(ino)->roc_rpcwaitq);
		spin_unlock(&ino->i_lock);
		pnfs_put_layout_hdr(lo);
		goto out;
@@ -926,11 +927,6 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, nfs4_stateid stateid,

	status = nfs4_proc_layoutreturn(lrp, sync);
out:
	if (status) {
		spin_lock(&ino->i_lock);
		clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
		spin_unlock(&ino->i_lock);
	}
	dprintk("<-- %s status: %d\n", __func__, status);
	return status;
}
@@ -1028,8 +1024,9 @@ bool pnfs_roc(struct inode *ino)
{
	struct pnfs_layout_hdr *lo;
	struct pnfs_layout_segment *lseg, *tmp;
	nfs4_stateid stateid;
	LIST_HEAD(tmp_list);
	bool found = false;
	bool found = false, layoutreturn = false;

	spin_lock(&ino->i_lock);
	lo = NFS_I(ino)->layout;
@@ -1050,7 +1047,20 @@ bool pnfs_roc(struct inode *ino)
	return true;

out_nolayout:
	if (lo) {
		stateid = lo->plh_stateid;
		layoutreturn =
			test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
					   &lo->plh_flags);
		if (layoutreturn) {
			lo->plh_block_lgets++;
			pnfs_get_layout_hdr(lo);
		}
	}
	spin_unlock(&ino->i_lock);
	if (layoutreturn)
		pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, 0,
				       NFS4_MAX_UINT64, true);
	return false;
}

@@ -1085,8 +1095,9 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
	struct nfs_inode *nfsi = NFS_I(ino);
	struct pnfs_layout_hdr *lo;
	struct pnfs_layout_segment *lseg;
	nfs4_stateid stateid;
	u32 current_seqid;
	bool found = false;
	bool found = false, layoutreturn = false;

	spin_lock(&ino->i_lock);
	list_for_each_entry(lseg, &nfsi->layout->plh_segs, pls_list)
@@ -1103,7 +1114,22 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
	 */
	*barrier = current_seqid + atomic_read(&lo->plh_outstanding);
out:
	if (!found) {
		stateid = lo->plh_stateid;
		layoutreturn =
			test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
					   &lo->plh_flags);
		if (layoutreturn) {
			lo->plh_block_lgets++;
			pnfs_get_layout_hdr(lo);
		}
	}
	spin_unlock(&ino->i_lock);
	if (layoutreturn) {
		rpc_sleep_on(&NFS_SERVER(ino)->roc_rpcwaitq, task, NULL);
		pnfs_send_layoutreturn(lo, stateid, IOMODE_ANY, 0,
				       NFS4_MAX_UINT64, false);
	}
	return found;
}

+1 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ enum {
	NFS_LAYOUT_BULK_RECALL,		/* bulk recall affecting layout */
	NFS_LAYOUT_ROC,			/* some lseg had roc bit set */
	NFS_LAYOUT_RETURN,		/* Return this layout ASAP */
	NFS_LAYOUT_RETURN_BEFORE_CLOSE,	/* Return this layout before close */
	NFS_LAYOUT_INVALID_STID,	/* layout stateid id is invalid */
	NFS_LAYOUT_FIRST_LAYOUTGET,	/* Serialize first layoutget */
};