Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 367275
b: refs/heads/master
c: 5d42230
h: refs/heads/master
i:
  367273: 40a0d41
  367271: bc741b5
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Mar 25, 2013
1 parent c735433 commit cd48b80
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ed5e2a2c394df4e03a680842c2d07a8680f133b
refs/heads/master: 5d422301f97b821301efcdb6fc9d1a83a5c102d6
8 changes: 7 additions & 1 deletion trunk/fs/nfs/nfs4_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ enum {
NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */
NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */
NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */
NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */
};

struct nfs4_state {
Expand Down Expand Up @@ -347,7 +348,7 @@ extern int nfs4_wait_clnt_recover(struct nfs_client *clp);
extern int nfs4_client_recover_expired_lease(struct nfs_client *clp);
extern void nfs4_schedule_state_manager(struct nfs_client *);
extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
extern void nfs41_handle_server_scope(struct nfs_client *,
struct nfs41_server_scope **);
Expand Down Expand Up @@ -412,6 +413,11 @@ static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_statei
return memcmp(dst, src, sizeof(*dst)) == 0;
}

static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
{
return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0;
}

#else

#define nfs4_close_state(a, b) do { } while (0)
Expand Down
12 changes: 9 additions & 3 deletions trunk/fs/nfs/nfs4filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,14 @@ static int filelayout_async_handle_error(struct rpc_task *task,
case -NFS4ERR_OPENMODE:
if (state == NULL)
break;
nfs4_schedule_stateid_recovery(mds_server, state);
if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
goto out_bad_stateid;
goto wait_on_recovery;
case -NFS4ERR_EXPIRED:
if (state != NULL)
nfs4_schedule_stateid_recovery(mds_server, state);
if (state != NULL) {
if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
goto out_bad_stateid;
}
nfs4_schedule_lease_recovery(mds_client);
goto wait_on_recovery;
/* DS session errors */
Expand Down Expand Up @@ -226,6 +229,9 @@ static int filelayout_async_handle_error(struct rpc_task *task,
out:
task->tk_status = 0;
return -EAGAIN;
out_bad_stateid:
task->tk_status = -EIO;
return 0;
wait_on_recovery:
rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL);
if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0)
Expand Down
37 changes: 29 additions & 8 deletions trunk/fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,19 +295,26 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
}
if (state == NULL)
break;
nfs4_schedule_stateid_recovery(server, state);
ret = nfs4_schedule_stateid_recovery(server, state);
if (ret < 0)
break;
goto wait_on_recovery;
case -NFS4ERR_DELEG_REVOKED:
case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_BAD_STATEID:
if (state == NULL)
break;
nfs_remove_bad_delegation(state->inode);
nfs4_schedule_stateid_recovery(server, state);
ret = nfs4_schedule_stateid_recovery(server, state);
if (ret < 0)
break;
goto wait_on_recovery;
case -NFS4ERR_EXPIRED:
if (state != NULL)
nfs4_schedule_stateid_recovery(server, state);
if (state != NULL) {
ret = nfs4_schedule_stateid_recovery(server, state);
if (ret < 0)
break;
}
case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_STALE_CLIENTID:
nfs4_schedule_lease_recovery(clp);
Expand Down Expand Up @@ -2053,7 +2060,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,

nfs_fattr_init(fattr);

if (state != NULL) {
if (state != NULL && nfs4_valid_open_stateid(state)) {
struct nfs_lockowner lockowner = {
.l_owner = current->files,
.l_pid = current->tgid,
Expand Down Expand Up @@ -2201,6 +2208,8 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
calldata->arg.fmode &= ~FMODE_WRITE;
}
}
if (!nfs4_valid_open_stateid(state))
call_close = 0;
spin_unlock(&state->owner->so_lock);

if (!call_close) {
Expand Down Expand Up @@ -3980,11 +3989,14 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
case -NFS4ERR_OPENMODE:
if (state == NULL)
break;
nfs4_schedule_stateid_recovery(server, state);
if (nfs4_schedule_stateid_recovery(server, state) < 0)
goto stateid_invalid;
goto wait_on_recovery;
case -NFS4ERR_EXPIRED:
if (state != NULL)
nfs4_schedule_stateid_recovery(server, state);
if (state != NULL) {
if (nfs4_schedule_stateid_recovery(server, state) < 0)
goto stateid_invalid;
}
case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_STALE_CLIENTID:
nfs4_schedule_lease_recovery(clp);
Expand Down Expand Up @@ -4016,6 +4028,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
}
task->tk_status = nfs4_map_errors(task->tk_status);
return 0;
stateid_invalid:
task->tk_status = -EIO;
return 0;
wait_on_recovery:
rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
Expand Down Expand Up @@ -4632,12 +4647,18 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
data->res.open_seqid = data->arg.open_seqid;
} else
data->arg.new_lock_owner = 0;
if (!nfs4_valid_open_stateid(state)) {
data->rpc_status = -EBADF;
task->tk_action = NULL;
goto out_release_open_seqid;
}
data->timestamp = jiffies;
if (nfs4_setup_sequence(data->server,
&data->arg.seq_args,
&data->res.seq_res,
task) == 0)
return;
out_release_open_seqid:
nfs_release_seqid(data->arg.open_seqid);
out_release_lock_seqid:
nfs_release_seqid(data->arg.lock_seqid);
Expand Down
19 changes: 14 additions & 5 deletions trunk/fs/nfs/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,8 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
list_for_each_entry(state, &nfsi->open_states, inode_states) {
if (state->owner != owner)
continue;
if (!nfs4_valid_open_stateid(state))
continue;
if (atomic_inc_not_zero(&state->count))
return state;
}
Expand Down Expand Up @@ -1286,14 +1288,17 @@ static int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_s
return 1;
}

void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state)
int nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state)
{
struct nfs_client *clp = server->nfs_client;

if (!nfs4_valid_open_stateid(state))
return -EBADF;
nfs4_state_mark_reclaim_nograce(clp, state);
dprintk("%s: scheduling stateid recovery for server %s\n", __func__,
clp->cl_hostname);
nfs4_schedule_state_manager(clp);
return 0;
}
EXPORT_SYMBOL_GPL(nfs4_schedule_stateid_recovery);

Expand Down Expand Up @@ -1323,6 +1328,11 @@ void nfs_inode_find_state_and_recover(struct inode *inode,
nfs4_schedule_state_manager(clp);
}

static void nfs4_state_mark_recovery_failed(struct nfs4_state *state, int error)
{
set_bit(NFS_STATE_RECOVERY_FAILED, &state->flags);
}


static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
{
Expand Down Expand Up @@ -1398,6 +1408,8 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
list_for_each_entry(state, &sp->so_states, open_states) {
if (!test_and_clear_bit(ops->state_flag_bit, &state->flags))
continue;
if (!nfs4_valid_open_stateid(state))
continue;
if (state->state == 0)
continue;
atomic_inc(&state->count);
Expand Down Expand Up @@ -1430,10 +1442,7 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
* Open state on this file cannot be recovered
* All we can do is revert to using the zero stateid.
*/
memset(&state->stateid, 0,
sizeof(state->stateid));
/* Mark the file as being 'closed' */
state->state = 0;
nfs4_state_mark_recovery_failed(state, status);
break;
case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_STALE_STATEID:
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
spin_lock(&lo->plh_inode->i_lock);
if (pnfs_layoutgets_blocked(lo, 1)) {
status = -EAGAIN;
} else if (!nfs4_valid_open_stateid(open_state)) {
status = -EBADF;
} else if (list_empty(&lo->plh_segs)) {
int seq;

Expand Down

0 comments on commit cd48b80

Please sign in to comment.