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.c243
1 files changed, 145 insertions, 98 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index fbd18c3074bb..d98d0213285d 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -230,7 +230,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
230 dp->dl_client = clp; 230 dp->dl_client = clp;
231 get_nfs4_file(fp); 231 get_nfs4_file(fp);
232 dp->dl_file = fp; 232 dp->dl_file = fp;
233 nfs4_file_get_access(fp, O_RDONLY); 233 dp->dl_vfs_file = find_readable_file(fp);
234 get_file(dp->dl_vfs_file);
234 dp->dl_flock = NULL; 235 dp->dl_flock = NULL;
235 dp->dl_type = type; 236 dp->dl_type = type;
236 dp->dl_stateid.si_boot = boot_time; 237 dp->dl_stateid.si_boot = boot_time;
@@ -252,6 +253,7 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
252 if (atomic_dec_and_test(&dp->dl_count)) { 253 if (atomic_dec_and_test(&dp->dl_count)) {
253 dprintk("NFSD: freeing dp %p\n",dp); 254 dprintk("NFSD: freeing dp %p\n",dp);
254 put_nfs4_file(dp->dl_file); 255 put_nfs4_file(dp->dl_file);
256 fput(dp->dl_vfs_file);
255 kmem_cache_free(deleg_slab, dp); 257 kmem_cache_free(deleg_slab, dp);
256 num_delegations--; 258 num_delegations--;
257 } 259 }
@@ -265,12 +267,10 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
265static void 267static void
266nfs4_close_delegation(struct nfs4_delegation *dp) 268nfs4_close_delegation(struct nfs4_delegation *dp)
267{ 269{
268 struct file *filp = find_readable_file(dp->dl_file);
269
270 dprintk("NFSD: close_delegation dp %p\n",dp); 270 dprintk("NFSD: close_delegation dp %p\n",dp);
271 /* XXX: do we even need this check?: */
271 if (dp->dl_flock) 272 if (dp->dl_flock)
272 vfs_setlease(filp, F_UNLCK, &dp->dl_flock); 273 vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock);
273 nfs4_file_put_access(dp->dl_file, O_RDONLY);
274} 274}
275 275
276/* Called under the state lock. */ 276/* Called under the state lock. */
@@ -642,6 +642,7 @@ static void nfsd4_conn_lost(struct svc_xpt_user *u)
642 free_conn(c); 642 free_conn(c);
643 } 643 }
644 spin_unlock(&clp->cl_lock); 644 spin_unlock(&clp->cl_lock);
645 nfsd4_probe_callback(clp);
645} 646}
646 647
647static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags) 648static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
@@ -679,15 +680,12 @@ static int nfsd4_register_conn(struct nfsd4_conn *conn)
679 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); 680 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
680} 681}
681 682
682static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) 683static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir)
683{ 684{
684 struct nfsd4_conn *conn; 685 struct nfsd4_conn *conn;
685 u32 flags = NFS4_CDFC4_FORE;
686 int ret; 686 int ret;
687 687
688 if (ses->se_flags & SESSION4_BACK_CHAN) 688 conn = alloc_conn(rqstp, dir);
689 flags |= NFS4_CDFC4_BACK;
690 conn = alloc_conn(rqstp, flags);
691 if (!conn) 689 if (!conn)
692 return nfserr_jukebox; 690 return nfserr_jukebox;
693 nfsd4_hash_conn(conn, ses); 691 nfsd4_hash_conn(conn, ses);
@@ -698,6 +696,17 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
698 return nfs_ok; 696 return nfs_ok;
699} 697}
700 698
699static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses)
700{
701 u32 dir = NFS4_CDFC4_FORE;
702
703 if (ses->se_flags & SESSION4_BACK_CHAN)
704 dir |= NFS4_CDFC4_BACK;
705
706 return nfsd4_new_conn(rqstp, ses, dir);
707}
708
709/* must be called under client_lock */
701static void nfsd4_del_conns(struct nfsd4_session *s) 710static void nfsd4_del_conns(struct nfsd4_session *s)
702{ 711{
703 struct nfs4_client *clp = s->se_client; 712 struct nfs4_client *clp = s->se_client;
@@ -749,6 +758,8 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
749 */ 758 */
750 slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached); 759 slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached);
751 numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs); 760 numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs);
761 if (numslots < 1)
762 return NULL;
752 763
753 new = alloc_session(slotsize, numslots); 764 new = alloc_session(slotsize, numslots);
754 if (!new) { 765 if (!new) {
@@ -769,25 +780,30 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
769 idx = hash_sessionid(&new->se_sessionid); 780 idx = hash_sessionid(&new->se_sessionid);
770 spin_lock(&client_lock); 781 spin_lock(&client_lock);
771 list_add(&new->se_hash, &sessionid_hashtbl[idx]); 782 list_add(&new->se_hash, &sessionid_hashtbl[idx]);
783 spin_lock(&clp->cl_lock);
772 list_add(&new->se_perclnt, &clp->cl_sessions); 784 list_add(&new->se_perclnt, &clp->cl_sessions);
785 spin_unlock(&clp->cl_lock);
773 spin_unlock(&client_lock); 786 spin_unlock(&client_lock);
774 787
775 status = nfsd4_new_conn(rqstp, new); 788 status = nfsd4_new_conn_from_crses(rqstp, new);
776 /* whoops: benny points out, status is ignored! (err, or bogus) */ 789 /* whoops: benny points out, status is ignored! (err, or bogus) */
777 if (status) { 790 if (status) {
778 free_session(&new->se_ref); 791 free_session(&new->se_ref);
779 return NULL; 792 return NULL;
780 } 793 }
781 if (!clp->cl_cb_session && (cses->flags & SESSION4_BACK_CHAN)) { 794 if (cses->flags & SESSION4_BACK_CHAN) {
782 struct sockaddr *sa = svc_addr(rqstp); 795 struct sockaddr *sa = svc_addr(rqstp);
783 796 /*
784 clp->cl_cb_session = new; 797 * This is a little silly; with sessions there's no real
785 clp->cl_cb_conn.cb_xprt = rqstp->rq_xprt; 798 * use for the callback address. Use the peer address
786 svc_xprt_get(rqstp->rq_xprt); 799 * as a reasonable default for now, but consider fixing
800 * the rpc client not to require an address in the
801 * future:
802 */
787 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa); 803 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
788 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa); 804 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
789 nfsd4_probe_callback(clp);
790 } 805 }
806 nfsd4_probe_callback(clp);
791 return new; 807 return new;
792} 808}
793 809
@@ -817,7 +833,9 @@ static void
817unhash_session(struct nfsd4_session *ses) 833unhash_session(struct nfsd4_session *ses)
818{ 834{
819 list_del(&ses->se_hash); 835 list_del(&ses->se_hash);
836 spin_lock(&ses->se_client->cl_lock);
820 list_del(&ses->se_perclnt); 837 list_del(&ses->se_perclnt);
838 spin_unlock(&ses->se_client->cl_lock);
821} 839}
822 840
823/* must be called under the client_lock */ 841/* must be called under the client_lock */
@@ -923,8 +941,10 @@ unhash_client_locked(struct nfs4_client *clp)
923 941
924 mark_client_expired(clp); 942 mark_client_expired(clp);
925 list_del(&clp->cl_lru); 943 list_del(&clp->cl_lru);
944 spin_lock(&clp->cl_lock);
926 list_for_each_entry(ses, &clp->cl_sessions, se_perclnt) 945 list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
927 list_del_init(&ses->se_hash); 946 list_del_init(&ses->se_hash);
947 spin_unlock(&clp->cl_lock);
928} 948}
929 949
930static void 950static void
@@ -1051,12 +1071,13 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1051 1071
1052 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 1072 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
1053 atomic_set(&clp->cl_refcount, 0); 1073 atomic_set(&clp->cl_refcount, 0);
1054 atomic_set(&clp->cl_cb_set, 0); 1074 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
1055 INIT_LIST_HEAD(&clp->cl_idhash); 1075 INIT_LIST_HEAD(&clp->cl_idhash);
1056 INIT_LIST_HEAD(&clp->cl_strhash); 1076 INIT_LIST_HEAD(&clp->cl_strhash);
1057 INIT_LIST_HEAD(&clp->cl_openowners); 1077 INIT_LIST_HEAD(&clp->cl_openowners);
1058 INIT_LIST_HEAD(&clp->cl_delegations); 1078 INIT_LIST_HEAD(&clp->cl_delegations);
1059 INIT_LIST_HEAD(&clp->cl_lru); 1079 INIT_LIST_HEAD(&clp->cl_lru);
1080 INIT_LIST_HEAD(&clp->cl_callbacks);
1060 spin_lock_init(&clp->cl_lock); 1081 spin_lock_init(&clp->cl_lock);
1061 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); 1082 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
1062 clp->cl_time = get_seconds(); 1083 clp->cl_time = get_seconds();
@@ -1132,54 +1153,55 @@ find_unconfirmed_client(clientid_t *clid)
1132 return NULL; 1153 return NULL;
1133} 1154}
1134 1155
1135/* 1156static bool clp_used_exchangeid(struct nfs4_client *clp)
1136 * Return 1 iff clp's clientid establishment method matches the use_exchange_id
1137 * parameter. Matching is based on the fact the at least one of the
1138 * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1
1139 *
1140 * FIXME: we need to unify the clientid namespaces for nfsv4.x
1141 * and correctly deal with client upgrade/downgrade in EXCHANGE_ID
1142 * and SET_CLIENTID{,_CONFIRM}
1143 */
1144static inline int
1145match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id)
1146{ 1157{
1147 bool has_exchange_flags = (clp->cl_exchange_flags != 0); 1158 return clp->cl_exchange_flags != 0;
1148 return use_exchange_id == has_exchange_flags; 1159}
1149}
1150 1160
1151static struct nfs4_client * 1161static struct nfs4_client *
1152find_confirmed_client_by_str(const char *dname, unsigned int hashval, 1162find_confirmed_client_by_str(const char *dname, unsigned int hashval)
1153 bool use_exchange_id)
1154{ 1163{
1155 struct nfs4_client *clp; 1164 struct nfs4_client *clp;
1156 1165
1157 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { 1166 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
1158 if (same_name(clp->cl_recdir, dname) && 1167 if (same_name(clp->cl_recdir, dname))
1159 match_clientid_establishment(clp, use_exchange_id))
1160 return clp; 1168 return clp;
1161 } 1169 }
1162 return NULL; 1170 return NULL;
1163} 1171}
1164 1172
1165static struct nfs4_client * 1173static struct nfs4_client *
1166find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, 1174find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
1167 bool use_exchange_id)
1168{ 1175{
1169 struct nfs4_client *clp; 1176 struct nfs4_client *clp;
1170 1177
1171 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { 1178 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
1172 if (same_name(clp->cl_recdir, dname) && 1179 if (same_name(clp->cl_recdir, dname))
1173 match_clientid_establishment(clp, use_exchange_id))
1174 return clp; 1180 return clp;
1175 } 1181 }
1176 return NULL; 1182 return NULL;
1177} 1183}
1178 1184
1185static void rpc_svcaddr2sockaddr(struct sockaddr *sa, unsigned short family, union svc_addr_u *svcaddr)
1186{
1187 switch (family) {
1188 case AF_INET:
1189 ((struct sockaddr_in *)sa)->sin_family = AF_INET;
1190 ((struct sockaddr_in *)sa)->sin_addr = svcaddr->addr;
1191 return;
1192 case AF_INET6:
1193 ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6;
1194 ((struct sockaddr_in6 *)sa)->sin6_addr = svcaddr->addr6;
1195 return;
1196 }
1197}
1198
1179static void 1199static void
1180gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid) 1200gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
1181{ 1201{
1182 struct nfs4_cb_conn *conn = &clp->cl_cb_conn; 1202 struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
1203 struct sockaddr *sa = svc_addr(rqstp);
1204 u32 scopeid = rpc_get_scope_id(sa);
1183 unsigned short expected_family; 1205 unsigned short expected_family;
1184 1206
1185 /* Currently, we only support tcp and tcp6 for the callback channel */ 1207 /* Currently, we only support tcp and tcp6 for the callback channel */
@@ -1205,6 +1227,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid)
1205 1227
1206 conn->cb_prog = se->se_callback_prog; 1228 conn->cb_prog = se->se_callback_prog;
1207 conn->cb_ident = se->se_callback_ident; 1229 conn->cb_ident = se->se_callback_ident;
1230 rpc_svcaddr2sockaddr((struct sockaddr *)&conn->cb_saddr, expected_family, &rqstp->rq_daddr);
1208 return; 1231 return;
1209out_err: 1232out_err:
1210 conn->cb_addr.ss_family = AF_UNSPEC; 1233 conn->cb_addr.ss_family = AF_UNSPEC;
@@ -1344,7 +1367,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1344 case SP4_NONE: 1367 case SP4_NONE:
1345 break; 1368 break;
1346 case SP4_SSV: 1369 case SP4_SSV:
1347 return nfserr_encr_alg_unsupp; 1370 return nfserr_serverfault;
1348 default: 1371 default:
1349 BUG(); /* checked by xdr code */ 1372 BUG(); /* checked by xdr code */
1350 case SP4_MACH_CRED: 1373 case SP4_MACH_CRED:
@@ -1361,8 +1384,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1361 nfs4_lock_state(); 1384 nfs4_lock_state();
1362 status = nfs_ok; 1385 status = nfs_ok;
1363 1386
1364 conf = find_confirmed_client_by_str(dname, strhashval, true); 1387 conf = find_confirmed_client_by_str(dname, strhashval);
1365 if (conf) { 1388 if (conf) {
1389 if (!clp_used_exchangeid(conf)) {
1390 status = nfserr_clid_inuse; /* XXX: ? */
1391 goto out;
1392 }
1366 if (!same_verf(&verf, &conf->cl_verifier)) { 1393 if (!same_verf(&verf, &conf->cl_verifier)) {
1367 /* 18.35.4 case 8 */ 1394 /* 18.35.4 case 8 */
1368 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1395 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
@@ -1403,7 +1430,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1403 goto out; 1430 goto out;
1404 } 1431 }
1405 1432
1406 unconf = find_unconfirmed_client_by_str(dname, strhashval, true); 1433 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1407 if (unconf) { 1434 if (unconf) {
1408 /* 1435 /*
1409 * Possible retry or client restart. Per 18.35.4 case 4, 1436 * Possible retry or client restart. Per 18.35.4 case 4,
@@ -1560,6 +1587,8 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1560 status = nfs_ok; 1587 status = nfs_ok;
1561 memcpy(cr_ses->sessionid.data, new->se_sessionid.data, 1588 memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
1562 NFS4_MAX_SESSIONID_LEN); 1589 NFS4_MAX_SESSIONID_LEN);
1590 memcpy(&cr_ses->fore_channel, &new->se_fchannel,
1591 sizeof(struct nfsd4_channel_attrs));
1563 cs_slot->sl_seqid++; 1592 cs_slot->sl_seqid++;
1564 cr_ses->seqid = cs_slot->sl_seqid; 1593 cr_ses->seqid = cs_slot->sl_seqid;
1565 1594
@@ -1581,6 +1610,45 @@ static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
1581 return argp->opcnt == resp->opcnt; 1610 return argp->opcnt == resp->opcnt;
1582} 1611}
1583 1612
1613static __be32 nfsd4_map_bcts_dir(u32 *dir)
1614{
1615 switch (*dir) {
1616 case NFS4_CDFC4_FORE:
1617 case NFS4_CDFC4_BACK:
1618 return nfs_ok;
1619 case NFS4_CDFC4_FORE_OR_BOTH:
1620 case NFS4_CDFC4_BACK_OR_BOTH:
1621 *dir = NFS4_CDFC4_BOTH;
1622 return nfs_ok;
1623 };
1624 return nfserr_inval;
1625}
1626
1627__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1628 struct nfsd4_compound_state *cstate,
1629 struct nfsd4_bind_conn_to_session *bcts)
1630{
1631 __be32 status;
1632
1633 if (!nfsd4_last_compound_op(rqstp))
1634 return nfserr_not_only_op;
1635 spin_lock(&client_lock);
1636 cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid);
1637 /* Sorta weird: we only need the refcnt'ing because new_conn acquires
1638 * client_lock iself: */
1639 if (cstate->session) {
1640 nfsd4_get_session(cstate->session);
1641 atomic_inc(&cstate->session->se_client->cl_refcount);
1642 }
1643 spin_unlock(&client_lock);
1644 if (!cstate->session)
1645 return nfserr_badsession;
1646
1647 status = nfsd4_map_bcts_dir(&bcts->dir);
1648 nfsd4_new_conn(rqstp, cstate->session, bcts->dir);
1649 return nfs_ok;
1650}
1651
1584static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) 1652static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
1585{ 1653{
1586 if (!session) 1654 if (!session)
@@ -1619,8 +1687,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
1619 spin_unlock(&client_lock); 1687 spin_unlock(&client_lock);
1620 1688
1621 nfs4_lock_state(); 1689 nfs4_lock_state();
1622 /* wait for callbacks */ 1690 nfsd4_probe_callback_sync(ses->se_client);
1623 nfsd4_shutdown_callback(ses->se_client);
1624 nfs4_unlock_state(); 1691 nfs4_unlock_state();
1625 1692
1626 nfsd4_del_conns(ses); 1693 nfsd4_del_conns(ses);
@@ -1733,8 +1800,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1733out: 1800out:
1734 /* Hold a session reference until done processing the compound. */ 1801 /* Hold a session reference until done processing the compound. */
1735 if (cstate->session) { 1802 if (cstate->session) {
1803 struct nfs4_client *clp = session->se_client;
1804
1736 nfsd4_get_session(cstate->session); 1805 nfsd4_get_session(cstate->session);
1737 atomic_inc(&session->se_client->cl_refcount); 1806 atomic_inc(&clp->cl_refcount);
1807 if (clp->cl_cb_state == NFSD4_CB_DOWN)
1808 seq->status_flags |= SEQ4_STATUS_CB_PATH_DOWN;
1738 } 1809 }
1739 kfree(conn); 1810 kfree(conn);
1740 spin_unlock(&client_lock); 1811 spin_unlock(&client_lock);
@@ -1775,7 +1846,6 @@ __be32
1775nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1846nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1776 struct nfsd4_setclientid *setclid) 1847 struct nfsd4_setclientid *setclid)
1777{ 1848{
1778 struct sockaddr *sa = svc_addr(rqstp);
1779 struct xdr_netobj clname = { 1849 struct xdr_netobj clname = {
1780 .len = setclid->se_namelen, 1850 .len = setclid->se_namelen,
1781 .data = setclid->se_name, 1851 .data = setclid->se_name,
@@ -1801,10 +1871,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1801 strhashval = clientstr_hashval(dname); 1871 strhashval = clientstr_hashval(dname);
1802 1872
1803 nfs4_lock_state(); 1873 nfs4_lock_state();
1804 conf = find_confirmed_client_by_str(dname, strhashval, false); 1874 conf = find_confirmed_client_by_str(dname, strhashval);
1805 if (conf) { 1875 if (conf) {
1806 /* RFC 3530 14.2.33 CASE 0: */ 1876 /* RFC 3530 14.2.33 CASE 0: */
1807 status = nfserr_clid_inuse; 1877 status = nfserr_clid_inuse;
1878 if (clp_used_exchangeid(conf))
1879 goto out;
1808 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { 1880 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
1809 char addr_str[INET6_ADDRSTRLEN]; 1881 char addr_str[INET6_ADDRSTRLEN];
1810 rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str, 1882 rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str,
@@ -1819,7 +1891,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1819 * has a description of SETCLIENTID request processing consisting 1891 * has a description of SETCLIENTID request processing consisting
1820 * of 5 bullet points, labeled as CASE0 - CASE4 below. 1892 * of 5 bullet points, labeled as CASE0 - CASE4 below.
1821 */ 1893 */
1822 unconf = find_unconfirmed_client_by_str(dname, strhashval, false); 1894 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1823 status = nfserr_resource; 1895 status = nfserr_resource;
1824 if (!conf) { 1896 if (!conf) {
1825 /* 1897 /*
@@ -1876,7 +1948,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1876 * for consistent minorversion use throughout: 1948 * for consistent minorversion use throughout:
1877 */ 1949 */
1878 new->cl_minorversion = 0; 1950 new->cl_minorversion = 0;
1879 gen_callback(new, setclid, rpc_get_scope_id(sa)); 1951 gen_callback(new, setclid, rqstp);
1880 add_to_unconfirmed(new, strhashval); 1952 add_to_unconfirmed(new, strhashval);
1881 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; 1953 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
1882 setclid->se_clientid.cl_id = new->cl_clientid.cl_id; 1954 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
@@ -1935,7 +2007,6 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1935 if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 2007 if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
1936 status = nfserr_clid_inuse; 2008 status = nfserr_clid_inuse;
1937 else { 2009 else {
1938 atomic_set(&conf->cl_cb_set, 0);
1939 nfsd4_change_callback(conf, &unconf->cl_cb_conn); 2010 nfsd4_change_callback(conf, &unconf->cl_cb_conn);
1940 nfsd4_probe_callback(conf); 2011 nfsd4_probe_callback(conf);
1941 expire_client(unconf); 2012 expire_client(unconf);
@@ -1964,7 +2035,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1964 unsigned int hash = 2035 unsigned int hash =
1965 clientstr_hashval(unconf->cl_recdir); 2036 clientstr_hashval(unconf->cl_recdir);
1966 conf = find_confirmed_client_by_str(unconf->cl_recdir, 2037 conf = find_confirmed_client_by_str(unconf->cl_recdir,
1967 hash, false); 2038 hash);
1968 if (conf) { 2039 if (conf) {
1969 nfsd4_remove_clid_dir(conf); 2040 nfsd4_remove_clid_dir(conf);
1970 expire_client(conf); 2041 expire_client(conf);
@@ -2300,41 +2371,6 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
2300 nfsd4_cb_recall(dp); 2371 nfsd4_cb_recall(dp);
2301} 2372}
2302 2373
2303/*
2304 * The file_lock is being reapd.
2305 *
2306 * Called by locks_free_lock() with lock_flocks() held.
2307 */
2308static
2309void nfsd_release_deleg_cb(struct file_lock *fl)
2310{
2311 struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
2312
2313 dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d\n", fl,dp, atomic_read(&dp->dl_count));
2314
2315 if (!(fl->fl_flags & FL_LEASE) || !dp)
2316 return;
2317 dp->dl_flock = NULL;
2318}
2319
2320/*
2321 * Called from setlease() with lock_flocks() held
2322 */
2323static
2324int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
2325{
2326 struct nfs4_delegation *onlistd =
2327 (struct nfs4_delegation *)onlist->fl_owner;
2328 struct nfs4_delegation *tryd =
2329 (struct nfs4_delegation *)try->fl_owner;
2330
2331 if (onlist->fl_lmops != try->fl_lmops)
2332 return 0;
2333
2334 return onlistd->dl_client == tryd->dl_client;
2335}
2336
2337
2338static 2374static
2339int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) 2375int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2340{ 2376{
@@ -2346,8 +2382,6 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2346 2382
2347static const struct lock_manager_operations nfsd_lease_mng_ops = { 2383static const struct lock_manager_operations nfsd_lease_mng_ops = {
2348 .fl_break = nfsd_break_deleg_cb, 2384 .fl_break = nfsd_break_deleg_cb,
2349 .fl_release_private = nfsd_release_deleg_cb,
2350 .fl_mylease = nfsd_same_client_deleg_cb,
2351 .fl_change = nfsd_change_deleg_cb, 2385 .fl_change = nfsd_change_deleg_cb,
2352}; 2386};
2353 2387
@@ -2514,8 +2548,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
2514 if (!fp->fi_fds[oflag]) { 2548 if (!fp->fi_fds[oflag]) {
2515 status = nfsd_open(rqstp, cur_fh, S_IFREG, access, 2549 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
2516 &fp->fi_fds[oflag]); 2550 &fp->fi_fds[oflag]);
2517 if (status == nfserr_dropit)
2518 status = nfserr_jukebox;
2519 if (status) 2551 if (status)
2520 return status; 2552 return status;
2521 } 2553 }
@@ -2596,6 +2628,19 @@ nfs4_set_claim_prev(struct nfsd4_open *open)
2596 open->op_stateowner->so_client->cl_firststate = 1; 2628 open->op_stateowner->so_client->cl_firststate = 1;
2597} 2629}
2598 2630
2631/* Should we give out recallable state?: */
2632static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
2633{
2634 if (clp->cl_cb_state == NFSD4_CB_UP)
2635 return true;
2636 /*
2637 * In the sessions case, since we don't have to establish a
2638 * separate connection for callbacks, we assume it's OK
2639 * until we hear otherwise:
2640 */
2641 return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
2642}
2643
2599/* 2644/*
2600 * Attempt to hand out a delegation. 2645 * Attempt to hand out a delegation.
2601 */ 2646 */
@@ -2604,10 +2649,11 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2604{ 2649{
2605 struct nfs4_delegation *dp; 2650 struct nfs4_delegation *dp;
2606 struct nfs4_stateowner *sop = stp->st_stateowner; 2651 struct nfs4_stateowner *sop = stp->st_stateowner;
2607 int cb_up = atomic_read(&sop->so_client->cl_cb_set); 2652 int cb_up;
2608 struct file_lock *fl; 2653 struct file_lock *fl;
2609 int status, flag = 0; 2654 int status, flag = 0;
2610 2655
2656 cb_up = nfsd4_cb_channel_good(sop->so_client);
2611 flag = NFS4_OPEN_DELEGATE_NONE; 2657 flag = NFS4_OPEN_DELEGATE_NONE;
2612 open->op_recall = 0; 2658 open->op_recall = 0;
2613 switch (open->op_claim_type) { 2659 switch (open->op_claim_type) {
@@ -2655,7 +2701,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2655 dp->dl_flock = fl; 2701 dp->dl_flock = fl;
2656 2702
2657 /* vfs_setlease checks to see if delegation should be handed out. 2703 /* vfs_setlease checks to see if delegation should be handed out.
2658 * the lock_manager callbacks fl_mylease and fl_change are used 2704 * the lock_manager callback fl_change is used
2659 */ 2705 */
2660 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { 2706 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
2661 dprintk("NFSD: setlease failed [%d], no delegation\n", status); 2707 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
@@ -2794,7 +2840,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2794 renew_client(clp); 2840 renew_client(clp);
2795 status = nfserr_cb_path_down; 2841 status = nfserr_cb_path_down;
2796 if (!list_empty(&clp->cl_delegations) 2842 if (!list_empty(&clp->cl_delegations)
2797 && !atomic_read(&clp->cl_cb_set)) 2843 && clp->cl_cb_state != NFSD4_CB_UP)
2798 goto out; 2844 goto out;
2799 status = nfs_ok; 2845 status = nfs_ok;
2800out: 2846out:
@@ -3081,9 +3127,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3081 if (status) 3127 if (status)
3082 goto out; 3128 goto out;
3083 renew_client(dp->dl_client); 3129 renew_client(dp->dl_client);
3084 if (filpp) 3130 if (filpp) {
3085 *filpp = find_readable_file(dp->dl_file); 3131 *filpp = find_readable_file(dp->dl_file);
3086 BUG_ON(!*filpp); 3132 BUG_ON(!*filpp);
3133 }
3087 } else { /* open or lock stateid */ 3134 } else { /* open or lock stateid */
3088 stp = find_stateid(stateid, flags); 3135 stp = find_stateid(stateid, flags);
3089 if (!stp) 3136 if (!stp)
@@ -4107,7 +4154,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
4107 unsigned int strhashval = clientstr_hashval(name); 4154 unsigned int strhashval = clientstr_hashval(name);
4108 struct nfs4_client *clp; 4155 struct nfs4_client *clp;
4109 4156
4110 clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id); 4157 clp = find_confirmed_client_by_str(name, strhashval);
4111 return clp ? 1 : 0; 4158 return clp ? 1 : 0;
4112} 4159}
4113 4160