nfs4session.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * fs/nfs/nfs4session.c
  4. *
  5. * Copyright (c) 2012 Trond Myklebust <[email protected]>
  6. *
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/errno.h>
  10. #include <linux/string.h>
  11. #include <linux/printk.h>
  12. #include <linux/slab.h>
  13. #include <linux/sunrpc/sched.h>
  14. #include <linux/sunrpc/bc_xprt.h>
  15. #include <linux/nfs.h>
  16. #include <linux/nfs4.h>
  17. #include <linux/nfs_fs.h>
  18. #include <linux/module.h>
  19. #include "nfs4_fs.h"
  20. #include "internal.h"
  21. #include "nfs4session.h"
  22. #include "callback.h"
  23. #define NFSDBG_FACILITY NFSDBG_STATE
  24. static void nfs4_init_slot_table(struct nfs4_slot_table *tbl, const char *queue)
  25. {
  26. tbl->highest_used_slotid = NFS4_NO_SLOT;
  27. spin_lock_init(&tbl->slot_tbl_lock);
  28. rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, queue);
  29. init_waitqueue_head(&tbl->slot_waitq);
  30. init_completion(&tbl->complete);
  31. }
  32. /*
  33. * nfs4_shrink_slot_table - free retired slots from the slot table
  34. */
  35. static void nfs4_shrink_slot_table(struct nfs4_slot_table *tbl, u32 newsize)
  36. {
  37. struct nfs4_slot **p;
  38. if (newsize >= tbl->max_slots)
  39. return;
  40. p = &tbl->slots;
  41. while (newsize--)
  42. p = &(*p)->next;
  43. while (*p) {
  44. struct nfs4_slot *slot = *p;
  45. *p = slot->next;
  46. kfree(slot);
  47. tbl->max_slots--;
  48. }
  49. }
  50. /**
  51. * nfs4_slot_tbl_drain_complete - wake waiters when drain is complete
  52. * @tbl: controlling slot table
  53. *
  54. */
  55. void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl)
  56. {
  57. if (nfs4_slot_tbl_draining(tbl))
  58. complete(&tbl->complete);
  59. }
  60. /*
  61. * nfs4_free_slot - free a slot and efficiently update slot table.
  62. *
  63. * freeing a slot is trivially done by clearing its respective bit
  64. * in the bitmap.
  65. * If the freed slotid equals highest_used_slotid we want to update it
  66. * so that the server would be able to size down the slot table if needed,
  67. * otherwise we know that the highest_used_slotid is still in use.
  68. * When updating highest_used_slotid there may be "holes" in the bitmap
  69. * so we need to scan down from highest_used_slotid to 0 looking for the now
  70. * highest slotid in use.
  71. * If none found, highest_used_slotid is set to NFS4_NO_SLOT.
  72. *
  73. * Must be called while holding tbl->slot_tbl_lock
  74. */
  75. void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
  76. {
  77. u32 slotid = slot->slot_nr;
  78. /* clear used bit in bitmap */
  79. __clear_bit(slotid, tbl->used_slots);
  80. /* update highest_used_slotid when it is freed */
  81. if (slotid == tbl->highest_used_slotid) {
  82. u32 new_max = find_last_bit(tbl->used_slots, slotid);
  83. if (new_max < slotid)
  84. tbl->highest_used_slotid = new_max;
  85. else {
  86. tbl->highest_used_slotid = NFS4_NO_SLOT;
  87. nfs4_slot_tbl_drain_complete(tbl);
  88. }
  89. }
  90. dprintk("%s: slotid %u highest_used_slotid %u\n", __func__,
  91. slotid, tbl->highest_used_slotid);
  92. }
  93. static struct nfs4_slot *nfs4_new_slot(struct nfs4_slot_table *tbl,
  94. u32 slotid, u32 seq_init, gfp_t gfp_mask)
  95. {
  96. struct nfs4_slot *slot;
  97. slot = kzalloc(sizeof(*slot), gfp_mask);
  98. if (slot) {
  99. slot->table = tbl;
  100. slot->slot_nr = slotid;
  101. slot->seq_nr = seq_init;
  102. slot->seq_nr_highest_sent = seq_init;
  103. slot->seq_nr_last_acked = seq_init - 1;
  104. }
  105. return slot;
  106. }
  107. static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl,
  108. u32 slotid, u32 seq_init, gfp_t gfp_mask)
  109. {
  110. struct nfs4_slot **p, *slot;
  111. p = &tbl->slots;
  112. for (;;) {
  113. if (*p == NULL) {
  114. *p = nfs4_new_slot(tbl, tbl->max_slots,
  115. seq_init, gfp_mask);
  116. if (*p == NULL)
  117. break;
  118. tbl->max_slots++;
  119. }
  120. slot = *p;
  121. if (slot->slot_nr == slotid)
  122. return slot;
  123. p = &slot->next;
  124. }
  125. return ERR_PTR(-ENOMEM);
  126. }
  127. static void nfs4_lock_slot(struct nfs4_slot_table *tbl,
  128. struct nfs4_slot *slot)
  129. {
  130. u32 slotid = slot->slot_nr;
  131. __set_bit(slotid, tbl->used_slots);
  132. if (slotid > tbl->highest_used_slotid ||
  133. tbl->highest_used_slotid == NFS4_NO_SLOT)
  134. tbl->highest_used_slotid = slotid;
  135. slot->generation = tbl->generation;
  136. }
  137. /*
  138. * nfs4_try_to_lock_slot - Given a slot try to allocate it
  139. *
  140. * Note: must be called with the slot_tbl_lock held.
  141. */
  142. bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
  143. {
  144. if (nfs4_test_locked_slot(tbl, slot->slot_nr))
  145. return false;
  146. nfs4_lock_slot(tbl, slot);
  147. return true;
  148. }
  149. /*
  150. * nfs4_lookup_slot - Find a slot but don't allocate it
  151. *
  152. * Note: must be called with the slot_tbl_lock held.
  153. */
  154. struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid)
  155. {
  156. if (slotid <= tbl->max_slotid)
  157. return nfs4_find_or_create_slot(tbl, slotid, 0, GFP_NOWAIT);
  158. return ERR_PTR(-E2BIG);
  159. }
  160. static int nfs4_slot_get_seqid(struct nfs4_slot_table *tbl, u32 slotid,
  161. u32 *seq_nr)
  162. __must_hold(&tbl->slot_tbl_lock)
  163. {
  164. struct nfs4_slot *slot;
  165. int ret;
  166. slot = nfs4_lookup_slot(tbl, slotid);
  167. ret = PTR_ERR_OR_ZERO(slot);
  168. if (!ret)
  169. *seq_nr = slot->seq_nr;
  170. return ret;
  171. }
  172. /*
  173. * nfs4_slot_seqid_in_use - test if a slot sequence id is still in use
  174. *
  175. * Given a slot table, slot id and sequence number, determine if the
  176. * RPC call in question is still in flight. This function is mainly
  177. * intended for use by the callback channel.
  178. */
  179. static bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl,
  180. u32 slotid, u32 seq_nr)
  181. {
  182. u32 cur_seq = 0;
  183. bool ret = false;
  184. spin_lock(&tbl->slot_tbl_lock);
  185. if (nfs4_slot_get_seqid(tbl, slotid, &cur_seq) == 0 &&
  186. cur_seq == seq_nr && test_bit(slotid, tbl->used_slots))
  187. ret = true;
  188. spin_unlock(&tbl->slot_tbl_lock);
  189. return ret;
  190. }
  191. /*
  192. * nfs4_slot_wait_on_seqid - wait until a slot sequence id is complete
  193. *
  194. * Given a slot table, slot id and sequence number, wait until the
  195. * corresponding RPC call completes. This function is mainly
  196. * intended for use by the callback channel.
  197. */
  198. int nfs4_slot_wait_on_seqid(struct nfs4_slot_table *tbl,
  199. u32 slotid, u32 seq_nr,
  200. unsigned long timeout)
  201. {
  202. if (wait_event_timeout(tbl->slot_waitq,
  203. !nfs4_slot_seqid_in_use(tbl, slotid, seq_nr),
  204. timeout) == 0)
  205. return -ETIMEDOUT;
  206. return 0;
  207. }
  208. /*
  209. * nfs4_alloc_slot - efficiently look for a free slot
  210. *
  211. * nfs4_alloc_slot looks for an unset bit in the used_slots bitmap.
  212. * If found, we mark the slot as used, update the highest_used_slotid,
  213. * and respectively set up the sequence operation args.
  214. *
  215. * Note: must be called with under the slot_tbl_lock.
  216. */
  217. struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)
  218. {
  219. struct nfs4_slot *ret = ERR_PTR(-EBUSY);
  220. u32 slotid;
  221. dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
  222. __func__, tbl->used_slots[0], tbl->highest_used_slotid,
  223. tbl->max_slotid + 1);
  224. slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1);
  225. if (slotid <= tbl->max_slotid) {
  226. ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT);
  227. if (!IS_ERR(ret))
  228. nfs4_lock_slot(tbl, ret);
  229. }
  230. dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n",
  231. __func__, tbl->used_slots[0], tbl->highest_used_slotid,
  232. !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT);
  233. return ret;
  234. }
  235. static int nfs4_grow_slot_table(struct nfs4_slot_table *tbl,
  236. u32 max_reqs, u32 ivalue)
  237. {
  238. if (max_reqs <= tbl->max_slots)
  239. return 0;
  240. if (!IS_ERR(nfs4_find_or_create_slot(tbl, max_reqs - 1, ivalue, GFP_NOFS)))
  241. return 0;
  242. return -ENOMEM;
  243. }
  244. static void nfs4_reset_slot_table(struct nfs4_slot_table *tbl,
  245. u32 server_highest_slotid,
  246. u32 ivalue)
  247. {
  248. struct nfs4_slot **p;
  249. nfs4_shrink_slot_table(tbl, server_highest_slotid + 1);
  250. p = &tbl->slots;
  251. while (*p) {
  252. (*p)->seq_nr = ivalue;
  253. (*p)->seq_nr_highest_sent = ivalue;
  254. (*p)->seq_nr_last_acked = ivalue - 1;
  255. p = &(*p)->next;
  256. }
  257. tbl->highest_used_slotid = NFS4_NO_SLOT;
  258. tbl->target_highest_slotid = server_highest_slotid;
  259. tbl->server_highest_slotid = server_highest_slotid;
  260. tbl->d_target_highest_slotid = 0;
  261. tbl->d2_target_highest_slotid = 0;
  262. tbl->max_slotid = server_highest_slotid;
  263. }
  264. /*
  265. * (re)Initialise a slot table
  266. */
  267. static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl,
  268. u32 max_reqs, u32 ivalue)
  269. {
  270. int ret;
  271. dprintk("--> %s: max_reqs=%u, tbl->max_slots %u\n", __func__,
  272. max_reqs, tbl->max_slots);
  273. if (max_reqs > NFS4_MAX_SLOT_TABLE)
  274. max_reqs = NFS4_MAX_SLOT_TABLE;
  275. ret = nfs4_grow_slot_table(tbl, max_reqs, ivalue);
  276. if (ret)
  277. goto out;
  278. spin_lock(&tbl->slot_tbl_lock);
  279. nfs4_reset_slot_table(tbl, max_reqs - 1, ivalue);
  280. spin_unlock(&tbl->slot_tbl_lock);
  281. dprintk("%s: tbl=%p slots=%p max_slots=%u\n", __func__,
  282. tbl, tbl->slots, tbl->max_slots);
  283. out:
  284. dprintk("<-- %s: return %d\n", __func__, ret);
  285. return ret;
  286. }
  287. /*
  288. * nfs4_release_slot_table - release all slot table entries
  289. */
  290. static void nfs4_release_slot_table(struct nfs4_slot_table *tbl)
  291. {
  292. nfs4_shrink_slot_table(tbl, 0);
  293. }
  294. /**
  295. * nfs4_shutdown_slot_table - release resources attached to a slot table
  296. * @tbl: slot table to shut down
  297. *
  298. */
  299. void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl)
  300. {
  301. nfs4_release_slot_table(tbl);
  302. rpc_destroy_wait_queue(&tbl->slot_tbl_waitq);
  303. }
  304. /**
  305. * nfs4_setup_slot_table - prepare a stand-alone slot table for use
  306. * @tbl: slot table to set up
  307. * @max_reqs: maximum number of requests allowed
  308. * @queue: name to give RPC wait queue
  309. *
  310. * Returns zero on success, or a negative errno.
  311. */
  312. int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, unsigned int max_reqs,
  313. const char *queue)
  314. {
  315. nfs4_init_slot_table(tbl, queue);
  316. return nfs4_realloc_slot_table(tbl, max_reqs, 0);
  317. }
  318. static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
  319. {
  320. struct nfs4_sequence_args *args = task->tk_msg.rpc_argp;
  321. struct nfs4_sequence_res *res = task->tk_msg.rpc_resp;
  322. struct nfs4_slot *slot = pslot;
  323. struct nfs4_slot_table *tbl = slot->table;
  324. if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
  325. return false;
  326. slot->generation = tbl->generation;
  327. args->sa_slot = slot;
  328. res->sr_timestamp = jiffies;
  329. res->sr_slot = slot;
  330. res->sr_status_flags = 0;
  331. res->sr_status = 1;
  332. return true;
  333. }
  334. static bool __nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
  335. struct nfs4_slot *slot)
  336. {
  337. if (rpc_wake_up_first(&tbl->slot_tbl_waitq, nfs41_assign_slot, slot))
  338. return true;
  339. return false;
  340. }
  341. bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
  342. struct nfs4_slot *slot)
  343. {
  344. if (slot->slot_nr > tbl->max_slotid)
  345. return false;
  346. return __nfs41_wake_and_assign_slot(tbl, slot);
  347. }
  348. static bool nfs41_try_wake_next_slot_table_entry(struct nfs4_slot_table *tbl)
  349. {
  350. struct nfs4_slot *slot = nfs4_alloc_slot(tbl);
  351. if (!IS_ERR(slot)) {
  352. bool ret = __nfs41_wake_and_assign_slot(tbl, slot);
  353. if (ret)
  354. return ret;
  355. nfs4_free_slot(tbl, slot);
  356. }
  357. return false;
  358. }
  359. void nfs41_wake_slot_table(struct nfs4_slot_table *tbl)
  360. {
  361. for (;;) {
  362. if (!nfs41_try_wake_next_slot_table_entry(tbl))
  363. break;
  364. }
  365. }
  366. #if defined(CONFIG_NFS_V4_1)
  367. static void nfs41_set_max_slotid_locked(struct nfs4_slot_table *tbl,
  368. u32 target_highest_slotid)
  369. {
  370. u32 max_slotid;
  371. max_slotid = min(NFS4_MAX_SLOT_TABLE - 1, target_highest_slotid);
  372. if (max_slotid > tbl->server_highest_slotid)
  373. max_slotid = tbl->server_highest_slotid;
  374. if (max_slotid > tbl->target_highest_slotid)
  375. max_slotid = tbl->target_highest_slotid;
  376. tbl->max_slotid = max_slotid;
  377. nfs41_wake_slot_table(tbl);
  378. }
  379. /* Update the client's idea of target_highest_slotid */
  380. static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
  381. u32 target_highest_slotid)
  382. {
  383. if (tbl->target_highest_slotid == target_highest_slotid)
  384. return;
  385. tbl->target_highest_slotid = target_highest_slotid;
  386. tbl->generation++;
  387. }
  388. void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
  389. u32 target_highest_slotid)
  390. {
  391. spin_lock(&tbl->slot_tbl_lock);
  392. nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
  393. tbl->d_target_highest_slotid = 0;
  394. tbl->d2_target_highest_slotid = 0;
  395. nfs41_set_max_slotid_locked(tbl, target_highest_slotid);
  396. spin_unlock(&tbl->slot_tbl_lock);
  397. }
  398. static void nfs41_set_server_slotid_locked(struct nfs4_slot_table *tbl,
  399. u32 highest_slotid)
  400. {
  401. if (tbl->server_highest_slotid == highest_slotid)
  402. return;
  403. if (tbl->highest_used_slotid > highest_slotid)
  404. return;
  405. /* Deallocate slots */
  406. nfs4_shrink_slot_table(tbl, highest_slotid + 1);
  407. tbl->server_highest_slotid = highest_slotid;
  408. }
  409. static s32 nfs41_derivative_target_slotid(s32 s1, s32 s2)
  410. {
  411. s1 -= s2;
  412. if (s1 == 0)
  413. return 0;
  414. if (s1 < 0)
  415. return (s1 - 1) >> 1;
  416. return (s1 + 1) >> 1;
  417. }
  418. static int nfs41_sign_s32(s32 s1)
  419. {
  420. if (s1 > 0)
  421. return 1;
  422. if (s1 < 0)
  423. return -1;
  424. return 0;
  425. }
  426. static bool nfs41_same_sign_or_zero_s32(s32 s1, s32 s2)
  427. {
  428. if (!s1 || !s2)
  429. return true;
  430. return nfs41_sign_s32(s1) == nfs41_sign_s32(s2);
  431. }
  432. /* Try to eliminate outliers by checking for sharp changes in the
  433. * derivatives and second derivatives
  434. */
  435. static bool nfs41_is_outlier_target_slotid(struct nfs4_slot_table *tbl,
  436. u32 new_target)
  437. {
  438. s32 d_target, d2_target;
  439. bool ret = true;
  440. d_target = nfs41_derivative_target_slotid(new_target,
  441. tbl->target_highest_slotid);
  442. d2_target = nfs41_derivative_target_slotid(d_target,
  443. tbl->d_target_highest_slotid);
  444. /* Is first derivative same sign? */
  445. if (nfs41_same_sign_or_zero_s32(d_target, tbl->d_target_highest_slotid))
  446. ret = false;
  447. /* Is second derivative same sign? */
  448. if (nfs41_same_sign_or_zero_s32(d2_target, tbl->d2_target_highest_slotid))
  449. ret = false;
  450. tbl->d_target_highest_slotid = d_target;
  451. tbl->d2_target_highest_slotid = d2_target;
  452. return ret;
  453. }
  454. void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
  455. struct nfs4_slot *slot,
  456. struct nfs4_sequence_res *res)
  457. {
  458. u32 target_highest_slotid = min(res->sr_target_highest_slotid,
  459. NFS4_MAX_SLOTID);
  460. u32 highest_slotid = min(res->sr_highest_slotid, NFS4_MAX_SLOTID);
  461. spin_lock(&tbl->slot_tbl_lock);
  462. if (!nfs41_is_outlier_target_slotid(tbl, target_highest_slotid))
  463. nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
  464. if (tbl->generation == slot->generation)
  465. nfs41_set_server_slotid_locked(tbl, highest_slotid);
  466. nfs41_set_max_slotid_locked(tbl, target_highest_slotid);
  467. spin_unlock(&tbl->slot_tbl_lock);
  468. }
  469. static void nfs4_release_session_slot_tables(struct nfs4_session *session)
  470. {
  471. nfs4_release_slot_table(&session->fc_slot_table);
  472. nfs4_release_slot_table(&session->bc_slot_table);
  473. }
  474. /*
  475. * Initialize or reset the forechannel and backchannel tables
  476. */
  477. int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
  478. {
  479. struct nfs4_slot_table *tbl;
  480. int status;
  481. dprintk("--> %s\n", __func__);
  482. /* Fore channel */
  483. tbl = &ses->fc_slot_table;
  484. tbl->session = ses;
  485. status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
  486. if (status || !(ses->flags & SESSION4_BACK_CHAN)) /* -ENOMEM */
  487. return status;
  488. /* Back channel */
  489. tbl = &ses->bc_slot_table;
  490. tbl->session = ses;
  491. status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
  492. if (status && tbl->slots == NULL)
  493. /* Fore and back channel share a connection so get
  494. * both slot tables or neither */
  495. nfs4_release_session_slot_tables(ses);
  496. return status;
  497. }
  498. struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
  499. {
  500. struct nfs4_session *session;
  501. session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
  502. if (!session)
  503. return NULL;
  504. nfs4_init_slot_table(&session->fc_slot_table, "ForeChannel Slot table");
  505. nfs4_init_slot_table(&session->bc_slot_table, "BackChannel Slot table");
  506. session->session_state = 1<<NFS4_SESSION_INITING;
  507. session->clp = clp;
  508. return session;
  509. }
  510. static void nfs4_destroy_session_slot_tables(struct nfs4_session *session)
  511. {
  512. nfs4_shutdown_slot_table(&session->fc_slot_table);
  513. nfs4_shutdown_slot_table(&session->bc_slot_table);
  514. }
  515. void nfs4_destroy_session(struct nfs4_session *session)
  516. {
  517. struct rpc_xprt *xprt;
  518. const struct cred *cred;
  519. cred = nfs4_get_clid_cred(session->clp);
  520. nfs4_proc_destroy_session(session, cred);
  521. put_cred(cred);
  522. rcu_read_lock();
  523. xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
  524. rcu_read_unlock();
  525. dprintk("%s Destroy backchannel for xprt %p\n",
  526. __func__, xprt);
  527. xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
  528. nfs4_destroy_session_slot_tables(session);
  529. kfree(session);
  530. }
  531. /*
  532. * With sessions, the client is not marked ready until after a
  533. * successful EXCHANGE_ID and CREATE_SESSION.
  534. *
  535. * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
  536. * other versions of NFS can be tried.
  537. */
  538. static int nfs41_check_session_ready(struct nfs_client *clp)
  539. {
  540. int ret;
  541. if (clp->cl_cons_state == NFS_CS_SESSION_INITING) {
  542. ret = nfs4_client_recover_expired_lease(clp);
  543. if (ret)
  544. return ret;
  545. }
  546. if (clp->cl_cons_state < NFS_CS_READY)
  547. return -EPROTONOSUPPORT;
  548. smp_rmb();
  549. return 0;
  550. }
  551. int nfs4_init_session(struct nfs_client *clp)
  552. {
  553. if (!nfs4_has_session(clp))
  554. return 0;
  555. clear_bit(NFS4_SESSION_INITING, &clp->cl_session->session_state);
  556. return nfs41_check_session_ready(clp);
  557. }
  558. int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time)
  559. {
  560. struct nfs4_session *session = clp->cl_session;
  561. int ret;
  562. spin_lock(&clp->cl_lock);
  563. if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
  564. /*
  565. * Do not set NFS_CS_CHECK_LEASE_TIME instead set the
  566. * DS lease to be equal to the MDS lease.
  567. */
  568. clp->cl_lease_time = lease_time;
  569. clp->cl_last_renewal = jiffies;
  570. }
  571. spin_unlock(&clp->cl_lock);
  572. ret = nfs41_check_session_ready(clp);
  573. if (ret)
  574. return ret;
  575. /* Test for the DS role */
  576. if (!is_ds_client(clp))
  577. return -ENODEV;
  578. return 0;
  579. }
  580. EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
  581. #endif /* defined(CONFIG_NFS_V4_1) */