|
@@ -490,11 +490,17 @@ static void nfs41_init_sequence(struct nfs4_sequence_args *args,
|
|
|
{
|
|
|
args->sa_slot = NULL;
|
|
|
args->sa_cache_this = 0;
|
|
|
+ args->sa_privileged = 0;
|
|
|
if (cache_reply)
|
|
|
args->sa_cache_this = 1;
|
|
|
res->sr_slot = NULL;
|
|
|
}
|
|
|
|
|
|
+static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
|
|
|
+{
|
|
|
+ args->sa_privileged = 1;
|
|
|
+}
|
|
|
+
|
|
|
int nfs41_setup_sequence(struct nfs4_session *session,
|
|
|
struct nfs4_sequence_args *args,
|
|
|
struct nfs4_sequence_res *res,
|
|
@@ -514,7 +520,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
|
|
|
|
|
|
spin_lock(&tbl->slot_tbl_lock);
|
|
|
if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) &&
|
|
|
- !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
|
|
|
+ !args->sa_privileged) {
|
|
|
/* The state manager will wait until the slot table is empty */
|
|
|
dprintk("%s session is draining\n", __func__);
|
|
|
goto out_sleep;
|
|
@@ -548,6 +554,9 @@ out_success:
|
|
|
rpc_call_start(task);
|
|
|
return 0;
|
|
|
out_sleep:
|
|
|
+ /* Privileged tasks are queued with top priority */
|
|
|
+ if (args->sa_privileged)
|
|
|
+ rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
|
|
|
spin_unlock(&tbl->slot_tbl_lock);
|
|
|
return -EAGAIN;
|
|
@@ -593,12 +602,6 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
|
|
|
nfs41_setup_sequence(session, data->seq_args, data->seq_res, task);
|
|
|
}
|
|
|
|
|
|
-static void nfs41_call_priv_sync_prepare(struct rpc_task *task, void *calldata)
|
|
|
-{
|
|
|
- rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
- nfs41_call_sync_prepare(task, calldata);
|
|
|
-}
|
|
|
-
|
|
|
static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
|
|
|
{
|
|
|
struct nfs41_call_sync_data *data = calldata;
|
|
@@ -611,17 +614,11 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {
|
|
|
.rpc_call_done = nfs41_call_sync_done,
|
|
|
};
|
|
|
|
|
|
-static const struct rpc_call_ops nfs41_call_priv_sync_ops = {
|
|
|
- .rpc_call_prepare = nfs41_call_priv_sync_prepare,
|
|
|
- .rpc_call_done = nfs41_call_sync_done,
|
|
|
-};
|
|
|
-
|
|
|
static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
|
|
|
struct nfs_server *server,
|
|
|
struct rpc_message *msg,
|
|
|
struct nfs4_sequence_args *args,
|
|
|
- struct nfs4_sequence_res *res,
|
|
|
- int privileged)
|
|
|
+ struct nfs4_sequence_res *res)
|
|
|
{
|
|
|
int ret;
|
|
|
struct rpc_task *task;
|
|
@@ -637,8 +634,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
|
|
|
.callback_data = &data
|
|
|
};
|
|
|
|
|
|
- if (privileged)
|
|
|
- task_setup.callback_ops = &nfs41_call_priv_sync_ops;
|
|
|
task = rpc_run_task(&task_setup);
|
|
|
if (IS_ERR(task))
|
|
|
ret = PTR_ERR(task);
|
|
@@ -656,16 +651,21 @@ int _nfs4_call_sync_session(struct rpc_clnt *clnt,
|
|
|
struct nfs4_sequence_args *args,
|
|
|
struct nfs4_sequence_res *res)
|
|
|
{
|
|
|
- return nfs4_call_sync_sequence(clnt, server, msg, args, res, 0);
|
|
|
+ return nfs4_call_sync_sequence(clnt, server, msg, args, res);
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
-static inline
|
|
|
+static
|
|
|
void nfs41_init_sequence(struct nfs4_sequence_args *args,
|
|
|
struct nfs4_sequence_res *res, int cache_reply)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int nfs4_sequence_done(struct rpc_task *task,
|
|
|
struct nfs4_sequence_res *res)
|
|
|
{
|
|
@@ -1475,13 +1475,6 @@ unlock_no_action:
|
|
|
rcu_read_unlock();
|
|
|
out_no_action:
|
|
|
task->tk_action = NULL;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-static void nfs4_recover_open_prepare(struct rpc_task *task, void *calldata)
|
|
|
-{
|
|
|
- rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
- nfs4_open_prepare(task, calldata);
|
|
|
}
|
|
|
|
|
|
static void nfs4_open_done(struct rpc_task *task, void *calldata)
|
|
@@ -1542,12 +1535,6 @@ static const struct rpc_call_ops nfs4_open_ops = {
|
|
|
.rpc_release = nfs4_open_release,
|
|
|
};
|
|
|
|
|
|
-static const struct rpc_call_ops nfs4_recover_open_ops = {
|
|
|
- .rpc_call_prepare = nfs4_recover_open_prepare,
|
|
|
- .rpc_call_done = nfs4_open_done,
|
|
|
- .rpc_release = nfs4_open_release,
|
|
|
-};
|
|
|
-
|
|
|
static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
|
|
|
{
|
|
|
struct inode *dir = data->dir->d_inode;
|
|
@@ -1577,7 +1564,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
|
|
|
data->rpc_status = 0;
|
|
|
data->cancelled = 0;
|
|
|
if (isrecover)
|
|
|
- task_setup_data.callback_ops = &nfs4_recover_open_ops;
|
|
|
+ nfs4_set_sequence_privileged(&o_arg->seq_args);
|
|
|
task = rpc_run_task(&task_setup_data);
|
|
|
if (IS_ERR(task))
|
|
|
return PTR_ERR(task);
|
|
@@ -4558,8 +4545,9 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
|
|
|
return;
|
|
|
/* Do we need to do an open_to_lock_owner? */
|
|
|
if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
|
|
|
- if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
|
|
|
+ if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) {
|
|
|
goto out_release_lock_seqid;
|
|
|
+ }
|
|
|
data->arg.open_stateid = &state->stateid;
|
|
|
data->arg.new_lock_owner = 1;
|
|
|
data->res.open_seqid = data->arg.open_seqid;
|
|
@@ -4574,13 +4562,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
|
|
|
nfs_release_seqid(data->arg.open_seqid);
|
|
|
out_release_lock_seqid:
|
|
|
nfs_release_seqid(data->arg.lock_seqid);
|
|
|
- dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
|
|
|
-}
|
|
|
-
|
|
|
-static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
|
|
|
-{
|
|
|
- rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
- nfs4_lock_prepare(task, calldata);
|
|
|
+ dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
|
|
|
}
|
|
|
|
|
|
static void nfs4_lock_done(struct rpc_task *task, void *calldata)
|
|
@@ -4635,12 +4617,6 @@ static const struct rpc_call_ops nfs4_lock_ops = {
|
|
|
.rpc_release = nfs4_lock_release,
|
|
|
};
|
|
|
|
|
|
-static const struct rpc_call_ops nfs4_recover_lock_ops = {
|
|
|
- .rpc_call_prepare = nfs4_recover_lock_prepare,
|
|
|
- .rpc_call_done = nfs4_lock_done,
|
|
|
- .rpc_release = nfs4_lock_release,
|
|
|
-};
|
|
|
-
|
|
|
static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
|
|
|
{
|
|
|
switch (error) {
|
|
@@ -4683,15 +4659,15 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
|
|
|
return -ENOMEM;
|
|
|
if (IS_SETLKW(cmd))
|
|
|
data->arg.block = 1;
|
|
|
- if (recovery_type > NFS_LOCK_NEW) {
|
|
|
- if (recovery_type == NFS_LOCK_RECLAIM)
|
|
|
- data->arg.reclaim = NFS_LOCK_RECLAIM;
|
|
|
- task_setup_data.callback_ops = &nfs4_recover_lock_ops;
|
|
|
- }
|
|
|
nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
|
|
|
msg.rpc_argp = &data->arg;
|
|
|
msg.rpc_resp = &data->res;
|
|
|
task_setup_data.callback_data = data;
|
|
|
+ if (recovery_type > NFS_LOCK_NEW) {
|
|
|
+ if (recovery_type == NFS_LOCK_RECLAIM)
|
|
|
+ data->arg.reclaim = NFS_LOCK_RECLAIM;
|
|
|
+ nfs4_set_sequence_privileged(&data->arg.seq_args);
|
|
|
+ }
|
|
|
task = rpc_run_task(&task_setup_data);
|
|
|
if (IS_ERR(task))
|
|
|
return PTR_ERR(task);
|
|
@@ -5432,7 +5408,6 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
|
|
|
(struct nfs4_get_lease_time_data *)calldata;
|
|
|
|
|
|
dprintk("--> %s\n", __func__);
|
|
|
- rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
/* just setup sequence, do not trigger session recovery
|
|
|
since we're invoked within one */
|
|
|
nfs41_setup_sequence(data->clp->cl_session,
|
|
@@ -5500,6 +5475,7 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
|
|
|
int status;
|
|
|
|
|
|
nfs41_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0);
|
|
|
+ nfs4_set_sequence_privileged(&args.la_seq_args);
|
|
|
dprintk("--> %s\n", __func__);
|
|
|
task = rpc_run_task(&task_setup);
|
|
|
|
|
@@ -5775,26 +5751,15 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
|
|
|
nfs41_setup_sequence(clp->cl_session, args, res, task);
|
|
|
}
|
|
|
|
|
|
-static void nfs41_sequence_prepare_privileged(struct rpc_task *task, void *data)
|
|
|
-{
|
|
|
- rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
- nfs41_sequence_prepare(task, data);
|
|
|
-}
|
|
|
-
|
|
|
static const struct rpc_call_ops nfs41_sequence_ops = {
|
|
|
.rpc_call_done = nfs41_sequence_call_done,
|
|
|
.rpc_call_prepare = nfs41_sequence_prepare,
|
|
|
.rpc_release = nfs41_sequence_release,
|
|
|
};
|
|
|
|
|
|
-static const struct rpc_call_ops nfs41_sequence_privileged_ops = {
|
|
|
- .rpc_call_done = nfs41_sequence_call_done,
|
|
|
- .rpc_call_prepare = nfs41_sequence_prepare_privileged,
|
|
|
- .rpc_release = nfs41_sequence_release,
|
|
|
-};
|
|
|
-
|
|
|
-static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred,
|
|
|
- const struct rpc_call_ops *seq_ops)
|
|
|
+static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
|
|
|
+ struct rpc_cred *cred,
|
|
|
+ bool is_privileged)
|
|
|
{
|
|
|
struct nfs4_sequence_data *calldata;
|
|
|
struct rpc_message msg = {
|
|
@@ -5804,7 +5769,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
|
|
|
struct rpc_task_setup task_setup_data = {
|
|
|
.rpc_client = clp->cl_rpcclient,
|
|
|
.rpc_message = &msg,
|
|
|
- .callback_ops = seq_ops,
|
|
|
+ .callback_ops = &nfs41_sequence_ops,
|
|
|
.flags = RPC_TASK_ASYNC | RPC_TASK_SOFT,
|
|
|
};
|
|
|
|
|
@@ -5816,6 +5781,8 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
}
|
|
|
nfs41_init_sequence(&calldata->args, &calldata->res, 0);
|
|
|
+ if (is_privileged)
|
|
|
+ nfs4_set_sequence_privileged(&calldata->args);
|
|
|
msg.rpc_argp = &calldata->args;
|
|
|
msg.rpc_resp = &calldata->res;
|
|
|
calldata->clp = clp;
|
|
@@ -5831,7 +5798,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
|
|
|
|
|
|
if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
|
|
|
return 0;
|
|
|
- task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_ops);
|
|
|
+ task = _nfs41_proc_sequence(clp, cred, false);
|
|
|
if (IS_ERR(task))
|
|
|
ret = PTR_ERR(task);
|
|
|
else
|
|
@@ -5845,7 +5812,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
struct rpc_task *task;
|
|
|
int ret;
|
|
|
|
|
|
- task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_privileged_ops);
|
|
|
+ task = _nfs41_proc_sequence(clp, cred, true);
|
|
|
if (IS_ERR(task)) {
|
|
|
ret = PTR_ERR(task);
|
|
|
goto out;
|
|
@@ -5874,7 +5841,6 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
|
|
|
{
|
|
|
struct nfs4_reclaim_complete_data *calldata = data;
|
|
|
|
|
|
- rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
|
|
|
nfs41_setup_sequence(calldata->clp->cl_session,
|
|
|
&calldata->arg.seq_args,
|
|
|
&calldata->res.seq_res,
|
|
@@ -5955,6 +5921,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
|
|
|
calldata->arg.one_fs = 0;
|
|
|
|
|
|
nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0);
|
|
|
+ nfs4_set_sequence_privileged(&calldata->arg.seq_args);
|
|
|
msg.rpc_argp = &calldata->arg;
|
|
|
msg.rpc_resp = &calldata->res;
|
|
|
task_setup_data.callback_data = calldata;
|
|
@@ -6521,7 +6488,9 @@ static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
|
|
|
|
|
|
dprintk("NFS call test_stateid %p\n", stateid);
|
|
|
nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
|
|
|
- status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
|
|
|
+ nfs4_set_sequence_privileged(&args.seq_args);
|
|
|
+ status = nfs4_call_sync_sequence(server->client, server, &msg,
|
|
|
+ &args.seq_args, &res.seq_res);
|
|
|
if (status != NFS_OK) {
|
|
|
dprintk("NFS reply test_stateid: failed, %d\n", status);
|
|
|
return status;
|
|
@@ -6568,8 +6537,9 @@ static int _nfs4_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
|
|
|
|
|
|
dprintk("NFS call free_stateid %p\n", stateid);
|
|
|
nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
|
|
|
+ nfs4_set_sequence_privileged(&args.seq_args);
|
|
|
status = nfs4_call_sync_sequence(server->client, server, &msg,
|
|
|
- &args.seq_args, &res.seq_res, 1);
|
|
|
+ &args.seq_args, &res.seq_res);
|
|
|
dprintk("NFS reply free_stateid: %d\n", status);
|
|
|
return status;
|
|
|
}
|