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

Commit 6c342655 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Return NFS4ERR_DELAY when a delegation recall fails due to igrab()



If the attempt to recall the delegation fails because the inode is
in the process of being evicted from cache, then use NFS4ERR_DELAY
to ask the server to retry later.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 025bb9f8
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -40,7 +40,9 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
		rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR));

	inode = nfs_delegation_find_inode(cps->clp, &args->fh);
	if (inode == NULL) {
	if (IS_ERR(inode)) {
		if (inode == ERR_PTR(-EAGAIN))
			res->status = htonl(NFS4ERR_DELAY);
		trace_nfs4_cb_getattr(cps->clp, &args->fh, NULL,
				-ntohl(res->status));
		goto out;
@@ -86,7 +88,9 @@ __be32 nfs4_callback_recall(void *argp, void *resp,

	res = htonl(NFS4ERR_BADHANDLE);
	inode = nfs_delegation_find_inode(cps->clp, &args->fh);
	if (inode == NULL) {
	if (IS_ERR(inode)) {
		if (inode == ERR_PTR(-EAGAIN))
			res = htonl(NFS4ERR_DELAY);
		trace_nfs4_cb_recall(cps->clp, &args->fh, NULL,
				&args->stateid, -ntohl(res));
		goto out;
+9 −7
Original line number Diff line number Diff line
@@ -856,12 +856,14 @@ nfs_delegation_find_inode_server(struct nfs_server *server,
		if (delegation->inode != NULL &&
		    nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
			res = igrab(delegation->inode);
		}
			spin_unlock(&delegation->lock);
			if (res != NULL)
			break;
	}
				return res;
			return ERR_PTR(-EAGAIN);
		}
		spin_unlock(&delegation->lock);
	}
	return ERR_PTR(-ENOENT);
}

/**
@@ -876,16 +878,16 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
					const struct nfs_fh *fhandle)
{
	struct nfs_server *server;
	struct inode *res = NULL;
	struct inode *res;

	rcu_read_lock();
	list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
		res = nfs_delegation_find_inode_server(server, fhandle);
		if (res != NULL)
			break;
		if (res != ERR_PTR(-ENOENT))
			return res;
	}
	rcu_read_unlock();
	return res;
	return ERR_PTR(-ENOENT);
}

static void nfs_delegation_mark_reclaim_server(struct nfs_server *server)