|
@@ -62,7 +62,7 @@
|
|
struct nfs4_opendata;
|
|
struct nfs4_opendata;
|
|
static int _nfs4_proc_open(struct nfs4_opendata *data);
|
|
static int _nfs4_proc_open(struct nfs4_opendata *data);
|
|
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
|
|
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
|
|
-static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
|
|
|
|
|
|
+static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
|
|
static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
|
|
|
|
@@ -235,12 +235,19 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
|
|
static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
|
|
static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
|
|
{
|
|
{
|
|
struct nfs_client *clp = server->nfs_client;
|
|
struct nfs_client *clp = server->nfs_client;
|
|
|
|
+ struct nfs4_state *state = exception->state;
|
|
int ret = errorcode;
|
|
int ret = errorcode;
|
|
|
|
|
|
exception->retry = 0;
|
|
exception->retry = 0;
|
|
switch(errorcode) {
|
|
switch(errorcode) {
|
|
case 0:
|
|
case 0:
|
|
return 0;
|
|
return 0;
|
|
|
|
+ case -NFS4ERR_ADMIN_REVOKED:
|
|
|
|
+ case -NFS4ERR_BAD_STATEID:
|
|
|
|
+ case -NFS4ERR_OPENMODE:
|
|
|
|
+ if (state == NULL)
|
|
|
|
+ break;
|
|
|
|
+ nfs4_state_mark_reclaim_nograce(clp, state);
|
|
case -NFS4ERR_STALE_CLIENTID:
|
|
case -NFS4ERR_STALE_CLIENTID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_EXPIRED:
|
|
case -NFS4ERR_EXPIRED:
|
|
@@ -1320,10 +1327,13 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
|
|
renew_lease(server, calldata->timestamp);
|
|
renew_lease(server, calldata->timestamp);
|
|
break;
|
|
break;
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
|
|
+ case -NFS4ERR_OLD_STATEID:
|
|
|
|
+ case -NFS4ERR_BAD_STATEID:
|
|
case -NFS4ERR_EXPIRED:
|
|
case -NFS4ERR_EXPIRED:
|
|
- break;
|
|
|
|
|
|
+ if (calldata->arg.open_flags == 0)
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
- if (nfs4_async_handle_error(task, server) == -EAGAIN) {
|
|
|
|
|
|
+ if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
|
|
rpc_restart_call(task);
|
|
rpc_restart_call(task);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -1418,6 +1428,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
|
|
calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
|
|
calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
|
|
if (calldata->arg.seqid == NULL)
|
|
if (calldata->arg.seqid == NULL)
|
|
goto out_free_calldata;
|
|
goto out_free_calldata;
|
|
|
|
+ calldata->arg.open_flags = 0;
|
|
calldata->arg.bitmask = server->attr_bitmask;
|
|
calldata->arg.bitmask = server->attr_bitmask;
|
|
calldata->res.fattr = &calldata->fattr;
|
|
calldata->res.fattr = &calldata->fattr;
|
|
calldata->res.seqid = calldata->arg.seqid;
|
|
calldata->res.seqid = calldata->arg.seqid;
|
|
@@ -2064,7 +2075,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
|
|
{
|
|
{
|
|
struct nfs_removeres *res = task->tk_msg.rpc_resp;
|
|
struct nfs_removeres *res = task->tk_msg.rpc_resp;
|
|
|
|
|
|
- if (nfs4_async_handle_error(task, res->server) == -EAGAIN)
|
|
|
|
|
|
+ if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
|
|
return 0;
|
|
return 0;
|
|
update_changeattr(dir, &res->cinfo);
|
|
update_changeattr(dir, &res->cinfo);
|
|
nfs_post_op_update_inode(dir, &res->dir_attr);
|
|
nfs_post_op_update_inode(dir, &res->dir_attr);
|
|
@@ -2492,7 +2503,7 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
|
|
{
|
|
{
|
|
struct nfs_server *server = NFS_SERVER(data->inode);
|
|
struct nfs_server *server = NFS_SERVER(data->inode);
|
|
|
|
|
|
- if (nfs4_async_handle_error(task, server) == -EAGAIN) {
|
|
|
|
|
|
+ if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
|
|
rpc_restart_call(task);
|
|
rpc_restart_call(task);
|
|
return -EAGAIN;
|
|
return -EAGAIN;
|
|
}
|
|
}
|
|
@@ -2513,7 +2524,7 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
|
|
{
|
|
{
|
|
struct inode *inode = data->inode;
|
|
struct inode *inode = data->inode;
|
|
|
|
|
|
- if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
|
|
|
|
|
|
+ if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
|
|
rpc_restart_call(task);
|
|
rpc_restart_call(task);
|
|
return -EAGAIN;
|
|
return -EAGAIN;
|
|
}
|
|
}
|
|
@@ -2539,7 +2550,7 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
|
|
{
|
|
{
|
|
struct inode *inode = data->inode;
|
|
struct inode *inode = data->inode;
|
|
|
|
|
|
- if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
|
|
|
|
|
|
+ if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
|
|
rpc_restart_call(task);
|
|
rpc_restart_call(task);
|
|
return -EAGAIN;
|
|
return -EAGAIN;
|
|
}
|
|
}
|
|
@@ -2832,13 +2843,19 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
-nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
|
|
|
|
|
|
+nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
|
|
{
|
|
{
|
|
struct nfs_client *clp = server->nfs_client;
|
|
struct nfs_client *clp = server->nfs_client;
|
|
|
|
|
|
if (!clp || task->tk_status >= 0)
|
|
if (!clp || task->tk_status >= 0)
|
|
return 0;
|
|
return 0;
|
|
switch(task->tk_status) {
|
|
switch(task->tk_status) {
|
|
|
|
+ case -NFS4ERR_ADMIN_REVOKED:
|
|
|
|
+ case -NFS4ERR_BAD_STATEID:
|
|
|
|
+ case -NFS4ERR_OPENMODE:
|
|
|
|
+ if (state == NULL)
|
|
|
|
+ break;
|
|
|
|
+ nfs4_state_mark_reclaim_nograce(clp, state);
|
|
case -NFS4ERR_STALE_CLIENTID:
|
|
case -NFS4ERR_STALE_CLIENTID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_EXPIRED:
|
|
case -NFS4ERR_EXPIRED:
|
|
@@ -3195,11 +3212,13 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
|
|
sizeof(calldata->lsp->ls_stateid.data));
|
|
sizeof(calldata->lsp->ls_stateid.data));
|
|
renew_lease(calldata->server, calldata->timestamp);
|
|
renew_lease(calldata->server, calldata->timestamp);
|
|
break;
|
|
break;
|
|
|
|
+ case -NFS4ERR_BAD_STATEID:
|
|
|
|
+ case -NFS4ERR_OLD_STATEID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_EXPIRED:
|
|
case -NFS4ERR_EXPIRED:
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN)
|
|
|
|
|
|
+ if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
|
|
rpc_restart_call(task);
|
|
rpc_restart_call(task);
|
|
}
|
|
}
|
|
}
|
|
}
|