aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c279
1 files changed, 102 insertions, 177 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 089da5b5d20a..e87fe612ca18 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -129,7 +129,7 @@ const u32 nfs4_fsinfo_bitmap[2] = { FATTR4_WORD0_MAXFILESIZE
129 | FATTR4_WORD0_MAXREAD 129 | FATTR4_WORD0_MAXREAD
130 | FATTR4_WORD0_MAXWRITE 130 | FATTR4_WORD0_MAXWRITE
131 | FATTR4_WORD0_LEASE_TIME, 131 | FATTR4_WORD0_LEASE_TIME,
132 0 132 FATTR4_WORD1_TIME_DELTA
133}; 133};
134 134
135const u32 nfs4_fs_locations_bitmap[2] = { 135const u32 nfs4_fs_locations_bitmap[2] = {
@@ -255,9 +255,6 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
255 nfs4_state_mark_reclaim_nograce(clp, state); 255 nfs4_state_mark_reclaim_nograce(clp, state);
256 goto do_state_recovery; 256 goto do_state_recovery;
257 case -NFS4ERR_STALE_STATEID: 257 case -NFS4ERR_STALE_STATEID:
258 if (state == NULL)
259 break;
260 nfs4_state_mark_reclaim_reboot(clp, state);
261 case -NFS4ERR_STALE_CLIENTID: 258 case -NFS4ERR_STALE_CLIENTID:
262 case -NFS4ERR_EXPIRED: 259 case -NFS4ERR_EXPIRED:
263 goto do_state_recovery; 260 goto do_state_recovery;
@@ -334,10 +331,12 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
334 * Must be called while holding tbl->slot_tbl_lock 331 * Must be called while holding tbl->slot_tbl_lock
335 */ 332 */
336static void 333static void
337nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) 334nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *free_slot)
338{ 335{
336 int free_slotid = free_slot - tbl->slots;
339 int slotid = free_slotid; 337 int slotid = free_slotid;
340 338
339 BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE);
341 /* clear used bit in bitmap */ 340 /* clear used bit in bitmap */
342 __clear_bit(slotid, tbl->used_slots); 341 __clear_bit(slotid, tbl->used_slots);
343 342
@@ -379,7 +378,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
379 struct nfs4_slot_table *tbl; 378 struct nfs4_slot_table *tbl;
380 379
381 tbl = &res->sr_session->fc_slot_table; 380 tbl = &res->sr_session->fc_slot_table;
382 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { 381 if (!res->sr_slot) {
383 /* just wake up the next guy waiting since 382 /* just wake up the next guy waiting since
384 * we may have not consumed a slot after all */ 383 * we may have not consumed a slot after all */
385 dprintk("%s: No slot\n", __func__); 384 dprintk("%s: No slot\n", __func__);
@@ -387,17 +386,15 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
387 } 386 }
388 387
389 spin_lock(&tbl->slot_tbl_lock); 388 spin_lock(&tbl->slot_tbl_lock);
390 nfs4_free_slot(tbl, res->sr_slotid); 389 nfs4_free_slot(tbl, res->sr_slot);
391 nfs41_check_drain_session_complete(res->sr_session); 390 nfs41_check_drain_session_complete(res->sr_session);
392 spin_unlock(&tbl->slot_tbl_lock); 391 spin_unlock(&tbl->slot_tbl_lock);
393 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 392 res->sr_slot = NULL;
394} 393}
395 394
396static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 395static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
397{ 396{
398 unsigned long timestamp; 397 unsigned long timestamp;
399 struct nfs4_slot_table *tbl;
400 struct nfs4_slot *slot;
401 struct nfs_client *clp; 398 struct nfs_client *clp;
402 399
403 /* 400 /*
@@ -410,17 +407,14 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
410 res->sr_status = NFS_OK; 407 res->sr_status = NFS_OK;
411 408
412 /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */ 409 /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */
413 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) 410 if (!res->sr_slot)
414 goto out; 411 goto out;
415 412
416 tbl = &res->sr_session->fc_slot_table;
417 slot = tbl->slots + res->sr_slotid;
418
419 /* Check the SEQUENCE operation status */ 413 /* Check the SEQUENCE operation status */
420 switch (res->sr_status) { 414 switch (res->sr_status) {
421 case 0: 415 case 0:
422 /* Update the slot's sequence and clientid lease timer */ 416 /* Update the slot's sequence and clientid lease timer */
423 ++slot->seq_nr; 417 ++res->sr_slot->seq_nr;
424 timestamp = res->sr_renewal_time; 418 timestamp = res->sr_renewal_time;
425 clp = res->sr_session->clp; 419 clp = res->sr_session->clp;
426 do_renew_lease(clp, timestamp); 420 do_renew_lease(clp, timestamp);
@@ -433,12 +427,14 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
433 * returned NFS4ERR_DELAY as per Section 2.10.6.2 427 * returned NFS4ERR_DELAY as per Section 2.10.6.2
434 * of RFC5661. 428 * of RFC5661.
435 */ 429 */
436 dprintk("%s: slot=%d seq=%d: Operation in progress\n", 430 dprintk("%s: slot=%ld seq=%d: Operation in progress\n",
437 __func__, res->sr_slotid, slot->seq_nr); 431 __func__,
432 res->sr_slot - res->sr_session->fc_slot_table.slots,
433 res->sr_slot->seq_nr);
438 goto out_retry; 434 goto out_retry;
439 default: 435 default:
440 /* Just update the slot sequence no. */ 436 /* Just update the slot sequence no. */
441 ++slot->seq_nr; 437 ++res->sr_slot->seq_nr;
442 } 438 }
443out: 439out:
444 /* The session may be reset by one of the error handlers. */ 440 /* The session may be reset by one of the error handlers. */
@@ -505,10 +501,9 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
505 501
506 dprintk("--> %s\n", __func__); 502 dprintk("--> %s\n", __func__);
507 /* slot already allocated? */ 503 /* slot already allocated? */
508 if (res->sr_slotid != NFS4_MAX_SLOT_TABLE) 504 if (res->sr_slot != NULL)
509 return 0; 505 return 0;
510 506
511 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
512 tbl = &session->fc_slot_table; 507 tbl = &session->fc_slot_table;
513 508
514 spin_lock(&tbl->slot_tbl_lock); 509 spin_lock(&tbl->slot_tbl_lock);
@@ -550,7 +545,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
550 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr); 545 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
551 546
552 res->sr_session = session; 547 res->sr_session = session;
553 res->sr_slotid = slotid; 548 res->sr_slot = slot;
554 res->sr_renewal_time = jiffies; 549 res->sr_renewal_time = jiffies;
555 res->sr_status_flags = 0; 550 res->sr_status_flags = 0;
556 /* 551 /*
@@ -576,8 +571,9 @@ int nfs4_setup_sequence(const struct nfs_server *server,
576 goto out; 571 goto out;
577 } 572 }
578 573
579 dprintk("--> %s clp %p session %p sr_slotid %d\n", 574 dprintk("--> %s clp %p session %p sr_slot %ld\n",
580 __func__, session->clp, session, res->sr_slotid); 575 __func__, session->clp, session, res->sr_slot ?
576 res->sr_slot - session->fc_slot_table.slots : -1);
581 577
582 ret = nfs41_setup_sequence(session, args, res, cache_reply, 578 ret = nfs41_setup_sequence(session, args, res, cache_reply,
583 task); 579 task);
@@ -650,7 +646,7 @@ static int nfs4_call_sync_sequence(struct nfs_server *server,
650 .callback_data = &data 646 .callback_data = &data
651 }; 647 };
652 648
653 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 649 res->sr_slot = NULL;
654 if (privileged) 650 if (privileged)
655 task_setup.callback_ops = &nfs41_call_priv_sync_ops; 651 task_setup.callback_ops = &nfs41_call_priv_sync_ops;
656 task = rpc_run_task(&task_setup); 652 task = rpc_run_task(&task_setup);
@@ -735,7 +731,6 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
735 p->o_res.server = p->o_arg.server; 731 p->o_res.server = p->o_arg.server;
736 nfs_fattr_init(&p->f_attr); 732 nfs_fattr_init(&p->f_attr);
737 nfs_fattr_init(&p->dir_attr); 733 nfs_fattr_init(&p->dir_attr);
738 p->o_res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
739} 734}
740 735
741static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, 736static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
@@ -1120,6 +1115,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1120 clear_bit(NFS_DELEGATED_STATE, &state->flags); 1115 clear_bit(NFS_DELEGATED_STATE, &state->flags);
1121 smp_rmb(); 1116 smp_rmb();
1122 if (state->n_rdwr != 0) { 1117 if (state->n_rdwr != 0) {
1118 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1123 ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate); 1119 ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate);
1124 if (ret != 0) 1120 if (ret != 0)
1125 return ret; 1121 return ret;
@@ -1127,6 +1123,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1127 return -ESTALE; 1123 return -ESTALE;
1128 } 1124 }
1129 if (state->n_wronly != 0) { 1125 if (state->n_wronly != 0) {
1126 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1130 ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate); 1127 ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate);
1131 if (ret != 0) 1128 if (ret != 0)
1132 return ret; 1129 return ret;
@@ -1134,6 +1131,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1134 return -ESTALE; 1131 return -ESTALE;
1135 } 1132 }
1136 if (state->n_rdonly != 0) { 1133 if (state->n_rdonly != 0) {
1134 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1137 ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate); 1135 ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate);
1138 if (ret != 0) 1136 if (ret != 0)
1139 return ret; 1137 return ret;
@@ -1188,7 +1186,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1188 int err; 1186 int err;
1189 do { 1187 do {
1190 err = _nfs4_do_open_reclaim(ctx, state); 1188 err = _nfs4_do_open_reclaim(ctx, state);
1191 if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED) 1189 if (err != -NFS4ERR_DELAY)
1192 break; 1190 break;
1193 nfs4_handle_exception(server, err, &exception); 1191 nfs4_handle_exception(server, err, &exception);
1194 } while (exception.retry); 1192 } while (exception.retry);
@@ -1258,6 +1256,13 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1258 case -NFS4ERR_ADMIN_REVOKED: 1256 case -NFS4ERR_ADMIN_REVOKED:
1259 case -NFS4ERR_BAD_STATEID: 1257 case -NFS4ERR_BAD_STATEID:
1260 nfs4_state_mark_reclaim_nograce(server->nfs_client, state); 1258 nfs4_state_mark_reclaim_nograce(server->nfs_client, state);
1259 case -EKEYEXPIRED:
1260 /*
1261 * User RPCSEC_GSS context has expired.
1262 * We cannot recover this stateid now, so
1263 * skip it and allow recovery thread to
1264 * proceed.
1265 */
1261 case -ENOMEM: 1266 case -ENOMEM:
1262 err = 0; 1267 err = 0;
1263 goto out; 1268 goto out;
@@ -1605,7 +1610,6 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state
1605 goto out; 1610 goto out;
1606 case -NFS4ERR_GRACE: 1611 case -NFS4ERR_GRACE:
1607 case -NFS4ERR_DELAY: 1612 case -NFS4ERR_DELAY:
1608 case -EKEYEXPIRED:
1609 nfs4_handle_exception(server, err, &exception); 1613 nfs4_handle_exception(server, err, &exception);
1610 err = 0; 1614 err = 0;
1611 } 1615 }
@@ -1975,7 +1979,6 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
1975 calldata->res.fattr = &calldata->fattr; 1979 calldata->res.fattr = &calldata->fattr;
1976 calldata->res.seqid = calldata->arg.seqid; 1980 calldata->res.seqid = calldata->arg.seqid;
1977 calldata->res.server = server; 1981 calldata->res.server = server;
1978 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
1979 path_get(path); 1982 path_get(path);
1980 calldata->path = *path; 1983 calldata->path = *path;
1981 1984
@@ -1998,120 +2001,17 @@ out:
1998 return status; 2001 return status;
1999} 2002}
2000 2003
2001static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state, fmode_t fmode) 2004static struct inode *
2002{ 2005nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr)
2003 struct file *filp;
2004 int ret;
2005
2006 /* If the open_intent is for execute, we have an extra check to make */
2007 if (fmode & FMODE_EXEC) {
2008 ret = nfs_may_open(state->inode,
2009 state->owner->so_cred,
2010 nd->intent.open.flags);
2011 if (ret < 0)
2012 goto out_close;
2013 }
2014 filp = lookup_instantiate_filp(nd, path->dentry, NULL);
2015 if (!IS_ERR(filp)) {
2016 struct nfs_open_context *ctx;
2017 ctx = nfs_file_open_context(filp);
2018 ctx->state = state;
2019 return 0;
2020 }
2021 ret = PTR_ERR(filp);
2022out_close:
2023 nfs4_close_sync(path, state, fmode & (FMODE_READ|FMODE_WRITE));
2024 return ret;
2025}
2026
2027struct dentry *
2028nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
2029{ 2006{
2030 struct path path = {
2031 .mnt = nd->path.mnt,
2032 .dentry = dentry,
2033 };
2034 struct dentry *parent;
2035 struct iattr attr;
2036 struct rpc_cred *cred;
2037 struct nfs4_state *state; 2007 struct nfs4_state *state;
2038 struct dentry *res;
2039 int open_flags = nd->intent.open.flags;
2040 fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
2041
2042 if (nd->flags & LOOKUP_CREATE) {
2043 attr.ia_mode = nd->intent.open.create_mode;
2044 attr.ia_valid = ATTR_MODE;
2045 if (!IS_POSIXACL(dir))
2046 attr.ia_mode &= ~current_umask();
2047 } else {
2048 open_flags &= ~O_EXCL;
2049 attr.ia_valid = 0;
2050 BUG_ON(open_flags & O_CREAT);
2051 }
2052 2008
2053 cred = rpc_lookup_cred();
2054 if (IS_ERR(cred))
2055 return (struct dentry *)cred;
2056 parent = dentry->d_parent;
2057 /* Protect against concurrent sillydeletes */ 2009 /* Protect against concurrent sillydeletes */
2058 nfs_block_sillyrename(parent); 2010 state = nfs4_do_open(dir, &ctx->path, ctx->mode, open_flags, attr, ctx->cred);
2059 state = nfs4_do_open(dir, &path, fmode, open_flags, &attr, cred); 2011 if (IS_ERR(state))
2060 put_rpccred(cred); 2012 return ERR_CAST(state);
2061 if (IS_ERR(state)) { 2013 ctx->state = state;
2062 if (PTR_ERR(state) == -ENOENT) { 2014 return igrab(state->inode);
2063 d_add(dentry, NULL);
2064 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
2065 }
2066 nfs_unblock_sillyrename(parent);
2067 return (struct dentry *)state;
2068 }
2069 res = d_add_unique(dentry, igrab(state->inode));
2070 if (res != NULL)
2071 path.dentry = res;
2072 nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
2073 nfs_unblock_sillyrename(parent);
2074 nfs4_intent_set_file(nd, &path, state, fmode);
2075 return res;
2076}
2077
2078int
2079nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
2080{
2081 struct path path = {
2082 .mnt = nd->path.mnt,
2083 .dentry = dentry,
2084 };
2085 struct rpc_cred *cred;
2086 struct nfs4_state *state;
2087 fmode_t fmode = openflags & (FMODE_READ | FMODE_WRITE);
2088
2089 cred = rpc_lookup_cred();
2090 if (IS_ERR(cred))
2091 return PTR_ERR(cred);
2092 state = nfs4_do_open(dir, &path, fmode, openflags, NULL, cred);
2093 put_rpccred(cred);
2094 if (IS_ERR(state)) {
2095 switch (PTR_ERR(state)) {
2096 case -EPERM:
2097 case -EACCES:
2098 case -EDQUOT:
2099 case -ENOSPC:
2100 case -EROFS:
2101 return PTR_ERR(state);
2102 default:
2103 goto out_drop;
2104 }
2105 }
2106 if (state->inode == dentry->d_inode) {
2107 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
2108 nfs4_intent_set_file(nd, &path, state, fmode);
2109 return 1;
2110 }
2111 nfs4_close_sync(&path, state, fmode);
2112out_drop:
2113 d_drop(dentry);
2114 return 0;
2115} 2015}
2116 2016
2117static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) 2017static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
@@ -2568,36 +2468,34 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
2568 2468
2569static int 2469static int
2570nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 2470nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2571 int flags, struct nameidata *nd) 2471 int flags, struct nfs_open_context *ctx)
2572{ 2472{
2573 struct path path = { 2473 struct path my_path = {
2574 .mnt = nd->path.mnt,
2575 .dentry = dentry, 2474 .dentry = dentry,
2576 }; 2475 };
2476 struct path *path = &my_path;
2577 struct nfs4_state *state; 2477 struct nfs4_state *state;
2578 struct rpc_cred *cred; 2478 struct rpc_cred *cred = NULL;
2579 fmode_t fmode = flags & (FMODE_READ | FMODE_WRITE); 2479 fmode_t fmode = 0;
2580 int status = 0; 2480 int status = 0;
2581 2481
2582 cred = rpc_lookup_cred(); 2482 if (ctx != NULL) {
2583 if (IS_ERR(cred)) { 2483 cred = ctx->cred;
2584 status = PTR_ERR(cred); 2484 path = &ctx->path;
2585 goto out; 2485 fmode = ctx->mode;
2586 } 2486 }
2587 state = nfs4_do_open(dir, &path, fmode, flags, sattr, cred); 2487 state = nfs4_do_open(dir, path, fmode, flags, sattr, cred);
2588 d_drop(dentry); 2488 d_drop(dentry);
2589 if (IS_ERR(state)) { 2489 if (IS_ERR(state)) {
2590 status = PTR_ERR(state); 2490 status = PTR_ERR(state);
2591 goto out_putcred; 2491 goto out;
2592 } 2492 }
2593 d_add(dentry, igrab(state->inode)); 2493 d_add(dentry, igrab(state->inode));
2594 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 2494 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
2595 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) 2495 if (ctx != NULL)
2596 status = nfs4_intent_set_file(nd, &path, state, fmode); 2496 ctx->state = state;
2597 else 2497 else
2598 nfs4_close_sync(&path, state, fmode); 2498 nfs4_close_sync(path, state, fmode);
2599out_putcred:
2600 put_rpccred(cred);
2601out: 2499out:
2602 return status; 2500 return status;
2603} 2501}
@@ -2655,6 +2553,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
2655 2553
2656 args->bitmask = server->cache_consistency_bitmask; 2554 args->bitmask = server->cache_consistency_bitmask;
2657 res->server = server; 2555 res->server = server;
2556 res->seq_res.sr_slot = NULL;
2658 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; 2557 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
2659} 2558}
2660 2559
@@ -2671,18 +2570,46 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2671 return 1; 2570 return 1;
2672} 2571}
2673 2572
2573static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
2574{
2575 struct nfs_server *server = NFS_SERVER(dir);
2576 struct nfs_renameargs *arg = msg->rpc_argp;
2577 struct nfs_renameres *res = msg->rpc_resp;
2578
2579 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
2580 arg->bitmask = server->attr_bitmask;
2581 res->server = server;
2582}
2583
2584static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
2585 struct inode *new_dir)
2586{
2587 struct nfs_renameres *res = task->tk_msg.rpc_resp;
2588
2589 if (!nfs4_sequence_done(task, &res->seq_res))
2590 return 0;
2591 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2592 return 0;
2593
2594 update_changeattr(old_dir, &res->old_cinfo);
2595 nfs_post_op_update_inode(old_dir, res->old_fattr);
2596 update_changeattr(new_dir, &res->new_cinfo);
2597 nfs_post_op_update_inode(new_dir, res->new_fattr);
2598 return 1;
2599}
2600
2674static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, 2601static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2675 struct inode *new_dir, struct qstr *new_name) 2602 struct inode *new_dir, struct qstr *new_name)
2676{ 2603{
2677 struct nfs_server *server = NFS_SERVER(old_dir); 2604 struct nfs_server *server = NFS_SERVER(old_dir);
2678 struct nfs4_rename_arg arg = { 2605 struct nfs_renameargs arg = {
2679 .old_dir = NFS_FH(old_dir), 2606 .old_dir = NFS_FH(old_dir),
2680 .new_dir = NFS_FH(new_dir), 2607 .new_dir = NFS_FH(new_dir),
2681 .old_name = old_name, 2608 .old_name = old_name,
2682 .new_name = new_name, 2609 .new_name = new_name,
2683 .bitmask = server->attr_bitmask, 2610 .bitmask = server->attr_bitmask,
2684 }; 2611 };
2685 struct nfs4_rename_res res = { 2612 struct nfs_renameres res = {
2686 .server = server, 2613 .server = server,
2687 }; 2614 };
2688 struct rpc_message msg = { 2615 struct rpc_message msg = {
@@ -2896,15 +2823,16 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
2896} 2823}
2897 2824
2898static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, 2825static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2899 u64 cookie, struct page *page, unsigned int count, int plus) 2826 u64 cookie, struct page **pages, unsigned int count, int plus)
2900{ 2827{
2901 struct inode *dir = dentry->d_inode; 2828 struct inode *dir = dentry->d_inode;
2902 struct nfs4_readdir_arg args = { 2829 struct nfs4_readdir_arg args = {
2903 .fh = NFS_FH(dir), 2830 .fh = NFS_FH(dir),
2904 .pages = &page, 2831 .pages = pages,
2905 .pgbase = 0, 2832 .pgbase = 0,
2906 .count = count, 2833 .count = count,
2907 .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask, 2834 .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
2835 .plus = plus,
2908 }; 2836 };
2909 struct nfs4_readdir_res res; 2837 struct nfs4_readdir_res res;
2910 struct rpc_message msg = { 2838 struct rpc_message msg = {
@@ -2932,14 +2860,14 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2932} 2860}
2933 2861
2934static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, 2862static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2935 u64 cookie, struct page *page, unsigned int count, int plus) 2863 u64 cookie, struct page **pages, unsigned int count, int plus)
2936{ 2864{
2937 struct nfs4_exception exception = { }; 2865 struct nfs4_exception exception = { };
2938 int err; 2866 int err;
2939 do { 2867 do {
2940 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), 2868 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
2941 _nfs4_proc_readdir(dentry, cred, cookie, 2869 _nfs4_proc_readdir(dentry, cred, cookie,
2942 page, count, plus), 2870 pages, count, plus),
2943 &exception); 2871 &exception);
2944 } while (exception.retry); 2872 } while (exception.retry);
2945 return err; 2873 return err;
@@ -3490,9 +3418,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3490 nfs4_state_mark_reclaim_nograce(clp, state); 3418 nfs4_state_mark_reclaim_nograce(clp, state);
3491 goto do_state_recovery; 3419 goto do_state_recovery;
3492 case -NFS4ERR_STALE_STATEID: 3420 case -NFS4ERR_STALE_STATEID:
3493 if (state == NULL)
3494 break;
3495 nfs4_state_mark_reclaim_reboot(clp, state);
3496 case -NFS4ERR_STALE_CLIENTID: 3421 case -NFS4ERR_STALE_CLIENTID:
3497 case -NFS4ERR_EXPIRED: 3422 case -NFS4ERR_EXPIRED:
3498 goto do_state_recovery; 3423 goto do_state_recovery;
@@ -3626,7 +3551,6 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
3626 case -NFS4ERR_RESOURCE: 3551 case -NFS4ERR_RESOURCE:
3627 /* The IBM lawyers misread another document! */ 3552 /* The IBM lawyers misread another document! */
3628 case -NFS4ERR_DELAY: 3553 case -NFS4ERR_DELAY:
3629 case -EKEYEXPIRED:
3630 err = nfs4_delay(clp->cl_rpcclient, &timeout); 3554 err = nfs4_delay(clp->cl_rpcclient, &timeout);
3631 } 3555 }
3632 } while (err == 0); 3556 } while (err == 0);
@@ -3721,7 +3645,6 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3721 memcpy(&data->stateid, stateid, sizeof(data->stateid)); 3645 memcpy(&data->stateid, stateid, sizeof(data->stateid));
3722 data->res.fattr = &data->fattr; 3646 data->res.fattr = &data->fattr;
3723 data->res.server = server; 3647 data->res.server = server;
3724 data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3725 nfs_fattr_init(data->res.fattr); 3648 nfs_fattr_init(data->res.fattr);
3726 data->timestamp = jiffies; 3649 data->timestamp = jiffies;
3727 data->rpc_status = 0; 3650 data->rpc_status = 0;
@@ -3874,7 +3797,6 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
3874 p->arg.fl = &p->fl; 3797 p->arg.fl = &p->fl;
3875 p->arg.seqid = seqid; 3798 p->arg.seqid = seqid;
3876 p->res.seqid = seqid; 3799 p->res.seqid = seqid;
3877 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3878 p->arg.stateid = &lsp->ls_stateid; 3800 p->arg.stateid = &lsp->ls_stateid;
3879 p->lsp = lsp; 3801 p->lsp = lsp;
3880 atomic_inc(&lsp->ls_count); 3802 atomic_inc(&lsp->ls_count);
@@ -4054,7 +3976,6 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
4054 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; 3976 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
4055 p->arg.lock_owner.id = lsp->ls_id.id; 3977 p->arg.lock_owner.id = lsp->ls_id.id;
4056 p->res.lock_seqid = p->arg.lock_seqid; 3978 p->res.lock_seqid = p->arg.lock_seqid;
4057 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
4058 p->lsp = lsp; 3979 p->lsp = lsp;
4059 p->server = server; 3980 p->server = server;
4060 atomic_inc(&lsp->ls_count); 3981 atomic_inc(&lsp->ls_count);
@@ -4241,7 +4162,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
4241 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4162 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4242 return 0; 4163 return 0;
4243 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); 4164 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
4244 if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED) 4165 if (err != -NFS4ERR_DELAY)
4245 break; 4166 break;
4246 nfs4_handle_exception(server, err, &exception); 4167 nfs4_handle_exception(server, err, &exception);
4247 } while (exception.retry); 4168 } while (exception.retry);
@@ -4266,7 +4187,6 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4266 goto out; 4187 goto out;
4267 case -NFS4ERR_GRACE: 4188 case -NFS4ERR_GRACE:
4268 case -NFS4ERR_DELAY: 4189 case -NFS4ERR_DELAY:
4269 case -EKEYEXPIRED:
4270 nfs4_handle_exception(server, err, &exception); 4190 nfs4_handle_exception(server, err, &exception);
4271 err = 0; 4191 err = 0;
4272 } 4192 }
@@ -4412,13 +4332,21 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4412 nfs4_state_mark_reclaim_nograce(server->nfs_client, state); 4332 nfs4_state_mark_reclaim_nograce(server->nfs_client, state);
4413 err = 0; 4333 err = 0;
4414 goto out; 4334 goto out;
4335 case -EKEYEXPIRED:
4336 /*
4337 * User RPCSEC_GSS context has expired.
4338 * We cannot recover this stateid now, so
4339 * skip it and allow recovery thread to
4340 * proceed.
4341 */
4342 err = 0;
4343 goto out;
4415 case -ENOMEM: 4344 case -ENOMEM:
4416 case -NFS4ERR_DENIED: 4345 case -NFS4ERR_DENIED:
4417 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 4346 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
4418 err = 0; 4347 err = 0;
4419 goto out; 4348 goto out;
4420 case -NFS4ERR_DELAY: 4349 case -NFS4ERR_DELAY:
4421 case -EKEYEXPIRED:
4422 break; 4350 break;
4423 } 4351 }
4424 err = nfs4_handle_exception(server, err, &exception); 4352 err = nfs4_handle_exception(server, err, &exception);
@@ -4647,7 +4575,6 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4647 switch (task->tk_status) { 4575 switch (task->tk_status) {
4648 case -NFS4ERR_DELAY: 4576 case -NFS4ERR_DELAY:
4649 case -NFS4ERR_GRACE: 4577 case -NFS4ERR_GRACE:
4650 case -EKEYEXPIRED:
4651 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); 4578 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4652 rpc_delay(task, NFS4_POLL_RETRY_MIN); 4579 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4653 task->tk_status = 0; 4580 task->tk_status = 0;
@@ -4687,7 +4614,6 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
4687 }; 4614 };
4688 int status; 4615 int status;
4689 4616
4690 res.lr_seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
4691 dprintk("--> %s\n", __func__); 4617 dprintk("--> %s\n", __func__);
4692 task = rpc_run_task(&task_setup); 4618 task = rpc_run_task(&task_setup);
4693 4619
@@ -5111,7 +5037,6 @@ static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client
5111{ 5037{
5112 switch(task->tk_status) { 5038 switch(task->tk_status) {
5113 case -NFS4ERR_DELAY: 5039 case -NFS4ERR_DELAY:
5114 case -EKEYEXPIRED:
5115 rpc_delay(task, NFS4_POLL_RETRY_MAX); 5040 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5116 return -EAGAIN; 5041 return -EAGAIN;
5117 default: 5042 default:
@@ -5180,12 +5105,11 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
5180 5105
5181 if (!atomic_inc_not_zero(&clp->cl_count)) 5106 if (!atomic_inc_not_zero(&clp->cl_count))
5182 return ERR_PTR(-EIO); 5107 return ERR_PTR(-EIO);
5183 calldata = kmalloc(sizeof(*calldata), GFP_NOFS); 5108 calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
5184 if (calldata == NULL) { 5109 if (calldata == NULL) {
5185 nfs_put_client(clp); 5110 nfs_put_client(clp);
5186 return ERR_PTR(-ENOMEM); 5111 return ERR_PTR(-ENOMEM);
5187 } 5112 }
5188 calldata->res.sr_slotid = NFS4_MAX_SLOT_TABLE;
5189 msg.rpc_argp = &calldata->args; 5113 msg.rpc_argp = &calldata->args;
5190 msg.rpc_resp = &calldata->res; 5114 msg.rpc_resp = &calldata->res;
5191 calldata->clp = clp; 5115 calldata->clp = clp;
@@ -5254,7 +5178,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
5254 case -NFS4ERR_WRONG_CRED: /* What to do here? */ 5178 case -NFS4ERR_WRONG_CRED: /* What to do here? */
5255 break; 5179 break;
5256 case -NFS4ERR_DELAY: 5180 case -NFS4ERR_DELAY:
5257 case -EKEYEXPIRED:
5258 rpc_delay(task, NFS4_POLL_RETRY_MAX); 5181 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5259 return -EAGAIN; 5182 return -EAGAIN;
5260 default: 5183 default:
@@ -5317,7 +5240,6 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5317 goto out; 5240 goto out;
5318 calldata->clp = clp; 5241 calldata->clp = clp;
5319 calldata->arg.one_fs = 0; 5242 calldata->arg.one_fs = 0;
5320 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
5321 5243
5322 msg.rpc_argp = &calldata->arg; 5244 msg.rpc_argp = &calldata->arg;
5323 msg.rpc_resp = &calldata->res; 5245 msg.rpc_resp = &calldata->res;
@@ -5443,6 +5365,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
5443 .unlink_setup = nfs4_proc_unlink_setup, 5365 .unlink_setup = nfs4_proc_unlink_setup,
5444 .unlink_done = nfs4_proc_unlink_done, 5366 .unlink_done = nfs4_proc_unlink_done,
5445 .rename = nfs4_proc_rename, 5367 .rename = nfs4_proc_rename,
5368 .rename_setup = nfs4_proc_rename_setup,
5369 .rename_done = nfs4_proc_rename_done,
5446 .link = nfs4_proc_link, 5370 .link = nfs4_proc_link,
5447 .symlink = nfs4_proc_symlink, 5371 .symlink = nfs4_proc_symlink,
5448 .mkdir = nfs4_proc_mkdir, 5372 .mkdir = nfs4_proc_mkdir,
@@ -5463,6 +5387,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
5463 .lock = nfs4_proc_lock, 5387 .lock = nfs4_proc_lock,
5464 .clear_acl_cache = nfs4_zap_acl_attr, 5388 .clear_acl_cache = nfs4_zap_acl_attr,
5465 .close_context = nfs4_close_context, 5389 .close_context = nfs4_close_context,
5390 .open_context = nfs4_atomic_open,
5466}; 5391};
5467 5392
5468/* 5393/*