aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Kconfig2
-rw-r--r--fs/nfs/nfs4_fs.h5
-rw-r--r--fs/nfs/nfs4proc.c203
-rw-r--r--fs/nfs/nfs4state.c60
-rw-r--r--fs/nfs/super.c8
5 files changed, 196 insertions, 82 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 2a77bc25d5af..59e5673b4597 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -90,7 +90,7 @@ config ROOT_NFS
90 If you want your system to mount its root file system via NFS, 90 If you want your system to mount its root file system via NFS,
91 choose Y here. This is common practice for managing systems 91 choose Y here. This is common practice for managing systems
92 without local permanent storage. For details, read 92 without local permanent storage. For details, read
93 <file:Documentation/filesystems/nfsroot.txt>. 93 <file:Documentation/filesystems/nfs/nfsroot.txt>.
94 94
95 Most people say N here. 95 Most people say N here.
96 96
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 7e57b04e4014..865265bdca03 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -108,6 +108,10 @@ enum {
108 NFS_OWNER_RECLAIM_NOGRACE 108 NFS_OWNER_RECLAIM_NOGRACE
109}; 109};
110 110
111#define NFS_LOCK_NEW 0
112#define NFS_LOCK_RECLAIM 1
113#define NFS_LOCK_EXPIRED 2
114
111/* 115/*
112 * struct nfs4_state maintains the client-side state for a given 116 * struct nfs4_state maintains the client-side state for a given
113 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK). 117 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
@@ -282,6 +286,7 @@ extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
282extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); 286extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
283extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid); 287extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
284extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid); 288extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
289extern void nfs_release_seqid(struct nfs_seqid *seqid);
285extern void nfs_free_seqid(struct nfs_seqid *seqid); 290extern void nfs_free_seqid(struct nfs_seqid *seqid);
286 291
287extern const nfs4_stateid zero_stateid; 292extern const nfs4_stateid zero_stateid;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9f5f11ecfd93..198d51d17c13 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -64,6 +64,7 @@
64 64
65struct nfs4_opendata; 65struct nfs4_opendata;
66static int _nfs4_proc_open(struct nfs4_opendata *data); 66static int _nfs4_proc_open(struct nfs4_opendata *data);
67static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
67static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 68static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
68static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 69static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
69static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 70static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
@@ -341,6 +342,27 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
341 free_slotid, tbl->highest_used_slotid); 342 free_slotid, tbl->highest_used_slotid);
342} 343}
343 344
345/*
346 * Signal state manager thread if session is drained
347 */
348static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
349{
350 struct rpc_task *task;
351
352 if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) {
353 task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
354 if (task)
355 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
356 return;
357 }
358
359 if (ses->fc_slot_table.highest_used_slotid != -1)
360 return;
361
362 dprintk("%s COMPLETE: Session Drained\n", __func__);
363 complete(&ses->complete);
364}
365
344static void nfs41_sequence_free_slot(const struct nfs_client *clp, 366static void nfs41_sequence_free_slot(const struct nfs_client *clp,
345 struct nfs4_sequence_res *res) 367 struct nfs4_sequence_res *res)
346{ 368{
@@ -356,15 +378,7 @@ static void nfs41_sequence_free_slot(const struct nfs_client *clp,
356 378
357 spin_lock(&tbl->slot_tbl_lock); 379 spin_lock(&tbl->slot_tbl_lock);
358 nfs4_free_slot(tbl, res->sr_slotid); 380 nfs4_free_slot(tbl, res->sr_slotid);
359 381 nfs41_check_drain_session_complete(clp->cl_session);
360 /* Signal state manager thread if session is drained */
361 if (test_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) {
362 if (tbl->highest_used_slotid == -1) {
363 dprintk("%s COMPLETE: Session Drained\n", __func__);
364 complete(&clp->cl_session->complete);
365 }
366 } else
367 rpc_wake_up_next(&tbl->slot_tbl_waitq);
368 spin_unlock(&tbl->slot_tbl_lock); 382 spin_unlock(&tbl->slot_tbl_lock);
369 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 383 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
370} 384}
@@ -421,7 +435,7 @@ out:
421 * Note: must be called with under the slot_tbl_lock. 435 * Note: must be called with under the slot_tbl_lock.
422 */ 436 */
423static u8 437static u8
424nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) 438nfs4_find_slot(struct nfs4_slot_table *tbl)
425{ 439{
426 int slotid; 440 int slotid;
427 u8 ret_id = NFS4_MAX_SLOT_TABLE; 441 u8 ret_id = NFS4_MAX_SLOT_TABLE;
@@ -463,7 +477,8 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
463 tbl = &session->fc_slot_table; 477 tbl = &session->fc_slot_table;
464 478
465 spin_lock(&tbl->slot_tbl_lock); 479 spin_lock(&tbl->slot_tbl_lock);
466 if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state)) { 480 if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state) &&
481 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
467 /* 482 /*
468 * The state manager will wait until the slot table is empty. 483 * The state manager will wait until the slot table is empty.
469 * Schedule the reset thread 484 * Schedule the reset thread
@@ -474,7 +489,15 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
474 return -EAGAIN; 489 return -EAGAIN;
475 } 490 }
476 491
477 slotid = nfs4_find_slot(tbl, task); 492 if (!rpc_queue_empty(&tbl->slot_tbl_waitq) &&
493 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
494 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
495 spin_unlock(&tbl->slot_tbl_lock);
496 dprintk("%s enforce FIFO order\n", __func__);
497 return -EAGAIN;
498 }
499
500 slotid = nfs4_find_slot(tbl);
478 if (slotid == NFS4_MAX_SLOT_TABLE) { 501 if (slotid == NFS4_MAX_SLOT_TABLE) {
479 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 502 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
480 spin_unlock(&tbl->slot_tbl_lock); 503 spin_unlock(&tbl->slot_tbl_lock);
@@ -483,6 +506,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
483 } 506 }
484 spin_unlock(&tbl->slot_tbl_lock); 507 spin_unlock(&tbl->slot_tbl_lock);
485 508
509 rpc_task_set_priority(task, RPC_PRIORITY_NORMAL);
486 slot = tbl->slots + slotid; 510 slot = tbl->slots + slotid;
487 args->sa_session = session; 511 args->sa_session = session;
488 args->sa_slotid = slotid; 512 args->sa_slotid = slotid;
@@ -545,6 +569,12 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
545 rpc_call_start(task); 569 rpc_call_start(task);
546} 570}
547 571
572static void nfs41_call_priv_sync_prepare(struct rpc_task *task, void *calldata)
573{
574 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
575 nfs41_call_sync_prepare(task, calldata);
576}
577
548static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 578static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
549{ 579{
550 struct nfs41_call_sync_data *data = calldata; 580 struct nfs41_call_sync_data *data = calldata;
@@ -557,12 +587,18 @@ struct rpc_call_ops nfs41_call_sync_ops = {
557 .rpc_call_done = nfs41_call_sync_done, 587 .rpc_call_done = nfs41_call_sync_done,
558}; 588};
559 589
590struct rpc_call_ops nfs41_call_priv_sync_ops = {
591 .rpc_call_prepare = nfs41_call_priv_sync_prepare,
592 .rpc_call_done = nfs41_call_sync_done,
593};
594
560static int nfs4_call_sync_sequence(struct nfs_client *clp, 595static int nfs4_call_sync_sequence(struct nfs_client *clp,
561 struct rpc_clnt *clnt, 596 struct rpc_clnt *clnt,
562 struct rpc_message *msg, 597 struct rpc_message *msg,
563 struct nfs4_sequence_args *args, 598 struct nfs4_sequence_args *args,
564 struct nfs4_sequence_res *res, 599 struct nfs4_sequence_res *res,
565 int cache_reply) 600 int cache_reply,
601 int privileged)
566{ 602{
567 int ret; 603 int ret;
568 struct rpc_task *task; 604 struct rpc_task *task;
@@ -580,6 +616,8 @@ static int nfs4_call_sync_sequence(struct nfs_client *clp,
580 }; 616 };
581 617
582 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 618 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
619 if (privileged)
620 task_setup.callback_ops = &nfs41_call_priv_sync_ops;
583 task = rpc_run_task(&task_setup); 621 task = rpc_run_task(&task_setup);
584 if (IS_ERR(task)) 622 if (IS_ERR(task))
585 ret = PTR_ERR(task); 623 ret = PTR_ERR(task);
@@ -597,7 +635,7 @@ int _nfs4_call_sync_session(struct nfs_server *server,
597 int cache_reply) 635 int cache_reply)
598{ 636{
599 return nfs4_call_sync_sequence(server->nfs_client, server->client, 637 return nfs4_call_sync_sequence(server->nfs_client, server->client,
600 msg, args, res, cache_reply); 638 msg, args, res, cache_reply, 0);
601} 639}
602 640
603#endif /* CONFIG_NFS_V4_1 */ 641#endif /* CONFIG_NFS_V4_1 */
@@ -1035,7 +1073,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod
1035 memset(&opendata->o_res, 0, sizeof(opendata->o_res)); 1073 memset(&opendata->o_res, 0, sizeof(opendata->o_res));
1036 memset(&opendata->c_res, 0, sizeof(opendata->c_res)); 1074 memset(&opendata->c_res, 0, sizeof(opendata->c_res));
1037 nfs4_init_opendata_res(opendata); 1075 nfs4_init_opendata_res(opendata);
1038 ret = _nfs4_proc_open(opendata); 1076 ret = _nfs4_recover_proc_open(opendata);
1039 if (ret != 0) 1077 if (ret != 0)
1040 return ret; 1078 return ret;
1041 newstate = nfs4_opendata_to_nfs4_state(opendata); 1079 newstate = nfs4_opendata_to_nfs4_state(opendata);
@@ -1326,6 +1364,12 @@ out_no_action:
1326 1364
1327} 1365}
1328 1366
1367static void nfs4_recover_open_prepare(struct rpc_task *task, void *calldata)
1368{
1369 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
1370 nfs4_open_prepare(task, calldata);
1371}
1372
1329static void nfs4_open_done(struct rpc_task *task, void *calldata) 1373static void nfs4_open_done(struct rpc_task *task, void *calldata)
1330{ 1374{
1331 struct nfs4_opendata *data = calldata; 1375 struct nfs4_opendata *data = calldata;
@@ -1384,10 +1428,13 @@ static const struct rpc_call_ops nfs4_open_ops = {
1384 .rpc_release = nfs4_open_release, 1428 .rpc_release = nfs4_open_release,
1385}; 1429};
1386 1430
1387/* 1431static const struct rpc_call_ops nfs4_recover_open_ops = {
1388 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata 1432 .rpc_call_prepare = nfs4_recover_open_prepare,
1389 */ 1433 .rpc_call_done = nfs4_open_done,
1390static int _nfs4_proc_open(struct nfs4_opendata *data) 1434 .rpc_release = nfs4_open_release,
1435};
1436
1437static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1391{ 1438{
1392 struct inode *dir = data->dir->d_inode; 1439 struct inode *dir = data->dir->d_inode;
1393 struct nfs_server *server = NFS_SERVER(dir); 1440 struct nfs_server *server = NFS_SERVER(dir);
@@ -1414,21 +1461,57 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1414 data->rpc_done = 0; 1461 data->rpc_done = 0;
1415 data->rpc_status = 0; 1462 data->rpc_status = 0;
1416 data->cancelled = 0; 1463 data->cancelled = 0;
1464 if (isrecover)
1465 task_setup_data.callback_ops = &nfs4_recover_open_ops;
1417 task = rpc_run_task(&task_setup_data); 1466 task = rpc_run_task(&task_setup_data);
1418 if (IS_ERR(task)) 1467 if (IS_ERR(task))
1419 return PTR_ERR(task); 1468 return PTR_ERR(task);
1420 status = nfs4_wait_for_completion_rpc_task(task); 1469 status = nfs4_wait_for_completion_rpc_task(task);
1421 if (status != 0) { 1470 if (status != 0) {
1422 data->cancelled = 1; 1471 data->cancelled = 1;
1423 smp_wmb(); 1472 smp_wmb();
1424 } else 1473 } else
1425 status = data->rpc_status; 1474 status = data->rpc_status;
1426 rpc_put_task(task); 1475 rpc_put_task(task);
1476
1477 return status;
1478}
1479
1480static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1481{
1482 struct inode *dir = data->dir->d_inode;
1483 struct nfs_openres *o_res = &data->o_res;
1484 int status;
1485
1486 status = nfs4_run_open_task(data, 1);
1427 if (status != 0 || !data->rpc_done) 1487 if (status != 0 || !data->rpc_done)
1428 return status; 1488 return status;
1429 1489
1430 if (o_res->fh.size == 0) 1490 nfs_refresh_inode(dir, o_res->dir_attr);
1431 _nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr); 1491
1492 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
1493 status = _nfs4_proc_open_confirm(data);
1494 if (status != 0)
1495 return status;
1496 }
1497
1498 return status;
1499}
1500
1501/*
1502 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
1503 */
1504static int _nfs4_proc_open(struct nfs4_opendata *data)
1505{
1506 struct inode *dir = data->dir->d_inode;
1507 struct nfs_server *server = NFS_SERVER(dir);
1508 struct nfs_openargs *o_arg = &data->o_arg;
1509 struct nfs_openres *o_res = &data->o_res;
1510 int status;
1511
1512 status = nfs4_run_open_task(data, 0);
1513 if (status != 0 || !data->rpc_done)
1514 return status;
1432 1515
1433 if (o_arg->open_flags & O_CREAT) { 1516 if (o_arg->open_flags & O_CREAT) {
1434 update_changeattr(dir, &o_res->cinfo); 1517 update_changeattr(dir, &o_res->cinfo);
@@ -1752,11 +1835,10 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1752 if (calldata->arg.fmode == 0) 1835 if (calldata->arg.fmode == 0)
1753 break; 1836 break;
1754 default: 1837 default:
1755 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1838 if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
1756 nfs_restart_rpc(task, server->nfs_client); 1839 rpc_restart_call_prepare(task);
1757 return;
1758 }
1759 } 1840 }
1841 nfs_release_seqid(calldata->arg.seqid);
1760 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1842 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1761} 1843}
1762 1844
@@ -1848,8 +1930,6 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1848 calldata->state = state; 1930 calldata->state = state;
1849 calldata->arg.fh = NFS_FH(state->inode); 1931 calldata->arg.fh = NFS_FH(state->inode);
1850 calldata->arg.stateid = &state->open_stateid; 1932 calldata->arg.stateid = &state->open_stateid;
1851 if (nfs4_has_session(server->nfs_client))
1852 memset(calldata->arg.stateid->data, 0, 4); /* clear seqid */
1853 /* Serialization for the sequence id */ 1933 /* Serialization for the sequence id */
1854 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1934 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1855 if (calldata->arg.seqid == NULL) 1935 if (calldata->arg.seqid == NULL)
@@ -3941,6 +4021,12 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3941 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); 4021 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
3942} 4022}
3943 4023
4024static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
4025{
4026 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4027 nfs4_lock_prepare(task, calldata);
4028}
4029
3944static void nfs4_lock_done(struct rpc_task *task, void *calldata) 4030static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3945{ 4031{
3946 struct nfs4_lockdata *data = calldata; 4032 struct nfs4_lockdata *data = calldata;
@@ -3996,7 +4082,13 @@ static const struct rpc_call_ops nfs4_lock_ops = {
3996 .rpc_release = nfs4_lock_release, 4082 .rpc_release = nfs4_lock_release,
3997}; 4083};
3998 4084
3999static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim) 4085static const struct rpc_call_ops nfs4_recover_lock_ops = {
4086 .rpc_call_prepare = nfs4_recover_lock_prepare,
4087 .rpc_call_done = nfs4_lock_done,
4088 .rpc_release = nfs4_lock_release,
4089};
4090
4091static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
4000{ 4092{
4001 struct nfs4_lockdata *data; 4093 struct nfs4_lockdata *data;
4002 struct rpc_task *task; 4094 struct rpc_task *task;
@@ -4020,8 +4112,11 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4020 return -ENOMEM; 4112 return -ENOMEM;
4021 if (IS_SETLKW(cmd)) 4113 if (IS_SETLKW(cmd))
4022 data->arg.block = 1; 4114 data->arg.block = 1;
4023 if (reclaim != 0) 4115 if (recovery_type > NFS_LOCK_NEW) {
4024 data->arg.reclaim = 1; 4116 if (recovery_type == NFS_LOCK_RECLAIM)
4117 data->arg.reclaim = NFS_LOCK_RECLAIM;
4118 task_setup_data.callback_ops = &nfs4_recover_lock_ops;
4119 }
4025 msg.rpc_argp = &data->arg, 4120 msg.rpc_argp = &data->arg,
4026 msg.rpc_resp = &data->res, 4121 msg.rpc_resp = &data->res,
4027 task_setup_data.callback_data = data; 4122 task_setup_data.callback_data = data;
@@ -4048,7 +4143,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
4048 /* Cache the lock if possible... */ 4143 /* Cache the lock if possible... */
4049 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4144 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4050 return 0; 4145 return 0;
4051 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 4146 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
4052 if (err != -NFS4ERR_DELAY) 4147 if (err != -NFS4ERR_DELAY)
4053 break; 4148 break;
4054 nfs4_handle_exception(server, err, &exception); 4149 nfs4_handle_exception(server, err, &exception);
@@ -4068,7 +4163,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4068 do { 4163 do {
4069 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4164 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4070 return 0; 4165 return 0;
4071 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 4166 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
4072 switch (err) { 4167 switch (err) {
4073 default: 4168 default:
4074 goto out; 4169 goto out;
@@ -4104,7 +4199,7 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
4104 status = do_vfs_lock(request->fl_file, request); 4199 status = do_vfs_lock(request->fl_file, request);
4105 goto out_unlock; 4200 goto out_unlock;
4106 } 4201 }
4107 status = _nfs4_do_setlk(state, cmd, request, 0); 4202 status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
4108 if (status != 0) 4203 if (status != 0)
4109 goto out_unlock; 4204 goto out_unlock;
4110 /* Note: we always want to sleep here! */ 4205 /* Note: we always want to sleep here! */
@@ -4187,7 +4282,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4187 if (err != 0) 4282 if (err != 0)
4188 goto out; 4283 goto out;
4189 do { 4284 do {
4190 err = _nfs4_do_setlk(state, F_SETLK, fl, 0); 4285 err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
4191 switch (err) { 4286 switch (err) {
4192 default: 4287 default:
4193 printk(KERN_ERR "%s: unhandled error %d.\n", 4288 printk(KERN_ERR "%s: unhandled error %d.\n",
@@ -4395,11 +4490,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4395 (struct nfs4_get_lease_time_data *)calldata; 4490 (struct nfs4_get_lease_time_data *)calldata;
4396 4491
4397 dprintk("--> %s\n", __func__); 4492 dprintk("--> %s\n", __func__);
4493 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4398 /* just setup sequence, do not trigger session recovery 4494 /* just setup sequence, do not trigger session recovery
4399 since we're invoked within one */ 4495 since we're invoked within one */
4400 ret = nfs41_setup_sequence(data->clp->cl_session, 4496 ret = nfs41_setup_sequence(data->clp->cl_session,
4401 &data->args->la_seq_args, 4497 &data->args->la_seq_args,
4402 &data->res->lr_seq_res, 0, task); 4498 &data->res->lr_seq_res, 0, task);
4403 4499
4404 BUG_ON(ret == -EAGAIN); 4500 BUG_ON(ret == -EAGAIN);
4405 rpc_call_start(task); 4501 rpc_call_start(task);
@@ -4619,7 +4715,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4619 tbl = &session->fc_slot_table; 4715 tbl = &session->fc_slot_table;
4620 tbl->highest_used_slotid = -1; 4716 tbl->highest_used_slotid = -1;
4621 spin_lock_init(&tbl->slot_tbl_lock); 4717 spin_lock_init(&tbl->slot_tbl_lock);
4622 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4718 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4623 4719
4624 tbl = &session->bc_slot_table; 4720 tbl = &session->bc_slot_table;
4625 tbl->highest_used_slotid = -1; 4721 tbl->highest_used_slotid = -1;
@@ -4838,14 +4934,22 @@ int nfs4_init_session(struct nfs_server *server)
4838{ 4934{
4839 struct nfs_client *clp = server->nfs_client; 4935 struct nfs_client *clp = server->nfs_client;
4840 struct nfs4_session *session; 4936 struct nfs4_session *session;
4937 unsigned int rsize, wsize;
4841 int ret; 4938 int ret;
4842 4939
4843 if (!nfs4_has_session(clp)) 4940 if (!nfs4_has_session(clp))
4844 return 0; 4941 return 0;
4845 4942
4943 rsize = server->rsize;
4944 if (rsize == 0)
4945 rsize = NFS_MAX_FILE_IO_SIZE;
4946 wsize = server->wsize;
4947 if (wsize == 0)
4948 wsize = NFS_MAX_FILE_IO_SIZE;
4949
4846 session = clp->cl_session; 4950 session = clp->cl_session;
4847 session->fc_attrs.max_rqst_sz = server->wsize + nfs41_maxwrite_overhead; 4951 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
4848 session->fc_attrs.max_resp_sz = server->rsize + nfs41_maxread_overhead; 4952 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
4849 4953
4850 ret = nfs4_recover_expired_lease(server); 4954 ret = nfs4_recover_expired_lease(server);
4851 if (!ret) 4955 if (!ret)
@@ -4871,7 +4975,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
4871 args.sa_cache_this = 0; 4975 args.sa_cache_this = 0;
4872 4976
4873 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args, 4977 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
4874 &res, 0); 4978 &res, args.sa_cache_this, 1);
4875} 4979}
4876 4980
4877void nfs41_sequence_call_done(struct rpc_task *task, void *data) 4981void nfs41_sequence_call_done(struct rpc_task *task, void *data)
@@ -4953,6 +5057,7 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
4953{ 5057{
4954 struct nfs4_reclaim_complete_data *calldata = data; 5058 struct nfs4_reclaim_complete_data *calldata = data;
4955 5059
5060 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4956 if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args, 5061 if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args,
4957 &calldata->res.seq_res, 0, task)) 5062 &calldata->res.seq_res, 0, task))
4958 return; 5063 return;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e76427e6346f..6d263ed79e92 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -135,16 +135,30 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
135 return status; 135 return status;
136} 136}
137 137
138static void nfs41_end_drain_session(struct nfs_client *clp, 138static void nfs4_end_drain_session(struct nfs_client *clp)
139 struct nfs4_session *ses)
140{ 139{
141 if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) 140 struct nfs4_session *ses = clp->cl_session;
142 rpc_wake_up(&ses->fc_slot_table.slot_tbl_waitq); 141 int max_slots;
142
143 if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) {
144 spin_lock(&ses->fc_slot_table.slot_tbl_lock);
145 max_slots = ses->fc_slot_table.max_slots;
146 while (max_slots--) {
147 struct rpc_task *task;
148
149 task = rpc_wake_up_next(&ses->fc_slot_table.
150 slot_tbl_waitq);
151 if (!task)
152 break;
153 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
154 }
155 spin_unlock(&ses->fc_slot_table.slot_tbl_lock);
156 }
143} 157}
144 158
145static int nfs41_begin_drain_session(struct nfs_client *clp, 159static int nfs4_begin_drain_session(struct nfs_client *clp)
146 struct nfs4_session *ses)
147{ 160{
161 struct nfs4_session *ses = clp->cl_session;
148 struct nfs4_slot_table *tbl = &ses->fc_slot_table; 162 struct nfs4_slot_table *tbl = &ses->fc_slot_table;
149 163
150 spin_lock(&tbl->slot_tbl_lock); 164 spin_lock(&tbl->slot_tbl_lock);
@@ -162,16 +176,13 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
162{ 176{
163 int status; 177 int status;
164 178
165 status = nfs41_begin_drain_session(clp, clp->cl_session); 179 nfs4_begin_drain_session(clp);
166 if (status != 0)
167 goto out;
168 status = nfs4_proc_exchange_id(clp, cred); 180 status = nfs4_proc_exchange_id(clp, cred);
169 if (status != 0) 181 if (status != 0)
170 goto out; 182 goto out;
171 status = nfs4_proc_create_session(clp); 183 status = nfs4_proc_create_session(clp);
172 if (status != 0) 184 if (status != 0)
173 goto out; 185 goto out;
174 nfs41_end_drain_session(clp, clp->cl_session);
175 nfs41_setup_state_renewal(clp); 186 nfs41_setup_state_renewal(clp);
176 nfs_mark_client_ready(clp, NFS_CS_READY); 187 nfs_mark_client_ready(clp, NFS_CS_READY);
177out: 188out:
@@ -755,16 +766,21 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
755 return new; 766 return new;
756} 767}
757 768
758void nfs_free_seqid(struct nfs_seqid *seqid) 769void nfs_release_seqid(struct nfs_seqid *seqid)
759{ 770{
760 if (!list_empty(&seqid->list)) { 771 if (!list_empty(&seqid->list)) {
761 struct rpc_sequence *sequence = seqid->sequence->sequence; 772 struct rpc_sequence *sequence = seqid->sequence->sequence;
762 773
763 spin_lock(&sequence->lock); 774 spin_lock(&sequence->lock);
764 list_del(&seqid->list); 775 list_del_init(&seqid->list);
765 spin_unlock(&sequence->lock); 776 spin_unlock(&sequence->lock);
766 rpc_wake_up(&sequence->wait); 777 rpc_wake_up(&sequence->wait);
767 } 778 }
779}
780
781void nfs_free_seqid(struct nfs_seqid *seqid)
782{
783 nfs_release_seqid(seqid);
768 kfree(seqid); 784 kfree(seqid);
769} 785}
770 786
@@ -1257,13 +1273,9 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
1257 1273
1258static int nfs4_reset_session(struct nfs_client *clp) 1274static int nfs4_reset_session(struct nfs_client *clp)
1259{ 1275{
1260 struct nfs4_session *ses = clp->cl_session;
1261 int status; 1276 int status;
1262 1277
1263 status = nfs41_begin_drain_session(clp, ses); 1278 nfs4_begin_drain_session(clp);
1264 if (status != 0)
1265 return status;
1266
1267 status = nfs4_proc_destroy_session(clp->cl_session); 1279 status = nfs4_proc_destroy_session(clp->cl_session);
1268 if (status && status != -NFS4ERR_BADSESSION && 1280 if (status && status != -NFS4ERR_BADSESSION &&
1269 status != -NFS4ERR_DEADSESSION) { 1281 status != -NFS4ERR_DEADSESSION) {
@@ -1279,19 +1291,17 @@ static int nfs4_reset_session(struct nfs_client *clp)
1279out: 1291out:
1280 /* 1292 /*
1281 * Let the state manager reestablish state 1293 * Let the state manager reestablish state
1282 * without waking other tasks yet.
1283 */ 1294 */
1284 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1295 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1285 /* Wake up the next rpc task */ 1296 status == 0)
1286 nfs41_end_drain_session(clp, ses); 1297 nfs41_setup_state_renewal(clp);
1287 if (status == 0) 1298
1288 nfs41_setup_state_renewal(clp);
1289 }
1290 return status; 1299 return status;
1291} 1300}
1292 1301
1293#else /* CONFIG_NFS_V4_1 */ 1302#else /* CONFIG_NFS_V4_1 */
1294static int nfs4_reset_session(struct nfs_client *clp) { return 0; } 1303static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1304static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
1295#endif /* CONFIG_NFS_V4_1 */ 1305#endif /* CONFIG_NFS_V4_1 */
1296 1306
1297/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors 1307/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
@@ -1382,6 +1392,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1382 goto out_error; 1392 goto out_error;
1383 } 1393 }
1384 1394
1395 nfs4_end_drain_session(clp);
1385 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { 1396 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
1386 nfs_client_return_marked_delegations(clp); 1397 nfs_client_return_marked_delegations(clp);
1387 continue; 1398 continue;
@@ -1398,6 +1409,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1398out_error: 1409out_error:
1399 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" 1410 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
1400 " with error %d\n", clp->cl_hostname, -status); 1411 " with error %d\n", clp->cl_hostname, -status);
1412 nfs4_end_drain_session(clp);
1401 nfs4_clear_state_manager_bit(clp); 1413 nfs4_clear_state_manager_bit(clp);
1402} 1414}
1403 1415
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index ce907efc5508..d5b112bcf3de 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2648,21 +2648,13 @@ out_freepage:
2648static int nfs_follow_remote_path(struct vfsmount *root_mnt, 2648static int nfs_follow_remote_path(struct vfsmount *root_mnt,
2649 const char *export_path, struct vfsmount *mnt_target) 2649 const char *export_path, struct vfsmount *mnt_target)
2650{ 2650{
2651 struct mnt_namespace *ns_private;
2652 struct nameidata nd; 2651 struct nameidata nd;
2653 struct super_block *s; 2652 struct super_block *s;
2654 int ret; 2653 int ret;
2655 2654
2656 ns_private = create_mnt_ns(root_mnt);
2657 ret = PTR_ERR(ns_private);
2658 if (IS_ERR(ns_private))
2659 goto out_mntput;
2660
2661 ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, 2655 ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
2662 export_path, LOOKUP_FOLLOW, &nd); 2656 export_path, LOOKUP_FOLLOW, &nd);
2663 2657
2664 put_mnt_ns(ns_private);
2665
2666 if (ret != 0) 2658 if (ret != 0)
2667 goto out_err; 2659 goto out_err;
2668 2660