aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c171
1 files changed, 93 insertions, 78 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3b711f5147a7..980a216a48c8 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -182,7 +182,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
182{ 182{
183 struct nfs4_delegation *dp; 183 struct nfs4_delegation *dp;
184 struct nfs4_file *fp = stp->st_file; 184 struct nfs4_file *fp = stp->st_file;
185 struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback; 185 struct nfs4_cb_conn *cb = &stp->st_stateowner->so_client->cl_cb_conn;
186 186
187 dprintk("NFSD alloc_init_deleg\n"); 187 dprintk("NFSD alloc_init_deleg\n");
188 if (fp->fi_had_conflict) 188 if (fp->fi_had_conflict)
@@ -203,10 +203,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
203 get_file(stp->st_vfs_file); 203 get_file(stp->st_vfs_file);
204 dp->dl_vfs_file = stp->st_vfs_file; 204 dp->dl_vfs_file = stp->st_vfs_file;
205 dp->dl_type = type; 205 dp->dl_type = type;
206 dp->dl_recall.cbr_dp = NULL; 206 dp->dl_ident = cb->cb_ident;
207 dp->dl_recall.cbr_ident = cb->cb_ident; 207 dp->dl_stateid.si_boot = get_seconds();
208 dp->dl_recall.cbr_trunc = 0;
209 dp->dl_stateid.si_boot = boot_time;
210 dp->dl_stateid.si_stateownerid = current_delegid++; 208 dp->dl_stateid.si_stateownerid = current_delegid++;
211 dp->dl_stateid.si_fileid = 0; 209 dp->dl_stateid.si_fileid = 0;
212 dp->dl_stateid.si_generation = 0; 210 dp->dl_stateid.si_generation = 0;
@@ -427,6 +425,11 @@ static int set_forechannel_maxreqs(struct nfsd4_channel_attrs *fchan)
427{ 425{
428 int status = 0, np = fchan->maxreqs * NFSD_PAGES_PER_SLOT; 426 int status = 0, np = fchan->maxreqs * NFSD_PAGES_PER_SLOT;
429 427
428 if (fchan->maxreqs < 1)
429 return nfserr_inval;
430 else if (fchan->maxreqs > NFSD_MAX_SLOTS_PER_SESSION)
431 fchan->maxreqs = NFSD_MAX_SLOTS_PER_SESSION;
432
430 spin_lock(&nfsd_serv->sv_lock); 433 spin_lock(&nfsd_serv->sv_lock);
431 if (np + nfsd_serv->sv_drc_pages_used > nfsd_serv->sv_drc_max_pages) 434 if (np + nfsd_serv->sv_drc_pages_used > nfsd_serv->sv_drc_max_pages)
432 np = nfsd_serv->sv_drc_max_pages - nfsd_serv->sv_drc_pages_used; 435 np = nfsd_serv->sv_drc_max_pages - nfsd_serv->sv_drc_pages_used;
@@ -446,8 +449,8 @@ static int set_forechannel_maxreqs(struct nfsd4_channel_attrs *fchan)
446 * fchan holds the client values on input, and the server values on output 449 * fchan holds the client values on input, and the server values on output
447 */ 450 */
448static int init_forechannel_attrs(struct svc_rqst *rqstp, 451static int init_forechannel_attrs(struct svc_rqst *rqstp,
449 struct nfsd4_session *session, 452 struct nfsd4_channel_attrs *session_fchan,
450 struct nfsd4_channel_attrs *fchan) 453 struct nfsd4_channel_attrs *fchan)
451{ 454{
452 int status = 0; 455 int status = 0;
453 __u32 maxcount = svc_max_payload(rqstp); 456 __u32 maxcount = svc_max_payload(rqstp);
@@ -457,21 +460,21 @@ static int init_forechannel_attrs(struct svc_rqst *rqstp,
457 /* Use the client's max request and max response size if possible */ 460 /* Use the client's max request and max response size if possible */
458 if (fchan->maxreq_sz > maxcount) 461 if (fchan->maxreq_sz > maxcount)
459 fchan->maxreq_sz = maxcount; 462 fchan->maxreq_sz = maxcount;
460 session->se_fmaxreq_sz = fchan->maxreq_sz; 463 session_fchan->maxreq_sz = fchan->maxreq_sz;
461 464
462 if (fchan->maxresp_sz > maxcount) 465 if (fchan->maxresp_sz > maxcount)
463 fchan->maxresp_sz = maxcount; 466 fchan->maxresp_sz = maxcount;
464 session->se_fmaxresp_sz = fchan->maxresp_sz; 467 session_fchan->maxresp_sz = fchan->maxresp_sz;
465 468
466 /* Set the max response cached size our default which is 469 /* Set the max response cached size our default which is
467 * a multiple of PAGE_SIZE and small */ 470 * a multiple of PAGE_SIZE and small */
468 session->se_fmaxresp_cached = NFSD_PAGES_PER_SLOT * PAGE_SIZE; 471 session_fchan->maxresp_cached = NFSD_PAGES_PER_SLOT * PAGE_SIZE;
469 fchan->maxresp_cached = session->se_fmaxresp_cached; 472 fchan->maxresp_cached = session_fchan->maxresp_cached;
470 473
471 /* Use the client's maxops if possible */ 474 /* Use the client's maxops if possible */
472 if (fchan->maxops > NFSD_MAX_OPS_PER_COMPOUND) 475 if (fchan->maxops > NFSD_MAX_OPS_PER_COMPOUND)
473 fchan->maxops = NFSD_MAX_OPS_PER_COMPOUND; 476 fchan->maxops = NFSD_MAX_OPS_PER_COMPOUND;
474 session->se_fmaxops = fchan->maxops; 477 session_fchan->maxops = fchan->maxops;
475 478
476 /* try to use the client requested number of slots */ 479 /* try to use the client requested number of slots */
477 if (fchan->maxreqs > NFSD_MAX_SLOTS_PER_SESSION) 480 if (fchan->maxreqs > NFSD_MAX_SLOTS_PER_SESSION)
@@ -483,7 +486,7 @@ static int init_forechannel_attrs(struct svc_rqst *rqstp,
483 */ 486 */
484 status = set_forechannel_maxreqs(fchan); 487 status = set_forechannel_maxreqs(fchan);
485 488
486 session->se_fnumslots = fchan->maxreqs; 489 session_fchan->maxreqs = fchan->maxreqs;
487 return status; 490 return status;
488} 491}
489 492
@@ -497,12 +500,14 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
497 memset(&tmp, 0, sizeof(tmp)); 500 memset(&tmp, 0, sizeof(tmp));
498 501
499 /* FIXME: For now, we just accept the client back channel attributes. */ 502 /* FIXME: For now, we just accept the client back channel attributes. */
500 status = init_forechannel_attrs(rqstp, &tmp, &cses->fore_channel); 503 tmp.se_bchannel = cses->back_channel;
504 status = init_forechannel_attrs(rqstp, &tmp.se_fchannel,
505 &cses->fore_channel);
501 if (status) 506 if (status)
502 goto out; 507 goto out;
503 508
504 /* allocate struct nfsd4_session and slot table in one piece */ 509 /* allocate struct nfsd4_session and slot table in one piece */
505 slotsize = tmp.se_fnumslots * sizeof(struct nfsd4_slot); 510 slotsize = tmp.se_fchannel.maxreqs * sizeof(struct nfsd4_slot);
506 new = kzalloc(sizeof(*new) + slotsize, GFP_KERNEL); 511 new = kzalloc(sizeof(*new) + slotsize, GFP_KERNEL);
507 if (!new) 512 if (!new)
508 goto out; 513 goto out;
@@ -576,7 +581,7 @@ free_session(struct kref *kref)
576 int i; 581 int i;
577 582
578 ses = container_of(kref, struct nfsd4_session, se_ref); 583 ses = container_of(kref, struct nfsd4_session, se_ref);
579 for (i = 0; i < ses->se_fnumslots; i++) { 584 for (i = 0; i < ses->se_fchannel.maxreqs; i++) {
580 struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry; 585 struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry;
581 nfsd4_release_respages(e->ce_respages, e->ce_resused); 586 nfsd4_release_respages(e->ce_respages, e->ce_resused);
582 } 587 }
@@ -632,16 +637,20 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
632static void 637static void
633shutdown_callback_client(struct nfs4_client *clp) 638shutdown_callback_client(struct nfs4_client *clp)
634{ 639{
635 struct rpc_clnt *clnt = clp->cl_callback.cb_client; 640 struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
636 641
637 if (clnt) { 642 if (clnt) {
638 /* 643 /*
639 * Callback threads take a reference on the client, so there 644 * Callback threads take a reference on the client, so there
640 * should be no outstanding callbacks at this point. 645 * should be no outstanding callbacks at this point.
641 */ 646 */
642 clp->cl_callback.cb_client = NULL; 647 clp->cl_cb_conn.cb_client = NULL;
643 rpc_shutdown_client(clnt); 648 rpc_shutdown_client(clnt);
644 } 649 }
650 if (clp->cl_cb_conn.cb_cred) {
651 put_rpccred(clp->cl_cb_conn.cb_cred);
652 clp->cl_cb_conn.cb_cred = NULL;
653 }
645} 654}
646 655
647static inline void 656static inline void
@@ -714,7 +723,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir)
714 return NULL; 723 return NULL;
715 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 724 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
716 atomic_set(&clp->cl_count, 1); 725 atomic_set(&clp->cl_count, 1);
717 atomic_set(&clp->cl_callback.cb_set, 0); 726 atomic_set(&clp->cl_cb_conn.cb_set, 0);
718 INIT_LIST_HEAD(&clp->cl_idhash); 727 INIT_LIST_HEAD(&clp->cl_idhash);
719 INIT_LIST_HEAD(&clp->cl_strhash); 728 INIT_LIST_HEAD(&clp->cl_strhash);
720 INIT_LIST_HEAD(&clp->cl_openowners); 729 INIT_LIST_HEAD(&clp->cl_openowners);
@@ -966,7 +975,7 @@ parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigne
966static void 975static void
967gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) 976gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
968{ 977{
969 struct nfs4_callback *cb = &clp->cl_callback; 978 struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
970 979
971 /* Currently, we only support tcp for the callback channel */ 980 /* Currently, we only support tcp for the callback channel */
972 if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) 981 if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
@@ -975,6 +984,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
975 if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val, 984 if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val,
976 &cb->cb_addr, &cb->cb_port))) 985 &cb->cb_addr, &cb->cb_port)))
977 goto out_err; 986 goto out_err;
987 cb->cb_minorversion = 0;
978 cb->cb_prog = se->se_callback_prog; 988 cb->cb_prog = se->se_callback_prog;
979 cb->cb_ident = se->se_callback_ident; 989 cb->cb_ident = se->se_callback_ident;
980 return; 990 return;
@@ -1128,7 +1138,7 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1128 * is sent (lease renewal). 1138 * is sent (lease renewal).
1129 */ 1139 */
1130 if (seq && nfsd4_not_cached(resp)) { 1140 if (seq && nfsd4_not_cached(resp)) {
1131 seq->maxslots = resp->cstate.session->se_fnumslots; 1141 seq->maxslots = resp->cstate.session->se_fchannel.maxreqs;
1132 return nfs_ok; 1142 return nfs_ok;
1133 } 1143 }
1134 1144
@@ -1238,12 +1248,6 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1238 expire_client(conf); 1248 expire_client(conf);
1239 goto out_new; 1249 goto out_new;
1240 } 1250 }
1241 if (ip_addr != conf->cl_addr &&
1242 !(exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A)) {
1243 /* Client collision. 18.35.4 case 3 */
1244 status = nfserr_clid_inuse;
1245 goto out;
1246 }
1247 /* 1251 /*
1248 * Set bit when the owner id and verifier map to an already 1252 * Set bit when the owner id and verifier map to an already
1249 * confirmed client id (18.35.3). 1253 * confirmed client id (18.35.3).
@@ -1257,12 +1261,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1257 copy_verf(conf, &verf); 1261 copy_verf(conf, &verf);
1258 new = conf; 1262 new = conf;
1259 goto out_copy; 1263 goto out_copy;
1260 } else { 1264 }
1261 /* 18.35.4 case 7 */ 1265
1262 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1266 /* 18.35.4 case 7 */
1263 status = nfserr_noent; 1267 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
1264 goto out; 1268 status = nfserr_noent;
1265 } 1269 goto out;
1266 } 1270 }
1267 1271
1268 unconf = find_unconfirmed_client_by_str(dname, strhashval, true); 1272 unconf = find_unconfirmed_client_by_str(dname, strhashval, true);
@@ -1471,7 +1475,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1471 goto out; 1475 goto out;
1472 1476
1473 status = nfserr_badslot; 1477 status = nfserr_badslot;
1474 if (seq->slotid >= session->se_fnumslots) 1478 if (seq->slotid >= session->se_fchannel.maxreqs)
1475 goto out; 1479 goto out;
1476 1480
1477 slot = &session->se_slots[seq->slotid]; 1481 slot = &session->se_slots[seq->slotid];
@@ -1686,9 +1690,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1686 else { 1690 else {
1687 /* XXX: We just turn off callbacks until we can handle 1691 /* XXX: We just turn off callbacks until we can handle
1688 * change request correctly. */ 1692 * change request correctly. */
1689 atomic_set(&conf->cl_callback.cb_set, 0); 1693 atomic_set(&conf->cl_cb_conn.cb_set, 0);
1690 gen_confirm(conf);
1691 nfsd4_remove_clid_dir(unconf);
1692 expire_client(unconf); 1694 expire_client(unconf);
1693 status = nfs_ok; 1695 status = nfs_ok;
1694 1696
@@ -1882,7 +1884,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
1882 stp->st_stateowner = sop; 1884 stp->st_stateowner = sop;
1883 get_nfs4_file(fp); 1885 get_nfs4_file(fp);
1884 stp->st_file = fp; 1886 stp->st_file = fp;
1885 stp->st_stateid.si_boot = boot_time; 1887 stp->st_stateid.si_boot = get_seconds();
1886 stp->st_stateid.si_stateownerid = sop->so_id; 1888 stp->st_stateid.si_stateownerid = sop->so_id;
1887 stp->st_stateid.si_fileid = fp->fi_id; 1889 stp->st_stateid.si_fileid = fp->fi_id;
1888 stp->st_stateid.si_generation = 0; 1890 stp->st_stateid.si_generation = 0;
@@ -2059,19 +2061,6 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
2059} 2061}
2060 2062
2061/* 2063/*
2062 * Recall a delegation
2063 */
2064static int
2065do_recall(void *__dp)
2066{
2067 struct nfs4_delegation *dp = __dp;
2068
2069 dp->dl_file->fi_had_conflict = true;
2070 nfsd4_cb_recall(dp);
2071 return 0;
2072}
2073
2074/*
2075 * Spawn a thread to perform a recall on the delegation represented 2064 * Spawn a thread to perform a recall on the delegation represented
2076 * by the lease (file_lock) 2065 * by the lease (file_lock)
2077 * 2066 *
@@ -2082,8 +2071,7 @@ do_recall(void *__dp)
2082static 2071static
2083void nfsd_break_deleg_cb(struct file_lock *fl) 2072void nfsd_break_deleg_cb(struct file_lock *fl)
2084{ 2073{
2085 struct nfs4_delegation *dp= (struct nfs4_delegation *)fl->fl_owner; 2074 struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
2086 struct task_struct *t;
2087 2075
2088 dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); 2076 dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
2089 if (!dp) 2077 if (!dp)
@@ -2111,16 +2099,8 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
2111 */ 2099 */
2112 fl->fl_break_time = 0; 2100 fl->fl_break_time = 0;
2113 2101
2114 t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall"); 2102 dp->dl_file->fi_had_conflict = true;
2115 if (IS_ERR(t)) { 2103 nfsd4_cb_recall(dp);
2116 struct nfs4_client *clp = dp->dl_client;
2117
2118 printk(KERN_INFO "NFSD: Callback thread failed for "
2119 "for client (clientid %08x/%08x)\n",
2120 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
2121 put_nfs4_client(dp->dl_client);
2122 nfs4_put_delegation(dp);
2123 }
2124} 2104}
2125 2105
2126/* 2106/*
@@ -2422,7 +2402,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2422{ 2402{
2423 struct nfs4_delegation *dp; 2403 struct nfs4_delegation *dp;
2424 struct nfs4_stateowner *sop = stp->st_stateowner; 2404 struct nfs4_stateowner *sop = stp->st_stateowner;
2425 struct nfs4_callback *cb = &sop->so_client->cl_callback; 2405 struct nfs4_cb_conn *cb = &sop->so_client->cl_cb_conn;
2426 struct file_lock fl, *flp = &fl; 2406 struct file_lock fl, *flp = &fl;
2427 int status, flag = 0; 2407 int status, flag = 0;
2428 2408
@@ -2614,7 +2594,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2614 renew_client(clp); 2594 renew_client(clp);
2615 status = nfserr_cb_path_down; 2595 status = nfserr_cb_path_down;
2616 if (!list_empty(&clp->cl_delegations) 2596 if (!list_empty(&clp->cl_delegations)
2617 && !atomic_read(&clp->cl_callback.cb_set)) 2597 && !atomic_read(&clp->cl_cb_conn.cb_set))
2618 goto out; 2598 goto out;
2619 status = nfs_ok; 2599 status = nfs_ok;
2620out: 2600out:
@@ -2738,12 +2718,42 @@ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
2738static int 2718static int
2739STALE_STATEID(stateid_t *stateid) 2719STALE_STATEID(stateid_t *stateid)
2740{ 2720{
2741 if (stateid->si_boot == boot_time) 2721 if (time_after((unsigned long)boot_time,
2742 return 0; 2722 (unsigned long)stateid->si_boot)) {
2743 dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", 2723 dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
2744 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, 2724 stateid->si_boot, stateid->si_stateownerid,
2745 stateid->si_generation); 2725 stateid->si_fileid, stateid->si_generation);
2746 return 1; 2726 return 1;
2727 }
2728 return 0;
2729}
2730
2731static int
2732EXPIRED_STATEID(stateid_t *stateid)
2733{
2734 if (time_before((unsigned long)boot_time,
2735 ((unsigned long)stateid->si_boot)) &&
2736 time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) {
2737 dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n",
2738 stateid->si_boot, stateid->si_stateownerid,
2739 stateid->si_fileid, stateid->si_generation);
2740 return 1;
2741 }
2742 return 0;
2743}
2744
2745static __be32
2746stateid_error_map(stateid_t *stateid)
2747{
2748 if (STALE_STATEID(stateid))
2749 return nfserr_stale_stateid;
2750 if (EXPIRED_STATEID(stateid))
2751 return nfserr_expired;
2752
2753 dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n",
2754 stateid->si_boot, stateid->si_stateownerid,
2755 stateid->si_fileid, stateid->si_generation);
2756 return nfserr_bad_stateid;
2747} 2757}
2748 2758
2749static inline int 2759static inline int
@@ -2867,8 +2877,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2867 status = nfserr_bad_stateid; 2877 status = nfserr_bad_stateid;
2868 if (is_delegation_stateid(stateid)) { 2878 if (is_delegation_stateid(stateid)) {
2869 dp = find_delegation_stateid(ino, stateid); 2879 dp = find_delegation_stateid(ino, stateid);
2870 if (!dp) 2880 if (!dp) {
2881 status = stateid_error_map(stateid);
2871 goto out; 2882 goto out;
2883 }
2872 status = check_stateid_generation(stateid, &dp->dl_stateid, 2884 status = check_stateid_generation(stateid, &dp->dl_stateid,
2873 flags); 2885 flags);
2874 if (status) 2886 if (status)
@@ -2881,8 +2893,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2881 *filpp = dp->dl_vfs_file; 2893 *filpp = dp->dl_vfs_file;
2882 } else { /* open or lock stateid */ 2894 } else { /* open or lock stateid */
2883 stp = find_stateid(stateid, flags); 2895 stp = find_stateid(stateid, flags);
2884 if (!stp) 2896 if (!stp) {
2897 status = stateid_error_map(stateid);
2885 goto out; 2898 goto out;
2899 }
2886 if (nfs4_check_fh(current_fh, stp)) 2900 if (nfs4_check_fh(current_fh, stp))
2887 goto out; 2901 goto out;
2888 if (!stp->st_stateowner->so_confirmed) 2902 if (!stp->st_stateowner->so_confirmed)
@@ -2956,7 +2970,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
2956 */ 2970 */
2957 sop = search_close_lru(stateid->si_stateownerid, flags); 2971 sop = search_close_lru(stateid->si_stateownerid, flags);
2958 if (sop == NULL) 2972 if (sop == NULL)
2959 return nfserr_bad_stateid; 2973 return stateid_error_map(stateid);
2960 *sopp = sop; 2974 *sopp = sop;
2961 goto check_replay; 2975 goto check_replay;
2962 } 2976 }
@@ -3227,8 +3241,10 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3227 if (!is_delegation_stateid(stateid)) 3241 if (!is_delegation_stateid(stateid))
3228 goto out; 3242 goto out;
3229 dp = find_delegation_stateid(inode, stateid); 3243 dp = find_delegation_stateid(inode, stateid);
3230 if (!dp) 3244 if (!dp) {
3245 status = stateid_error_map(stateid);
3231 goto out; 3246 goto out;
3247 }
3232 status = check_stateid_generation(stateid, &dp->dl_stateid, flags); 3248 status = check_stateid_generation(stateid, &dp->dl_stateid, flags);
3233 if (status) 3249 if (status)
3234 goto out; 3250 goto out;
@@ -3455,7 +3471,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3455 stp->st_stateowner = sop; 3471 stp->st_stateowner = sop;
3456 get_nfs4_file(fp); 3472 get_nfs4_file(fp);
3457 stp->st_file = fp; 3473 stp->st_file = fp;
3458 stp->st_stateid.si_boot = boot_time; 3474 stp->st_stateid.si_boot = get_seconds();
3459 stp->st_stateid.si_stateownerid = sop->so_id; 3475 stp->st_stateid.si_stateownerid = sop->so_id;
3460 stp->st_stateid.si_fileid = fp->fi_id; 3476 stp->st_stateid.si_fileid = fp->fi_id;
3461 stp->st_stateid.si_generation = 0; 3477 stp->st_stateid.si_generation = 0;
@@ -3987,6 +4003,7 @@ nfs4_state_init(void)
3987 INIT_LIST_HEAD(&conf_str_hashtbl[i]); 4003 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
3988 INIT_LIST_HEAD(&unconf_str_hashtbl[i]); 4004 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
3989 INIT_LIST_HEAD(&unconf_id_hashtbl[i]); 4005 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
4006 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
3990 } 4007 }
3991 for (i = 0; i < SESSION_HASH_SIZE; i++) 4008 for (i = 0; i < SESSION_HASH_SIZE; i++)
3992 INIT_LIST_HEAD(&sessionid_hashtbl[i]); 4009 INIT_LIST_HEAD(&sessionid_hashtbl[i]);
@@ -4009,8 +4026,6 @@ nfs4_state_init(void)
4009 INIT_LIST_HEAD(&close_lru); 4026 INIT_LIST_HEAD(&close_lru);
4010 INIT_LIST_HEAD(&client_lru); 4027 INIT_LIST_HEAD(&client_lru);
4011 INIT_LIST_HEAD(&del_recall_lru); 4028 INIT_LIST_HEAD(&del_recall_lru);
4012 for (i = 0; i < CLIENT_HASH_SIZE; i++)
4013 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
4014 reclaim_str_hashtbl_size = 0; 4029 reclaim_str_hashtbl_size = 0;
4015 return 0; 4030 return 0;
4016} 4031}