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.c376
1 files changed, 196 insertions, 180 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6a8fedaa4f55..12f7109720c2 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -45,8 +45,8 @@
45#define NFSDDBG_FACILITY NFSDDBG_PROC 45#define NFSDDBG_FACILITY NFSDDBG_PROC
46 46
47/* Globals */ 47/* Globals */
48static time_t lease_time = 90; /* default lease time */ 48time_t nfsd4_lease = 90; /* default lease time */
49static time_t user_lease_time = 90; 49time_t nfsd4_grace = 90;
50static time_t boot_time; 50static time_t boot_time;
51static u32 current_ownerid = 1; 51static u32 current_ownerid = 1;
52static u32 current_fileid = 1; 52static u32 current_fileid = 1;
@@ -190,7 +190,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
190 dp->dl_vfs_file = stp->st_vfs_file; 190 dp->dl_vfs_file = stp->st_vfs_file;
191 dp->dl_type = type; 191 dp->dl_type = type;
192 dp->dl_ident = cb->cb_ident; 192 dp->dl_ident = cb->cb_ident;
193 dp->dl_stateid.si_boot = get_seconds(); 193 dp->dl_stateid.si_boot = boot_time;
194 dp->dl_stateid.si_stateownerid = current_delegid++; 194 dp->dl_stateid.si_stateownerid = current_delegid++;
195 dp->dl_stateid.si_fileid = 0; 195 dp->dl_stateid.si_fileid = 0;
196 dp->dl_stateid.si_generation = 0; 196 dp->dl_stateid.si_generation = 0;
@@ -199,6 +199,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
199 atomic_set(&dp->dl_count, 1); 199 atomic_set(&dp->dl_count, 1);
200 list_add(&dp->dl_perfile, &fp->fi_delegations); 200 list_add(&dp->dl_perfile, &fp->fi_delegations);
201 list_add(&dp->dl_perclnt, &clp->cl_delegations); 201 list_add(&dp->dl_perclnt, &clp->cl_delegations);
202 INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc);
202 return dp; 203 return dp;
203} 204}
204 205
@@ -249,6 +250,9 @@ unhash_delegation(struct nfs4_delegation *dp)
249 * SETCLIENTID state 250 * SETCLIENTID state
250 */ 251 */
251 252
253/* client_lock protects the client lru list and session hash table */
254static DEFINE_SPINLOCK(client_lock);
255
252/* Hash tables for nfs4_clientid state */ 256/* Hash tables for nfs4_clientid state */
253#define CLIENT_HASH_BITS 4 257#define CLIENT_HASH_BITS 4
254#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS) 258#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
@@ -367,7 +371,6 @@ static void release_openowner(struct nfs4_stateowner *sop)
367 nfs4_put_stateowner(sop); 371 nfs4_put_stateowner(sop);
368} 372}
369 373
370static DEFINE_SPINLOCK(sessionid_lock);
371#define SESSION_HASH_SIZE 512 374#define SESSION_HASH_SIZE 512
372static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE]; 375static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
373 376
@@ -565,10 +568,10 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
565 568
566 new->se_flags = cses->flags; 569 new->se_flags = cses->flags;
567 kref_init(&new->se_ref); 570 kref_init(&new->se_ref);
568 spin_lock(&sessionid_lock); 571 spin_lock(&client_lock);
569 list_add(&new->se_hash, &sessionid_hashtbl[idx]); 572 list_add(&new->se_hash, &sessionid_hashtbl[idx]);
570 list_add(&new->se_perclnt, &clp->cl_sessions); 573 list_add(&new->se_perclnt, &clp->cl_sessions);
571 spin_unlock(&sessionid_lock); 574 spin_unlock(&client_lock);
572 575
573 status = nfs_ok; 576 status = nfs_ok;
574out: 577out:
@@ -579,7 +582,7 @@ out_free:
579 goto out; 582 goto out;
580} 583}
581 584
582/* caller must hold sessionid_lock */ 585/* caller must hold client_lock */
583static struct nfsd4_session * 586static struct nfsd4_session *
584find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid) 587find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
585{ 588{
@@ -602,7 +605,7 @@ find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
602 return NULL; 605 return NULL;
603} 606}
604 607
605/* caller must hold sessionid_lock */ 608/* caller must hold client_lock */
606static void 609static void
607unhash_session(struct nfsd4_session *ses) 610unhash_session(struct nfsd4_session *ses)
608{ 611{
@@ -610,15 +613,6 @@ unhash_session(struct nfsd4_session *ses)
610 list_del(&ses->se_perclnt); 613 list_del(&ses->se_perclnt);
611} 614}
612 615
613static void
614release_session(struct nfsd4_session *ses)
615{
616 spin_lock(&sessionid_lock);
617 unhash_session(ses);
618 spin_unlock(&sessionid_lock);
619 nfsd4_put_session(ses);
620}
621
622void 616void
623free_session(struct kref *kref) 617free_session(struct kref *kref)
624{ 618{
@@ -634,9 +628,18 @@ free_session(struct kref *kref)
634 kfree(ses); 628 kfree(ses);
635} 629}
636 630
631/* must be called under the client_lock */
637static inline void 632static inline void
638renew_client(struct nfs4_client *clp) 633renew_client_locked(struct nfs4_client *clp)
639{ 634{
635 if (is_client_expired(clp)) {
636 dprintk("%s: client (clientid %08x/%08x) already expired\n",
637 __func__,
638 clp->cl_clientid.cl_boot,
639 clp->cl_clientid.cl_id);
640 return;
641 }
642
640 /* 643 /*
641 * Move client to the end to the LRU list. 644 * Move client to the end to the LRU list.
642 */ 645 */
@@ -647,6 +650,14 @@ renew_client(struct nfs4_client *clp)
647 clp->cl_time = get_seconds(); 650 clp->cl_time = get_seconds();
648} 651}
649 652
653static inline void
654renew_client(struct nfs4_client *clp)
655{
656 spin_lock(&client_lock);
657 renew_client_locked(clp);
658 spin_unlock(&client_lock);
659}
660
650/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */ 661/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
651static int 662static int
652STALE_CLIENTID(clientid_t *clid) 663STALE_CLIENTID(clientid_t *clid)
@@ -680,27 +691,9 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
680 return clp; 691 return clp;
681} 692}
682 693
683static void
684shutdown_callback_client(struct nfs4_client *clp)
685{
686 struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
687
688 if (clnt) {
689 /*
690 * Callback threads take a reference on the client, so there
691 * should be no outstanding callbacks at this point.
692 */
693 clp->cl_cb_conn.cb_client = NULL;
694 rpc_shutdown_client(clnt);
695 }
696}
697
698static inline void 694static inline void
699free_client(struct nfs4_client *clp) 695free_client(struct nfs4_client *clp)
700{ 696{
701 shutdown_callback_client(clp);
702 if (clp->cl_cb_xprt)
703 svc_xprt_put(clp->cl_cb_xprt);
704 if (clp->cl_cred.cr_group_info) 697 if (clp->cl_cred.cr_group_info)
705 put_group_info(clp->cl_cred.cr_group_info); 698 put_group_info(clp->cl_cred.cr_group_info);
706 kfree(clp->cl_principal); 699 kfree(clp->cl_principal);
@@ -709,10 +702,34 @@ free_client(struct nfs4_client *clp)
709} 702}
710 703
711void 704void
712put_nfs4_client(struct nfs4_client *clp) 705release_session_client(struct nfsd4_session *session)
713{ 706{
714 if (atomic_dec_and_test(&clp->cl_count)) 707 struct nfs4_client *clp = session->se_client;
708
709 if (!atomic_dec_and_lock(&clp->cl_refcount, &client_lock))
710 return;
711 if (is_client_expired(clp)) {
715 free_client(clp); 712 free_client(clp);
713 session->se_client = NULL;
714 } else
715 renew_client_locked(clp);
716 spin_unlock(&client_lock);
717 nfsd4_put_session(session);
718}
719
720/* must be called under the client_lock */
721static inline void
722unhash_client_locked(struct nfs4_client *clp)
723{
724 mark_client_expired(clp);
725 list_del(&clp->cl_lru);
726 while (!list_empty(&clp->cl_sessions)) {
727 struct nfsd4_session *ses;
728 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
729 se_perclnt);
730 unhash_session(ses);
731 nfsd4_put_session(ses);
732 }
716} 733}
717 734
718static void 735static void
@@ -722,9 +739,6 @@ expire_client(struct nfs4_client *clp)
722 struct nfs4_delegation *dp; 739 struct nfs4_delegation *dp;
723 struct list_head reaplist; 740 struct list_head reaplist;
724 741
725 dprintk("NFSD: expire_client cl_count %d\n",
726 atomic_read(&clp->cl_count));
727
728 INIT_LIST_HEAD(&reaplist); 742 INIT_LIST_HEAD(&reaplist);
729 spin_lock(&recall_lock); 743 spin_lock(&recall_lock);
730 while (!list_empty(&clp->cl_delegations)) { 744 while (!list_empty(&clp->cl_delegations)) {
@@ -740,20 +754,20 @@ expire_client(struct nfs4_client *clp)
740 list_del_init(&dp->dl_recall_lru); 754 list_del_init(&dp->dl_recall_lru);
741 unhash_delegation(dp); 755 unhash_delegation(dp);
742 } 756 }
743 list_del(&clp->cl_idhash);
744 list_del(&clp->cl_strhash);
745 list_del(&clp->cl_lru);
746 while (!list_empty(&clp->cl_openowners)) { 757 while (!list_empty(&clp->cl_openowners)) {
747 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient); 758 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient);
748 release_openowner(sop); 759 release_openowner(sop);
749 } 760 }
750 while (!list_empty(&clp->cl_sessions)) { 761 nfsd4_set_callback_client(clp, NULL);
751 struct nfsd4_session *ses; 762 if (clp->cl_cb_conn.cb_xprt)
752 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session, 763 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
753 se_perclnt); 764 list_del(&clp->cl_idhash);
754 release_session(ses); 765 list_del(&clp->cl_strhash);
755 } 766 spin_lock(&client_lock);
756 put_nfs4_client(clp); 767 unhash_client_locked(clp);
768 if (atomic_read(&clp->cl_refcount) == 0)
769 free_client(clp);
770 spin_unlock(&client_lock);
757} 771}
758 772
759static void copy_verf(struct nfs4_client *target, nfs4_verifier *source) 773static void copy_verf(struct nfs4_client *target, nfs4_verifier *source)
@@ -839,14 +853,15 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
839 } 853 }
840 854
841 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 855 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
842 atomic_set(&clp->cl_count, 1); 856 atomic_set(&clp->cl_refcount, 0);
843 atomic_set(&clp->cl_cb_conn.cb_set, 0); 857 atomic_set(&clp->cl_cb_set, 0);
844 INIT_LIST_HEAD(&clp->cl_idhash); 858 INIT_LIST_HEAD(&clp->cl_idhash);
845 INIT_LIST_HEAD(&clp->cl_strhash); 859 INIT_LIST_HEAD(&clp->cl_strhash);
846 INIT_LIST_HEAD(&clp->cl_openowners); 860 INIT_LIST_HEAD(&clp->cl_openowners);
847 INIT_LIST_HEAD(&clp->cl_delegations); 861 INIT_LIST_HEAD(&clp->cl_delegations);
848 INIT_LIST_HEAD(&clp->cl_sessions); 862 INIT_LIST_HEAD(&clp->cl_sessions);
849 INIT_LIST_HEAD(&clp->cl_lru); 863 INIT_LIST_HEAD(&clp->cl_lru);
864 clp->cl_time = get_seconds();
850 clear_bit(0, &clp->cl_cb_slot_busy); 865 clear_bit(0, &clp->cl_cb_slot_busy);
851 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 866 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
852 copy_verf(clp, verf); 867 copy_verf(clp, verf);
@@ -877,8 +892,7 @@ add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
877 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]); 892 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
878 idhashval = clientid_hashval(clp->cl_clientid.cl_id); 893 idhashval = clientid_hashval(clp->cl_clientid.cl_id);
879 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]); 894 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
880 list_add_tail(&clp->cl_lru, &client_lru); 895 renew_client(clp);
881 clp->cl_time = get_seconds();
882} 896}
883 897
884static void 898static void
@@ -888,10 +902,9 @@ move_to_confirmed(struct nfs4_client *clp)
888 unsigned int strhashval; 902 unsigned int strhashval;
889 903
890 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); 904 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
891 list_del_init(&clp->cl_strhash);
892 list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); 905 list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
893 strhashval = clientstr_hashval(clp->cl_recdir); 906 strhashval = clientstr_hashval(clp->cl_recdir);
894 list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); 907 list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
895 renew_client(clp); 908 renew_client(clp);
896} 909}
897 910
@@ -1327,15 +1340,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1327 cs_slot->sl_seqid++; /* from 0 to 1 */ 1340 cs_slot->sl_seqid++; /* from 0 to 1 */
1328 move_to_confirmed(unconf); 1341 move_to_confirmed(unconf);
1329 1342
1330 /*
1331 * We do not support RDMA or persistent sessions
1332 */
1333 cr_ses->flags &= ~SESSION4_PERSIST;
1334 cr_ses->flags &= ~SESSION4_RDMA;
1335
1336 if (cr_ses->flags & SESSION4_BACK_CHAN) { 1343 if (cr_ses->flags & SESSION4_BACK_CHAN) {
1337 unconf->cl_cb_xprt = rqstp->rq_xprt; 1344 unconf->cl_cb_conn.cb_xprt = rqstp->rq_xprt;
1338 svc_xprt_get(unconf->cl_cb_xprt); 1345 svc_xprt_get(rqstp->rq_xprt);
1339 rpc_copy_addr( 1346 rpc_copy_addr(
1340 (struct sockaddr *)&unconf->cl_cb_conn.cb_addr, 1347 (struct sockaddr *)&unconf->cl_cb_conn.cb_addr,
1341 sa); 1348 sa);
@@ -1344,7 +1351,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1344 cstate->minorversion; 1351 cstate->minorversion;
1345 unconf->cl_cb_conn.cb_prog = cr_ses->callback_prog; 1352 unconf->cl_cb_conn.cb_prog = cr_ses->callback_prog;
1346 unconf->cl_cb_seq_nr = 1; 1353 unconf->cl_cb_seq_nr = 1;
1347 nfsd4_probe_callback(unconf); 1354 nfsd4_probe_callback(unconf, &unconf->cl_cb_conn);
1348 } 1355 }
1349 conf = unconf; 1356 conf = unconf;
1350 } else { 1357 } else {
@@ -1352,6 +1359,12 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1352 goto out; 1359 goto out;
1353 } 1360 }
1354 1361
1362 /*
1363 * We do not support RDMA or persistent sessions
1364 */
1365 cr_ses->flags &= ~SESSION4_PERSIST;
1366 cr_ses->flags &= ~SESSION4_RDMA;
1367
1355 status = alloc_init_session(rqstp, conf, cr_ses); 1368 status = alloc_init_session(rqstp, conf, cr_ses);
1356 if (status) 1369 if (status)
1357 goto out; 1370 goto out;
@@ -1369,6 +1382,21 @@ out:
1369 return status; 1382 return status;
1370} 1383}
1371 1384
1385static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
1386{
1387 struct nfsd4_compoundres *resp = rqstp->rq_resp;
1388 struct nfsd4_compoundargs *argp = rqstp->rq_argp;
1389
1390 return argp->opcnt == resp->opcnt;
1391}
1392
1393static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
1394{
1395 if (!session)
1396 return 0;
1397 return !memcmp(sid, &session->se_sessionid, sizeof(*sid));
1398}
1399
1372__be32 1400__be32
1373nfsd4_destroy_session(struct svc_rqst *r, 1401nfsd4_destroy_session(struct svc_rqst *r,
1374 struct nfsd4_compound_state *cstate, 1402 struct nfsd4_compound_state *cstate,
@@ -1384,19 +1412,25 @@ nfsd4_destroy_session(struct svc_rqst *r,
1384 * - Do we need to clear any callback info from previous session? 1412 * - Do we need to clear any callback info from previous session?
1385 */ 1413 */
1386 1414
1415 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
1416 if (!nfsd4_last_compound_op(r))
1417 return nfserr_not_only_op;
1418 }
1387 dump_sessionid(__func__, &sessionid->sessionid); 1419 dump_sessionid(__func__, &sessionid->sessionid);
1388 spin_lock(&sessionid_lock); 1420 spin_lock(&client_lock);
1389 ses = find_in_sessionid_hashtbl(&sessionid->sessionid); 1421 ses = find_in_sessionid_hashtbl(&sessionid->sessionid);
1390 if (!ses) { 1422 if (!ses) {
1391 spin_unlock(&sessionid_lock); 1423 spin_unlock(&client_lock);
1392 goto out; 1424 goto out;
1393 } 1425 }
1394 1426
1395 unhash_session(ses); 1427 unhash_session(ses);
1396 spin_unlock(&sessionid_lock); 1428 spin_unlock(&client_lock);
1397 1429
1430 nfs4_lock_state();
1398 /* wait for callbacks */ 1431 /* wait for callbacks */
1399 shutdown_callback_client(ses->se_client); 1432 nfsd4_set_callback_client(ses->se_client, NULL);
1433 nfs4_unlock_state();
1400 nfsd4_put_session(ses); 1434 nfsd4_put_session(ses);
1401 status = nfs_ok; 1435 status = nfs_ok;
1402out: 1436out:
@@ -1417,7 +1451,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1417 if (resp->opcnt != 1) 1451 if (resp->opcnt != 1)
1418 return nfserr_sequence_pos; 1452 return nfserr_sequence_pos;
1419 1453
1420 spin_lock(&sessionid_lock); 1454 spin_lock(&client_lock);
1421 status = nfserr_badsession; 1455 status = nfserr_badsession;
1422 session = find_in_sessionid_hashtbl(&seq->sessionid); 1456 session = find_in_sessionid_hashtbl(&seq->sessionid);
1423 if (!session) 1457 if (!session)
@@ -1456,23 +1490,47 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1456 cstate->slot = slot; 1490 cstate->slot = slot;
1457 cstate->session = session; 1491 cstate->session = session;
1458 1492
1459 /* Hold a session reference until done processing the compound:
1460 * nfsd4_put_session called only if the cstate slot is set.
1461 */
1462 nfsd4_get_session(session);
1463out: 1493out:
1464 spin_unlock(&sessionid_lock); 1494 /* Hold a session reference until done processing the compound. */
1465 /* Renew the clientid on success and on replay */
1466 if (cstate->session) { 1495 if (cstate->session) {
1467 nfs4_lock_state(); 1496 nfsd4_get_session(cstate->session);
1468 renew_client(session->se_client); 1497 atomic_inc(&session->se_client->cl_refcount);
1469 nfs4_unlock_state();
1470 } 1498 }
1499 spin_unlock(&client_lock);
1471 dprintk("%s: return %d\n", __func__, ntohl(status)); 1500 dprintk("%s: return %d\n", __func__, ntohl(status));
1472 return status; 1501 return status;
1473} 1502}
1474 1503
1475__be32 1504__be32
1505nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
1506{
1507 if (rc->rca_one_fs) {
1508 if (!cstate->current_fh.fh_dentry)
1509 return nfserr_nofilehandle;
1510 /*
1511 * We don't take advantage of the rca_one_fs case.
1512 * That's OK, it's optional, we can safely ignore it.
1513 */
1514 return nfs_ok;
1515 }
1516 nfs4_lock_state();
1517 if (is_client_expired(cstate->session->se_client)) {
1518 nfs4_unlock_state();
1519 /*
1520 * The following error isn't really legal.
1521 * But we only get here if the client just explicitly
1522 * destroyed the client. Surely it no longer cares what
1523 * error it gets back on an operation for the dead
1524 * client.
1525 */
1526 return nfserr_stale_clientid;
1527 }
1528 nfsd4_create_clid_dir(cstate->session->se_client);
1529 nfs4_unlock_state();
1530 return nfs_ok;
1531}
1532
1533__be32
1476nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1534nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1477 struct nfsd4_setclientid *setclid) 1535 struct nfsd4_setclientid *setclid)
1478{ 1536{
@@ -1631,9 +1689,8 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1631 if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 1689 if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
1632 status = nfserr_clid_inuse; 1690 status = nfserr_clid_inuse;
1633 else { 1691 else {
1634 /* XXX: We just turn off callbacks until we can handle 1692 atomic_set(&conf->cl_cb_set, 0);
1635 * change request correctly. */ 1693 nfsd4_probe_callback(conf, &unconf->cl_cb_conn);
1636 atomic_set(&conf->cl_cb_conn.cb_set, 0);
1637 expire_client(unconf); 1694 expire_client(unconf);
1638 status = nfs_ok; 1695 status = nfs_ok;
1639 1696
@@ -1667,7 +1724,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1667 } 1724 }
1668 move_to_confirmed(unconf); 1725 move_to_confirmed(unconf);
1669 conf = unconf; 1726 conf = unconf;
1670 nfsd4_probe_callback(conf); 1727 nfsd4_probe_callback(conf, &conf->cl_cb_conn);
1671 status = nfs_ok; 1728 status = nfs_ok;
1672 } 1729 }
1673 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm))) 1730 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm)))
@@ -1700,12 +1757,12 @@ alloc_init_file(struct inode *ino)
1700 INIT_LIST_HEAD(&fp->fi_hash); 1757 INIT_LIST_HEAD(&fp->fi_hash);
1701 INIT_LIST_HEAD(&fp->fi_stateids); 1758 INIT_LIST_HEAD(&fp->fi_stateids);
1702 INIT_LIST_HEAD(&fp->fi_delegations); 1759 INIT_LIST_HEAD(&fp->fi_delegations);
1703 spin_lock(&recall_lock);
1704 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
1705 spin_unlock(&recall_lock);
1706 fp->fi_inode = igrab(ino); 1760 fp->fi_inode = igrab(ino);
1707 fp->fi_id = current_fileid++; 1761 fp->fi_id = current_fileid++;
1708 fp->fi_had_conflict = false; 1762 fp->fi_had_conflict = false;
1763 spin_lock(&recall_lock);
1764 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
1765 spin_unlock(&recall_lock);
1709 return fp; 1766 return fp;
1710 } 1767 }
1711 return NULL; 1768 return NULL;
@@ -1827,7 +1884,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
1827 stp->st_stateowner = sop; 1884 stp->st_stateowner = sop;
1828 get_nfs4_file(fp); 1885 get_nfs4_file(fp);
1829 stp->st_file = fp; 1886 stp->st_file = fp;
1830 stp->st_stateid.si_boot = get_seconds(); 1887 stp->st_stateid.si_boot = boot_time;
1831 stp->st_stateid.si_stateownerid = sop->so_id; 1888 stp->st_stateid.si_stateownerid = sop->so_id;
1832 stp->st_stateid.si_fileid = fp->fi_id; 1889 stp->st_stateid.si_fileid = fp->fi_id;
1833 stp->st_stateid.si_generation = 0; 1890 stp->st_stateid.si_generation = 0;
@@ -2028,7 +2085,6 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
2028 * lock) we know the server hasn't removed the lease yet, we know 2085 * lock) we know the server hasn't removed the lease yet, we know
2029 * it's safe to take a reference: */ 2086 * it's safe to take a reference: */
2030 atomic_inc(&dp->dl_count); 2087 atomic_inc(&dp->dl_count);
2031 atomic_inc(&dp->dl_client->cl_count);
2032 2088
2033 spin_lock(&recall_lock); 2089 spin_lock(&recall_lock);
2034 list_add_tail(&dp->dl_recall_lru, &del_recall_lru); 2090 list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
@@ -2347,7 +2403,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2347{ 2403{
2348 struct nfs4_delegation *dp; 2404 struct nfs4_delegation *dp;
2349 struct nfs4_stateowner *sop = stp->st_stateowner; 2405 struct nfs4_stateowner *sop = stp->st_stateowner;
2350 struct nfs4_cb_conn *cb = &sop->so_client->cl_cb_conn; 2406 int cb_up = atomic_read(&sop->so_client->cl_cb_set);
2351 struct file_lock fl, *flp = &fl; 2407 struct file_lock fl, *flp = &fl;
2352 int status, flag = 0; 2408 int status, flag = 0;
2353 2409
@@ -2355,7 +2411,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2355 open->op_recall = 0; 2411 open->op_recall = 0;
2356 switch (open->op_claim_type) { 2412 switch (open->op_claim_type) {
2357 case NFS4_OPEN_CLAIM_PREVIOUS: 2413 case NFS4_OPEN_CLAIM_PREVIOUS:
2358 if (!atomic_read(&cb->cb_set)) 2414 if (!cb_up)
2359 open->op_recall = 1; 2415 open->op_recall = 1;
2360 flag = open->op_delegate_type; 2416 flag = open->op_delegate_type;
2361 if (flag == NFS4_OPEN_DELEGATE_NONE) 2417 if (flag == NFS4_OPEN_DELEGATE_NONE)
@@ -2366,7 +2422,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2366 * had the chance to reclaim theirs.... */ 2422 * had the chance to reclaim theirs.... */
2367 if (locks_in_grace()) 2423 if (locks_in_grace())
2368 goto out; 2424 goto out;
2369 if (!atomic_read(&cb->cb_set) || !sop->so_confirmed) 2425 if (!cb_up || !sop->so_confirmed)
2370 goto out; 2426 goto out;
2371 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 2427 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
2372 flag = NFS4_OPEN_DELEGATE_WRITE; 2428 flag = NFS4_OPEN_DELEGATE_WRITE;
@@ -2483,10 +2539,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2483 } 2539 }
2484 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); 2540 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
2485 2541
2486 if (nfsd4_has_session(&resp->cstate)) { 2542 if (nfsd4_has_session(&resp->cstate))
2487 open->op_stateowner->so_confirmed = 1; 2543 open->op_stateowner->so_confirmed = 1;
2488 nfsd4_create_clid_dir(open->op_stateowner->so_client);
2489 }
2490 2544
2491 /* 2545 /*
2492 * Attempt to hand out a delegation. No error return, because the 2546 * Attempt to hand out a delegation. No error return, because the
@@ -2537,7 +2591,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2537 renew_client(clp); 2591 renew_client(clp);
2538 status = nfserr_cb_path_down; 2592 status = nfserr_cb_path_down;
2539 if (!list_empty(&clp->cl_delegations) 2593 if (!list_empty(&clp->cl_delegations)
2540 && !atomic_read(&clp->cl_cb_conn.cb_set)) 2594 && !atomic_read(&clp->cl_cb_set))
2541 goto out; 2595 goto out;
2542 status = nfs_ok; 2596 status = nfs_ok;
2543out: 2597out:
@@ -2554,6 +2608,12 @@ nfsd4_end_grace(void)
2554 dprintk("NFSD: end of grace period\n"); 2608 dprintk("NFSD: end of grace period\n");
2555 nfsd4_recdir_purge_old(); 2609 nfsd4_recdir_purge_old();
2556 locks_end_grace(&nfsd4_manager); 2610 locks_end_grace(&nfsd4_manager);
2611 /*
2612 * Now that every NFSv4 client has had the chance to recover and
2613 * to see the (possibly new, possibly shorter) lease time, we
2614 * can safely set the next grace time to the current lease time:
2615 */
2616 nfsd4_grace = nfsd4_lease;
2557} 2617}
2558 2618
2559static time_t 2619static time_t
@@ -2563,15 +2623,17 @@ nfs4_laundromat(void)
2563 struct nfs4_stateowner *sop; 2623 struct nfs4_stateowner *sop;
2564 struct nfs4_delegation *dp; 2624 struct nfs4_delegation *dp;
2565 struct list_head *pos, *next, reaplist; 2625 struct list_head *pos, *next, reaplist;
2566 time_t cutoff = get_seconds() - NFSD_LEASE_TIME; 2626 time_t cutoff = get_seconds() - nfsd4_lease;
2567 time_t t, clientid_val = NFSD_LEASE_TIME; 2627 time_t t, clientid_val = nfsd4_lease;
2568 time_t u, test_val = NFSD_LEASE_TIME; 2628 time_t u, test_val = nfsd4_lease;
2569 2629
2570 nfs4_lock_state(); 2630 nfs4_lock_state();
2571 2631
2572 dprintk("NFSD: laundromat service - starting\n"); 2632 dprintk("NFSD: laundromat service - starting\n");
2573 if (locks_in_grace()) 2633 if (locks_in_grace())
2574 nfsd4_end_grace(); 2634 nfsd4_end_grace();
2635 INIT_LIST_HEAD(&reaplist);
2636 spin_lock(&client_lock);
2575 list_for_each_safe(pos, next, &client_lru) { 2637 list_for_each_safe(pos, next, &client_lru) {
2576 clp = list_entry(pos, struct nfs4_client, cl_lru); 2638 clp = list_entry(pos, struct nfs4_client, cl_lru);
2577 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 2639 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -2580,12 +2642,22 @@ nfs4_laundromat(void)
2580 clientid_val = t; 2642 clientid_val = t;
2581 break; 2643 break;
2582 } 2644 }
2645 if (atomic_read(&clp->cl_refcount)) {
2646 dprintk("NFSD: client in use (clientid %08x)\n",
2647 clp->cl_clientid.cl_id);
2648 continue;
2649 }
2650 unhash_client_locked(clp);
2651 list_add(&clp->cl_lru, &reaplist);
2652 }
2653 spin_unlock(&client_lock);
2654 list_for_each_safe(pos, next, &reaplist) {
2655 clp = list_entry(pos, struct nfs4_client, cl_lru);
2583 dprintk("NFSD: purging unused client (clientid %08x)\n", 2656 dprintk("NFSD: purging unused client (clientid %08x)\n",
2584 clp->cl_clientid.cl_id); 2657 clp->cl_clientid.cl_id);
2585 nfsd4_remove_clid_dir(clp); 2658 nfsd4_remove_clid_dir(clp);
2586 expire_client(clp); 2659 expire_client(clp);
2587 } 2660 }
2588 INIT_LIST_HEAD(&reaplist);
2589 spin_lock(&recall_lock); 2661 spin_lock(&recall_lock);
2590 list_for_each_safe(pos, next, &del_recall_lru) { 2662 list_for_each_safe(pos, next, &del_recall_lru) {
2591 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 2663 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
@@ -2605,7 +2677,7 @@ nfs4_laundromat(void)
2605 list_del_init(&dp->dl_recall_lru); 2677 list_del_init(&dp->dl_recall_lru);
2606 unhash_delegation(dp); 2678 unhash_delegation(dp);
2607 } 2679 }
2608 test_val = NFSD_LEASE_TIME; 2680 test_val = nfsd4_lease;
2609 list_for_each_safe(pos, next, &close_lru) { 2681 list_for_each_safe(pos, next, &close_lru) {
2610 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); 2682 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
2611 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) { 2683 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
@@ -2661,39 +2733,11 @@ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
2661static int 2733static int
2662STALE_STATEID(stateid_t *stateid) 2734STALE_STATEID(stateid_t *stateid)
2663{ 2735{
2664 if (time_after((unsigned long)boot_time, 2736 if (stateid->si_boot == boot_time)
2665 (unsigned long)stateid->si_boot)) { 2737 return 0;
2666 dprintk("NFSD: stale stateid " STATEID_FMT "!\n", 2738 dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
2667 STATEID_VAL(stateid));
2668 return 1;
2669 }
2670 return 0;
2671}
2672
2673static int
2674EXPIRED_STATEID(stateid_t *stateid)
2675{
2676 if (time_before((unsigned long)boot_time,
2677 ((unsigned long)stateid->si_boot)) &&
2678 time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) {
2679 dprintk("NFSD: expired stateid " STATEID_FMT "!\n",
2680 STATEID_VAL(stateid));
2681 return 1;
2682 }
2683 return 0;
2684}
2685
2686static __be32
2687stateid_error_map(stateid_t *stateid)
2688{
2689 if (STALE_STATEID(stateid))
2690 return nfserr_stale_stateid;
2691 if (EXPIRED_STATEID(stateid))
2692 return nfserr_expired;
2693
2694 dprintk("NFSD: bad stateid " STATEID_FMT "!\n",
2695 STATEID_VAL(stateid)); 2739 STATEID_VAL(stateid));
2696 return nfserr_bad_stateid; 2740 return 1;
2697} 2741}
2698 2742
2699static inline int 2743static inline int
@@ -2817,10 +2861,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2817 status = nfserr_bad_stateid; 2861 status = nfserr_bad_stateid;
2818 if (is_delegation_stateid(stateid)) { 2862 if (is_delegation_stateid(stateid)) {
2819 dp = find_delegation_stateid(ino, stateid); 2863 dp = find_delegation_stateid(ino, stateid);
2820 if (!dp) { 2864 if (!dp)
2821 status = stateid_error_map(stateid);
2822 goto out; 2865 goto out;
2823 }
2824 status = check_stateid_generation(stateid, &dp->dl_stateid, 2866 status = check_stateid_generation(stateid, &dp->dl_stateid,
2825 flags); 2867 flags);
2826 if (status) 2868 if (status)
@@ -2833,10 +2875,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2833 *filpp = dp->dl_vfs_file; 2875 *filpp = dp->dl_vfs_file;
2834 } else { /* open or lock stateid */ 2876 } else { /* open or lock stateid */
2835 stp = find_stateid(stateid, flags); 2877 stp = find_stateid(stateid, flags);
2836 if (!stp) { 2878 if (!stp)
2837 status = stateid_error_map(stateid);
2838 goto out; 2879 goto out;
2839 }
2840 if (nfs4_check_fh(current_fh, stp)) 2880 if (nfs4_check_fh(current_fh, stp))
2841 goto out; 2881 goto out;
2842 if (!stp->st_stateowner->so_confirmed) 2882 if (!stp->st_stateowner->so_confirmed)
@@ -2908,7 +2948,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
2908 */ 2948 */
2909 sop = search_close_lru(stateid->si_stateownerid, flags); 2949 sop = search_close_lru(stateid->si_stateownerid, flags);
2910 if (sop == NULL) 2950 if (sop == NULL)
2911 return stateid_error_map(stateid); 2951 return nfserr_bad_stateid;
2912 *sopp = sop; 2952 *sopp = sop;
2913 goto check_replay; 2953 goto check_replay;
2914 } 2954 }
@@ -3175,10 +3215,8 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3175 if (!is_delegation_stateid(stateid)) 3215 if (!is_delegation_stateid(stateid))
3176 goto out; 3216 goto out;
3177 dp = find_delegation_stateid(inode, stateid); 3217 dp = find_delegation_stateid(inode, stateid);
3178 if (!dp) { 3218 if (!dp)
3179 status = stateid_error_map(stateid);
3180 goto out; 3219 goto out;
3181 }
3182 status = check_stateid_generation(stateid, &dp->dl_stateid, flags); 3220 status = check_stateid_generation(stateid, &dp->dl_stateid, flags);
3183 if (status) 3221 if (status)
3184 goto out; 3222 goto out;
@@ -3404,7 +3442,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3404 stp->st_stateowner = sop; 3442 stp->st_stateowner = sop;
3405 get_nfs4_file(fp); 3443 get_nfs4_file(fp);
3406 stp->st_file = fp; 3444 stp->st_file = fp;
3407 stp->st_stateid.si_boot = get_seconds(); 3445 stp->st_stateid.si_boot = boot_time;
3408 stp->st_stateid.si_stateownerid = sop->so_id; 3446 stp->st_stateid.si_stateownerid = sop->so_id;
3409 stp->st_stateid.si_fileid = fp->fi_id; 3447 stp->st_stateid.si_fileid = fp->fi_id;
3410 stp->st_stateid.si_generation = 0; 3448 stp->st_stateid.si_generation = 0;
@@ -3976,12 +4014,6 @@ nfsd4_load_reboot_recovery_data(void)
3976 printk("NFSD: Failure reading reboot recovery data\n"); 4014 printk("NFSD: Failure reading reboot recovery data\n");
3977} 4015}
3978 4016
3979unsigned long
3980get_nfs4_grace_period(void)
3981{
3982 return max(user_lease_time, lease_time) * HZ;
3983}
3984
3985/* 4017/*
3986 * Since the lifetime of a delegation isn't limited to that of an open, a 4018 * Since the lifetime of a delegation isn't limited to that of an open, a
3987 * client may quite reasonably hang on to a delegation as long as it has 4019 * client may quite reasonably hang on to a delegation as long as it has
@@ -4008,20 +4040,27 @@ set_max_delegations(void)
4008static int 4040static int
4009__nfs4_state_start(void) 4041__nfs4_state_start(void)
4010{ 4042{
4011 unsigned long grace_time; 4043 int ret;
4012 4044
4013 boot_time = get_seconds(); 4045 boot_time = get_seconds();
4014 grace_time = get_nfs4_grace_period();
4015 lease_time = user_lease_time;
4016 locks_start_grace(&nfsd4_manager); 4046 locks_start_grace(&nfsd4_manager);
4017 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4047 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4018 grace_time/HZ); 4048 nfsd4_grace);
4049 ret = set_callback_cred();
4050 if (ret)
4051 return -ENOMEM;
4019 laundry_wq = create_singlethread_workqueue("nfsd4"); 4052 laundry_wq = create_singlethread_workqueue("nfsd4");
4020 if (laundry_wq == NULL) 4053 if (laundry_wq == NULL)
4021 return -ENOMEM; 4054 return -ENOMEM;
4022 queue_delayed_work(laundry_wq, &laundromat_work, grace_time); 4055 ret = nfsd4_create_callback_queue();
4056 if (ret)
4057 goto out_free_laundry;
4058 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ);
4023 set_max_delegations(); 4059 set_max_delegations();
4024 return set_callback_cred(); 4060 return 0;
4061out_free_laundry:
4062 destroy_workqueue(laundry_wq);
4063 return ret;
4025} 4064}
4026 4065
4027int 4066int
@@ -4039,12 +4078,6 @@ nfs4_state_start(void)
4039 return 0; 4078 return 0;
4040} 4079}
4041 4080
4042time_t
4043nfs4_lease_time(void)
4044{
4045 return lease_time;
4046}
4047
4048static void 4081static void
4049__nfs4_state_shutdown(void) 4082__nfs4_state_shutdown(void)
4050{ 4083{
@@ -4089,6 +4122,7 @@ nfs4_state_shutdown(void)
4089 nfs4_lock_state(); 4122 nfs4_lock_state();
4090 nfs4_release_reclaim(); 4123 nfs4_release_reclaim();
4091 __nfs4_state_shutdown(); 4124 __nfs4_state_shutdown();
4125 nfsd4_destroy_callback_queue();
4092 nfs4_unlock_state(); 4126 nfs4_unlock_state();
4093} 4127}
4094 4128
@@ -4128,21 +4162,3 @@ nfs4_recoverydir(void)
4128{ 4162{
4129 return user_recovery_dirname; 4163 return user_recovery_dirname;
4130} 4164}
4131
4132/*
4133 * Called when leasetime is changed.
4134 *
4135 * The only way the protocol gives us to handle on-the-fly lease changes is to
4136 * simulate a reboot. Instead of doing that, we just wait till the next time
4137 * we start to register any changes in lease time. If the administrator
4138 * really wants to change the lease time *now*, they can go ahead and bring
4139 * nfsd down and then back up again after changing the lease time.
4140 *
4141 * user_lease_time is protected by nfsd_mutex since it's only really accessed
4142 * when nfsd is starting
4143 */
4144void
4145nfs4_reset_lease(time_t leasetime)
4146{
4147 user_lease_time = leasetime;
4148}