NFSv4: Enable delegated opens even when reboot recovery is pending

Unlike the previous attempt, this takes into account the fact that
we may be calling it from the recovery thread itself. Detect this
by looking at what kind of open we're doing, and checking the state
of the NFS_DELEGATION_NEED_RECLAIM if it turns out we're doing a
reboot reclaim-type open.

Cc: Olga Kornievskaia <aglo@umich.edu>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
Trond Myklebust 2015-08-19 22:30:00 -05:00
parent c740624989
commit 2a606188c5
2 changed files with 20 additions and 9 deletions

View File

@ -1150,16 +1150,25 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
return ret; return ret;
} }
static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode,
enum open_claim_type4 claim)
{ {
if (delegation == NULL) if (delegation == NULL)
return 0; return 0;
if ((delegation->type & fmode) != fmode) if ((delegation->type & fmode) != fmode)
return 0; return 0;
if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
return 0;
if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
return 0; return 0;
switch (claim) {
case NFS4_OPEN_CLAIM_NULL:
case NFS4_OPEN_CLAIM_FH:
break;
case NFS4_OPEN_CLAIM_PREVIOUS:
if (!test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
break;
default:
return 0;
}
nfs_mark_delegation_referenced(delegation); nfs_mark_delegation_referenced(delegation);
return 1; return 1;
} }
@ -1378,6 +1387,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
struct nfs_delegation *delegation; struct nfs_delegation *delegation;
int open_mode = opendata->o_arg.open_flags; int open_mode = opendata->o_arg.open_flags;
fmode_t fmode = opendata->o_arg.fmode; fmode_t fmode = opendata->o_arg.fmode;
enum open_claim_type4 claim = opendata->o_arg.claim;
nfs4_stateid stateid; nfs4_stateid stateid;
int ret = -EAGAIN; int ret = -EAGAIN;
@ -1391,7 +1401,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
spin_unlock(&state->owner->so_lock); spin_unlock(&state->owner->so_lock);
rcu_read_lock(); rcu_read_lock();
delegation = rcu_dereference(nfsi->delegation); delegation = rcu_dereference(nfsi->delegation);
if (!can_open_delegated(delegation, fmode)) { if (!can_open_delegated(delegation, fmode, claim)) {
rcu_read_unlock(); rcu_read_unlock();
break; break;
} }
@ -1854,6 +1864,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
struct nfs4_opendata *data = calldata; struct nfs4_opendata *data = calldata;
struct nfs4_state_owner *sp = data->owner; struct nfs4_state_owner *sp = data->owner;
struct nfs_client *clp = sp->so_server->nfs_client; struct nfs_client *clp = sp->so_server->nfs_client;
enum open_claim_type4 claim = data->o_arg.claim;
if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
goto out_wait; goto out_wait;
@ -1868,15 +1879,15 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
goto out_no_action; goto out_no_action;
rcu_read_lock(); rcu_read_lock();
delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);
if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR && if (can_open_delegated(delegation, data->o_arg.fmode, claim))
data->o_arg.claim != NFS4_OPEN_CLAIM_DELEG_CUR_FH &&
can_open_delegated(delegation, data->o_arg.fmode))
goto unlock_no_action; goto unlock_no_action;
rcu_read_unlock(); rcu_read_unlock();
} }
/* Update client id. */ /* Update client id. */
data->o_arg.clientid = clp->cl_clientid; data->o_arg.clientid = clp->cl_clientid;
switch (data->o_arg.claim) { switch (claim) {
default:
break;
case NFS4_OPEN_CLAIM_PREVIOUS: case NFS4_OPEN_CLAIM_PREVIOUS:
case NFS4_OPEN_CLAIM_DELEG_CUR_FH: case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
case NFS4_OPEN_CLAIM_DELEG_PREV_FH: case NFS4_OPEN_CLAIM_DELEG_PREV_FH:

View File

@ -389,7 +389,7 @@ struct nfs_openargs {
const struct nfs_server *server; /* Needed for ID mapping */ const struct nfs_server *server; /* Needed for ID mapping */
const u32 * bitmask; const u32 * bitmask;
const u32 * open_bitmap; const u32 * open_bitmap;
__u32 claim; enum open_claim_type4 claim;
enum createmode4 createmode; enum createmode4 createmode;
const struct nfs4_label *label; const struct nfs4_label *label;
}; };