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