diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 203 |
1 files changed, 154 insertions, 49 deletions
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 | ||
65 | struct nfs4_opendata; | 65 | struct nfs4_opendata; |
66 | static int _nfs4_proc_open(struct nfs4_opendata *data); | 66 | static int _nfs4_proc_open(struct nfs4_opendata *data); |
67 | static int _nfs4_recover_proc_open(struct nfs4_opendata *data); | ||
67 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); | 68 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); |
68 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); | 69 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); |
69 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 70 | static 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 | */ | ||
348 | static 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 | |||
344 | static void nfs41_sequence_free_slot(const struct nfs_client *clp, | 366 | static 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 | */ |
423 | static u8 | 437 | static u8 |
424 | nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) | 438 | nfs4_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 | ||
572 | static 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 | |||
548 | static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) | 578 | static 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 | ||
590 | struct 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 | |||
560 | static int nfs4_call_sync_sequence(struct nfs_client *clp, | 595 | static 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 | ||
1367 | static 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 | |||
1329 | static void nfs4_open_done(struct rpc_task *task, void *calldata) | 1373 | static 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 | /* | 1431 | static 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, |
1390 | static int _nfs4_proc_open(struct nfs4_opendata *data) | 1434 | .rpc_release = nfs4_open_release, |
1435 | }; | ||
1436 | |||
1437 | static 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 | |||
1480 | static 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 | */ | ||
1504 | static 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 | ||
4024 | static 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 | |||
3944 | static void nfs4_lock_done(struct rpc_task *task, void *calldata) | 4030 | static 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 | ||
3999 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim) | 4085 | static 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 | |||
4091 | static 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 | ||
4877 | void nfs41_sequence_call_done(struct rpc_task *task, void *data) | 4981 | void 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; |