Commit b4a558fd authored by Trond Myklebust's avatar Trond Myklebust

RPC,NFSv4: NFSv4 operations that create or destroy state on the

   server are not allowed to be interrupted as that may result in the
   client and server disagreeing.
parent fdd46e51
...@@ -227,7 +227,7 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st ...@@ -227,7 +227,7 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
} }
o_arg.u.delegation_type = delegation->type; o_arg.u.delegation_type = delegation->type;
} }
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
nfs4_increment_seqid(status, sp); nfs4_increment_seqid(status, sp);
if (status == 0) { if (status == 0) {
memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid)); memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
...@@ -297,7 +297,7 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state ...@@ -297,7 +297,7 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state
arg.seqid = sp->so_seqid; arg.seqid = sp->so_seqid;
arg.open_flags = state->state; arg.open_flags = state->state;
memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data)); memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data));
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
nfs4_increment_seqid(status, sp); nfs4_increment_seqid(status, sp);
if (status >= 0) { if (status >= 0) {
memcpy(state->stateid.data, res.stateid.data, memcpy(state->stateid.data, res.stateid.data,
...@@ -348,7 +348,7 @@ static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *f ...@@ -348,7 +348,7 @@ static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *f
}; };
int status; int status;
status = rpc_call_sync(clnt, &msg, 0); status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR);
nfs4_increment_seqid(status, sp); nfs4_increment_seqid(status, sp);
if (status >= 0) if (status >= 0)
memcpy(stateid, &res.stateid, sizeof(*stateid)); memcpy(stateid, &res.stateid, sizeof(*stateid));
...@@ -526,7 +526,7 @@ static int _nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct ...@@ -526,7 +526,7 @@ static int _nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct
o_arg.id = sp->so_id; o_arg.id = sp->so_id;
o_arg.clientid = clp->cl_clientid, o_arg.clientid = clp->cl_clientid,
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
nfs4_increment_seqid(status, sp); nfs4_increment_seqid(status, sp);
if (status) if (status)
goto out_err; goto out_err;
...@@ -688,7 +688,7 @@ static int _nfs4_do_close(struct inode *inode, struct nfs4_state *state) ...@@ -688,7 +688,7 @@ static int _nfs4_do_close(struct inode *inode, struct nfs4_state *state)
memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid)); memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid));
/* Serialization for the sequence id */ /* Serialization for the sequence id */
arg.seqid = sp->so_seqid, arg.seqid = sp->so_seqid,
status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0); status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, RPC_TASK_NOINTR);
/* hmm. we are done with the inode, and in the process of freeing /* hmm. we are done with the inode, and in the process of freeing
* the state_owner. we keep this around to process errors * the state_owner. we keep this around to process errors
...@@ -739,7 +739,7 @@ static int _nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mod ...@@ -739,7 +739,7 @@ static int _nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mod
if (test_bit(NFS_DELEGATED_STATE, &state->flags)) if (test_bit(NFS_DELEGATED_STATE, &state->flags))
return 0; return 0;
memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid)); memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid));
status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0); status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, RPC_TASK_NOINTR);
nfs4_increment_seqid(status, sp); nfs4_increment_seqid(status, sp);
if (!status) if (!status)
memcpy(&state->stateid, &res.stateid, sizeof(state->stateid)); memcpy(&state->stateid, &res.stateid, sizeof(state->stateid));
...@@ -2403,7 +2403,7 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock ...@@ -2403,7 +2403,7 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock
luargs.seqid = lsp->ls_seqid; luargs.seqid = lsp->ls_seqid;
memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid)); memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
arg.u.locku = &luargs; arg.u.locku = &luargs;
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
nfs4_increment_lock_seqid(status, lsp); nfs4_increment_lock_seqid(status, lsp);
} }
...@@ -2479,7 +2479,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r ...@@ -2479,7 +2479,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
arg.u.lock = &largs; arg.u.lock = &largs;
down(&owner->so_sema); down(&owner->so_sema);
otl.open_seqid = owner->so_seqid; otl.open_seqid = owner->so_seqid;
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
/* increment open_owner seqid on success, and /* increment open_owner seqid on success, and
* seqid mutating errors */ * seqid mutating errors */
nfs4_increment_seqid(status, owner); nfs4_increment_seqid(status, owner);
...@@ -2492,7 +2492,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r ...@@ -2492,7 +2492,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
largs.u.exist_lock = ⪙ largs.u.exist_lock = ⪙
largs.new_lock_owner = 0; largs.new_lock_owner = 0;
arg.u.lock = &largs; arg.u.lock = &largs;
status = rpc_call_sync(server->client, &msg, 0); status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
} }
/* increment seqid on success, and * seqid mutating errors*/ /* increment seqid on success, and * seqid mutating errors*/
nfs4_increment_lock_seqid(status, lsp); nfs4_increment_lock_seqid(status, lsp);
......
...@@ -113,6 +113,7 @@ typedef void (*rpc_action)(struct rpc_task *); ...@@ -113,6 +113,7 @@ typedef void (*rpc_action)(struct rpc_task *);
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */ #define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
#define RPC_TASK_KILLED 0x0100 /* task was killed */ #define RPC_TASK_KILLED 0x0100 /* task was killed */
#define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */ #define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */
#define RPC_TASK_NOINTR 0x0400 /* uninterruptible task */
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
#define RPC_IS_SETUID(t) ((t)->tk_flags & RPC_TASK_SETUID) #define RPC_IS_SETUID(t) ((t)->tk_flags & RPC_TASK_SETUID)
...@@ -123,6 +124,7 @@ typedef void (*rpc_action)(struct rpc_task *); ...@@ -123,6 +124,7 @@ typedef void (*rpc_action)(struct rpc_task *);
#define RPC_IS_ACTIVATED(t) ((t)->tk_active) #define RPC_IS_ACTIVATED(t) ((t)->tk_active)
#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL) #define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL)
#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
#define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
#define RPC_TASK_SLEEPING 0 #define RPC_TASK_SLEEPING 0
#define RPC_TASK_RUNNING 1 #define RPC_TASK_RUNNING 1
......
...@@ -698,7 +698,7 @@ __rpc_execute(struct rpc_task *task) ...@@ -698,7 +698,7 @@ __rpc_execute(struct rpc_task *task)
if (current->pid == rpciod_pid) if (current->pid == rpciod_pid)
printk(KERN_ERR "RPC: rpciod waiting on sync task!\n"); printk(KERN_ERR "RPC: rpciod waiting on sync task!\n");
if (!task->tk_client->cl_intr) { if (RPC_TASK_UNINTERRUPTIBLE(task)) {
__wait_event(task->tk_wait, !RPC_IS_SLEEPING(task)); __wait_event(task->tk_wait, !RPC_IS_SLEEPING(task));
} else { } else {
__wait_event_interruptible(task->tk_wait, !RPC_IS_SLEEPING(task), status); __wait_event_interruptible(task->tk_wait, !RPC_IS_SLEEPING(task), status);
...@@ -884,6 +884,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call ...@@ -884,6 +884,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call
atomic_inc(&clnt->cl_users); atomic_inc(&clnt->cl_users);
if (clnt->cl_softrtry) if (clnt->cl_softrtry)
task->tk_flags |= RPC_TASK_SOFT; task->tk_flags |= RPC_TASK_SOFT;
if (!clnt->cl_intr)
task->tk_flags |= RPC_TASK_NOINTR;
} }
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment