1 /* 2 * Common NFS I/O operations for the pnfs file based 3 * layout drivers. 4 * 5 * Copyright (c) 2014, Primary Data, Inc. All rights reserved. 6 * 7 * Tom Haynes <loghyr@primarydata.com> 8 */ 9 10 #include <linux/nfs_fs.h> 11 #include <linux/nfs_page.h> 12 #include <linux/sunrpc/addr.h> 13 #include <linux/module.h> 14 15 #include "nfs4session.h" 16 #include "internal.h" 17 #include "pnfs.h" 18 19 #define NFSDBG_FACILITY NFSDBG_PNFS 20 21 void pnfs_generic_rw_release(void *data) 22 { 23 struct nfs_pgio_header *hdr = data; 24 25 nfs_put_client(hdr->ds_clp); 26 hdr->mds_ops->rpc_release(data); 27 } 28 EXPORT_SYMBOL_GPL(pnfs_generic_rw_release); 29 30 /* Fake up some data that will cause nfs_commit_release to retry the writes. */ 31 void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data) 32 { 33 struct nfs_page *first = nfs_list_entry(data->pages.next); 34 35 data->task.tk_status = 0; 36 memcpy(&data->verf.verifier, &first->wb_verf, 37 sizeof(data->verf.verifier)); 38 data->verf.verifier.data[0]++; /* ensure verifier mismatch */ 39 } 40 EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes); 41 42 void pnfs_generic_write_commit_done(struct rpc_task *task, void *data) 43 { 44 struct nfs_commit_data *wdata = data; 45 46 /* Note this may cause RPC to be resent */ 47 wdata->mds_ops->rpc_call_done(task, data); 48 } 49 EXPORT_SYMBOL_GPL(pnfs_generic_write_commit_done); 50 51 void pnfs_generic_commit_release(void *calldata) 52 { 53 struct nfs_commit_data *data = calldata; 54 55 data->completion_ops->completion(data); 56 pnfs_put_lseg(data->lseg); 57 nfs_put_client(data->ds_clp); 58 nfs_commitdata_release(data); 59 } 60 EXPORT_SYMBOL_GPL(pnfs_generic_commit_release); 61 62 /* The generic layer is about to remove the req from the commit list. 63 * If this will make the bucket empty, it will need to put the lseg reference. 64 * Note this must be called holding i_lock 65 */ 66 void 67 pnfs_generic_clear_request_commit(struct nfs_page *req, 68 struct nfs_commit_info *cinfo) 69 { 70 struct pnfs_layout_segment *freeme = NULL; 71 72 if (!test_and_clear_bit(PG_COMMIT_TO_DS, &req->wb_flags)) 73 goto out; 74 cinfo->ds->nwritten--; 75 if (list_is_singular(&req->wb_list)) { 76 struct pnfs_commit_bucket *bucket; 77 78 bucket = list_first_entry(&req->wb_list, 79 struct pnfs_commit_bucket, 80 written); 81 freeme = bucket->wlseg; 82 bucket->wlseg = NULL; 83 } 84 out: 85 nfs_request_remove_commit_list(req, cinfo); 86 pnfs_put_lseg_locked(freeme); 87 } 88 EXPORT_SYMBOL_GPL(pnfs_generic_clear_request_commit); 89 90 static int 91 pnfs_generic_transfer_commit_list(struct list_head *src, struct list_head *dst, 92 struct nfs_commit_info *cinfo, int max) 93 { 94 struct nfs_page *req, *tmp; 95 int ret = 0; 96 97 list_for_each_entry_safe(req, tmp, src, wb_list) { 98 if (!nfs_lock_request(req)) 99 continue; 100 kref_get(&req->wb_kref); 101 if (cond_resched_lock(&cinfo->inode->i_lock)) 102 list_safe_reset_next(req, tmp, wb_list); 103 nfs_request_remove_commit_list(req, cinfo); 104 clear_bit(PG_COMMIT_TO_DS, &req->wb_flags); 105 nfs_list_add_request(req, dst); 106 ret++; 107 if ((ret == max) && !cinfo->dreq) 108 break; 109 } 110 return ret; 111 } 112 113 static int 114 pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket, 115 struct nfs_commit_info *cinfo, 116 int max) 117 { 118 struct list_head *src = &bucket->written; 119 struct list_head *dst = &bucket->committing; 120 int ret; 121 122 lockdep_assert_held(&cinfo->inode->i_lock); 123 ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max); 124 if (ret) { 125 cinfo->ds->nwritten -= ret; 126 cinfo->ds->ncommitting += ret; 127 if (bucket->clseg == NULL) 128 bucket->clseg = pnfs_get_lseg(bucket->wlseg); 129 if (list_empty(src)) { 130 pnfs_put_lseg_locked(bucket->wlseg); 131 bucket->wlseg = NULL; 132 } 133 } 134 return ret; 135 } 136 137 /* Move reqs from written to committing lists, returning count 138 * of number moved. 139 */ 140 int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, 141 int max) 142 { 143 int i, rv = 0, cnt; 144 145 lockdep_assert_held(&cinfo->inode->i_lock); 146 for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) { 147 cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i], 148 cinfo, max); 149 max -= cnt; 150 rv += cnt; 151 } 152 return rv; 153 } 154 EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists); 155 156 /* Pull everything off the committing lists and dump into @dst. */ 157 void pnfs_generic_recover_commit_reqs(struct list_head *dst, 158 struct nfs_commit_info *cinfo) 159 { 160 struct pnfs_commit_bucket *b; 161 struct pnfs_layout_segment *freeme; 162 int nwritten; 163 int i; 164 165 lockdep_assert_held(&cinfo->inode->i_lock); 166 restart: 167 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) { 168 nwritten = pnfs_generic_transfer_commit_list(&b->written, 169 dst, cinfo, 0); 170 if (!nwritten) 171 continue; 172 cinfo->ds->nwritten -= nwritten; 173 if (list_empty(&b->written)) { 174 freeme = b->wlseg; 175 b->wlseg = NULL; 176 spin_unlock(&cinfo->inode->i_lock); 177 pnfs_put_lseg(freeme); 178 spin_lock(&cinfo->inode->i_lock); 179 goto restart; 180 } 181 } 182 } 183 EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs); 184 185 static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx) 186 { 187 struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds; 188 struct pnfs_commit_bucket *bucket; 189 struct pnfs_layout_segment *freeme; 190 struct list_head *pos; 191 LIST_HEAD(pages); 192 int i; 193 194 spin_lock(&cinfo->inode->i_lock); 195 for (i = idx; i < fl_cinfo->nbuckets; i++) { 196 bucket = &fl_cinfo->buckets[i]; 197 if (list_empty(&bucket->committing)) 198 continue; 199 freeme = bucket->clseg; 200 bucket->clseg = NULL; 201 list_for_each(pos, &bucket->committing) 202 cinfo->ds->ncommitting--; 203 list_splice_init(&bucket->committing, &pages); 204 spin_unlock(&cinfo->inode->i_lock); 205 nfs_retry_commit(&pages, freeme, cinfo, i); 206 pnfs_put_lseg(freeme); 207 spin_lock(&cinfo->inode->i_lock); 208 } 209 spin_unlock(&cinfo->inode->i_lock); 210 } 211 212 static unsigned int 213 pnfs_generic_alloc_ds_commits(struct nfs_commit_info *cinfo, 214 struct list_head *list) 215 { 216 struct pnfs_ds_commit_info *fl_cinfo; 217 struct pnfs_commit_bucket *bucket; 218 struct nfs_commit_data *data; 219 int i; 220 unsigned int nreq = 0; 221 222 fl_cinfo = cinfo->ds; 223 bucket = fl_cinfo->buckets; 224 for (i = 0; i < fl_cinfo->nbuckets; i++, bucket++) { 225 if (list_empty(&bucket->committing)) 226 continue; 227 data = nfs_commitdata_alloc(false); 228 if (!data) 229 break; 230 data->ds_commit_index = i; 231 list_add(&data->pages, list); 232 nreq++; 233 } 234 235 /* Clean up on error */ 236 pnfs_generic_retry_commit(cinfo, i); 237 return nreq; 238 } 239 240 static inline 241 void pnfs_fetch_commit_bucket_list(struct list_head *pages, 242 struct nfs_commit_data *data, 243 struct nfs_commit_info *cinfo) 244 { 245 struct pnfs_commit_bucket *bucket; 246 struct list_head *pos; 247 248 bucket = &cinfo->ds->buckets[data->ds_commit_index]; 249 spin_lock(&cinfo->inode->i_lock); 250 list_for_each(pos, &bucket->committing) 251 cinfo->ds->ncommitting--; 252 list_splice_init(&bucket->committing, pages); 253 data->lseg = bucket->clseg; 254 bucket->clseg = NULL; 255 spin_unlock(&cinfo->inode->i_lock); 256 257 } 258 259 /* Helper function for pnfs_generic_commit_pagelist to catch an empty 260 * page list. This can happen when two commits race. 261 * 262 * This must be called instead of nfs_init_commit - call one or the other, but 263 * not both! 264 */ 265 static bool 266 pnfs_generic_commit_cancel_empty_pagelist(struct list_head *pages, 267 struct nfs_commit_data *data, 268 struct nfs_commit_info *cinfo) 269 { 270 if (list_empty(pages)) { 271 if (atomic_dec_and_test(&cinfo->mds->rpcs_out)) 272 wake_up_atomic_t(&cinfo->mds->rpcs_out); 273 /* don't call nfs_commitdata_release - it tries to put 274 * the open_context which is not acquired until nfs_init_commit 275 * which has not been called on @data */ 276 WARN_ON_ONCE(data->context); 277 nfs_commit_free(data); 278 return true; 279 } 280 281 return false; 282 } 283 284 /* This follows nfs_commit_list pretty closely */ 285 int 286 pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages, 287 int how, struct nfs_commit_info *cinfo, 288 int (*initiate_commit)(struct nfs_commit_data *data, 289 int how)) 290 { 291 struct nfs_commit_data *data, *tmp; 292 LIST_HEAD(list); 293 unsigned int nreq = 0; 294 295 if (!list_empty(mds_pages)) { 296 data = nfs_commitdata_alloc(true); 297 data->ds_commit_index = -1; 298 list_add(&data->pages, &list); 299 nreq++; 300 } 301 302 nreq += pnfs_generic_alloc_ds_commits(cinfo, &list); 303 304 if (nreq == 0) 305 goto out; 306 307 atomic_add(nreq, &cinfo->mds->rpcs_out); 308 309 list_for_each_entry_safe(data, tmp, &list, pages) { 310 list_del_init(&data->pages); 311 if (data->ds_commit_index < 0) { 312 /* another commit raced with us */ 313 if (pnfs_generic_commit_cancel_empty_pagelist(mds_pages, 314 data, cinfo)) 315 continue; 316 317 nfs_init_commit(data, mds_pages, NULL, cinfo); 318 nfs_initiate_commit(NFS_CLIENT(inode), data, 319 NFS_PROTO(data->inode), 320 data->mds_ops, how, 0); 321 } else { 322 LIST_HEAD(pages); 323 324 pnfs_fetch_commit_bucket_list(&pages, data, cinfo); 325 326 /* another commit raced with us */ 327 if (pnfs_generic_commit_cancel_empty_pagelist(&pages, 328 data, cinfo)) 329 continue; 330 331 nfs_init_commit(data, &pages, data->lseg, cinfo); 332 initiate_commit(data, how); 333 } 334 } 335 out: 336 return PNFS_ATTEMPTED; 337 } 338 EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist); 339 340 /* 341 * Data server cache 342 * 343 * Data servers can be mapped to different device ids. 344 * nfs4_pnfs_ds reference counting 345 * - set to 1 on allocation 346 * - incremented when a device id maps a data server already in the cache. 347 * - decremented when deviceid is removed from the cache. 348 */ 349 static DEFINE_SPINLOCK(nfs4_ds_cache_lock); 350 static LIST_HEAD(nfs4_data_server_cache); 351 352 /* Debug routines */ 353 static void 354 print_ds(struct nfs4_pnfs_ds *ds) 355 { 356 if (ds == NULL) { 357 printk(KERN_WARNING "%s NULL device\n", __func__); 358 return; 359 } 360 printk(KERN_WARNING " ds %s\n" 361 " ref count %d\n" 362 " client %p\n" 363 " cl_exchange_flags %x\n", 364 ds->ds_remotestr, 365 atomic_read(&ds->ds_count), ds->ds_clp, 366 ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0); 367 } 368 369 static bool 370 same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2) 371 { 372 struct sockaddr_in *a, *b; 373 struct sockaddr_in6 *a6, *b6; 374 375 if (addr1->sa_family != addr2->sa_family) 376 return false; 377 378 switch (addr1->sa_family) { 379 case AF_INET: 380 a = (struct sockaddr_in *)addr1; 381 b = (struct sockaddr_in *)addr2; 382 383 if (a->sin_addr.s_addr == b->sin_addr.s_addr && 384 a->sin_port == b->sin_port) 385 return true; 386 break; 387 388 case AF_INET6: 389 a6 = (struct sockaddr_in6 *)addr1; 390 b6 = (struct sockaddr_in6 *)addr2; 391 392 /* LINKLOCAL addresses must have matching scope_id */ 393 if (ipv6_addr_src_scope(&a6->sin6_addr) == 394 IPV6_ADDR_SCOPE_LINKLOCAL && 395 a6->sin6_scope_id != b6->sin6_scope_id) 396 return false; 397 398 if (ipv6_addr_equal(&a6->sin6_addr, &b6->sin6_addr) && 399 a6->sin6_port == b6->sin6_port) 400 return true; 401 break; 402 403 default: 404 dprintk("%s: unhandled address family: %u\n", 405 __func__, addr1->sa_family); 406 return false; 407 } 408 409 return false; 410 } 411 412 /* 413 * Checks if 'dsaddrs1' contains a subset of 'dsaddrs2'. If it does, 414 * declare a match. 415 */ 416 static bool 417 _same_data_server_addrs_locked(const struct list_head *dsaddrs1, 418 const struct list_head *dsaddrs2) 419 { 420 struct nfs4_pnfs_ds_addr *da1, *da2; 421 struct sockaddr *sa1, *sa2; 422 bool match = false; 423 424 list_for_each_entry(da1, dsaddrs1, da_node) { 425 sa1 = (struct sockaddr *)&da1->da_addr; 426 match = false; 427 list_for_each_entry(da2, dsaddrs2, da_node) { 428 sa2 = (struct sockaddr *)&da2->da_addr; 429 match = same_sockaddr(sa1, sa2); 430 if (match) 431 break; 432 } 433 if (!match) 434 break; 435 } 436 return match; 437 } 438 439 /* 440 * Lookup DS by addresses. nfs4_ds_cache_lock is held 441 */ 442 static struct nfs4_pnfs_ds * 443 _data_server_lookup_locked(const struct list_head *dsaddrs) 444 { 445 struct nfs4_pnfs_ds *ds; 446 447 list_for_each_entry(ds, &nfs4_data_server_cache, ds_node) 448 if (_same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs)) 449 return ds; 450 return NULL; 451 } 452 453 static void destroy_ds(struct nfs4_pnfs_ds *ds) 454 { 455 struct nfs4_pnfs_ds_addr *da; 456 457 dprintk("--> %s\n", __func__); 458 ifdebug(FACILITY) 459 print_ds(ds); 460 461 nfs_put_client(ds->ds_clp); 462 463 while (!list_empty(&ds->ds_addrs)) { 464 da = list_first_entry(&ds->ds_addrs, 465 struct nfs4_pnfs_ds_addr, 466 da_node); 467 list_del_init(&da->da_node); 468 kfree(da->da_remotestr); 469 kfree(da); 470 } 471 472 kfree(ds->ds_remotestr); 473 kfree(ds); 474 } 475 476 void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds) 477 { 478 if (atomic_dec_and_lock(&ds->ds_count, 479 &nfs4_ds_cache_lock)) { 480 list_del_init(&ds->ds_node); 481 spin_unlock(&nfs4_ds_cache_lock); 482 destroy_ds(ds); 483 } 484 } 485 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_put); 486 487 /* 488 * Create a string with a human readable address and port to avoid 489 * complicated setup around many dprinks. 490 */ 491 static char * 492 nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags) 493 { 494 struct nfs4_pnfs_ds_addr *da; 495 char *remotestr; 496 size_t len; 497 char *p; 498 499 len = 3; /* '{', '}' and eol */ 500 list_for_each_entry(da, dsaddrs, da_node) { 501 len += strlen(da->da_remotestr) + 1; /* string plus comma */ 502 } 503 504 remotestr = kzalloc(len, gfp_flags); 505 if (!remotestr) 506 return NULL; 507 508 p = remotestr; 509 *(p++) = '{'; 510 len--; 511 list_for_each_entry(da, dsaddrs, da_node) { 512 size_t ll = strlen(da->da_remotestr); 513 514 if (ll > len) 515 goto out_err; 516 517 memcpy(p, da->da_remotestr, ll); 518 p += ll; 519 len -= ll; 520 521 if (len < 1) 522 goto out_err; 523 (*p++) = ','; 524 len--; 525 } 526 if (len < 2) 527 goto out_err; 528 *(p++) = '}'; 529 *p = '\0'; 530 return remotestr; 531 out_err: 532 kfree(remotestr); 533 return NULL; 534 } 535 536 /* 537 * Given a list of multipath struct nfs4_pnfs_ds_addr, add it to ds cache if 538 * uncached and return cached struct nfs4_pnfs_ds. 539 */ 540 struct nfs4_pnfs_ds * 541 nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags) 542 { 543 struct nfs4_pnfs_ds *tmp_ds, *ds = NULL; 544 char *remotestr; 545 546 if (list_empty(dsaddrs)) { 547 dprintk("%s: no addresses defined\n", __func__); 548 goto out; 549 } 550 551 ds = kzalloc(sizeof(*ds), gfp_flags); 552 if (!ds) 553 goto out; 554 555 /* this is only used for debugging, so it's ok if its NULL */ 556 remotestr = nfs4_pnfs_remotestr(dsaddrs, gfp_flags); 557 558 spin_lock(&nfs4_ds_cache_lock); 559 tmp_ds = _data_server_lookup_locked(dsaddrs); 560 if (tmp_ds == NULL) { 561 INIT_LIST_HEAD(&ds->ds_addrs); 562 list_splice_init(dsaddrs, &ds->ds_addrs); 563 ds->ds_remotestr = remotestr; 564 atomic_set(&ds->ds_count, 1); 565 INIT_LIST_HEAD(&ds->ds_node); 566 ds->ds_clp = NULL; 567 list_add(&ds->ds_node, &nfs4_data_server_cache); 568 dprintk("%s add new data server %s\n", __func__, 569 ds->ds_remotestr); 570 } else { 571 kfree(remotestr); 572 kfree(ds); 573 atomic_inc(&tmp_ds->ds_count); 574 dprintk("%s data server %s found, inc'ed ds_count to %d\n", 575 __func__, tmp_ds->ds_remotestr, 576 atomic_read(&tmp_ds->ds_count)); 577 ds = tmp_ds; 578 } 579 spin_unlock(&nfs4_ds_cache_lock); 580 out: 581 return ds; 582 } 583 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_add); 584 585 static void nfs4_wait_ds_connect(struct nfs4_pnfs_ds *ds) 586 { 587 might_sleep(); 588 wait_on_bit(&ds->ds_state, NFS4DS_CONNECTING, 589 TASK_KILLABLE); 590 } 591 592 static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds) 593 { 594 smp_mb__before_atomic(); 595 clear_bit(NFS4DS_CONNECTING, &ds->ds_state); 596 smp_mb__after_atomic(); 597 wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING); 598 } 599 600 static struct nfs_client *(*get_v3_ds_connect)( 601 struct nfs_server *mds_srv, 602 const struct sockaddr *ds_addr, 603 int ds_addrlen, 604 int ds_proto, 605 unsigned int ds_timeo, 606 unsigned int ds_retrans); 607 608 static bool load_v3_ds_connect(void) 609 { 610 if (!get_v3_ds_connect) { 611 get_v3_ds_connect = symbol_request(nfs3_set_ds_client); 612 WARN_ON_ONCE(!get_v3_ds_connect); 613 } 614 615 return(get_v3_ds_connect != NULL); 616 } 617 618 void nfs4_pnfs_v3_ds_connect_unload(void) 619 { 620 if (get_v3_ds_connect) { 621 symbol_put(nfs3_set_ds_client); 622 get_v3_ds_connect = NULL; 623 } 624 } 625 626 static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, 627 struct nfs4_pnfs_ds *ds, 628 unsigned int timeo, 629 unsigned int retrans) 630 { 631 struct nfs_client *clp = ERR_PTR(-EIO); 632 struct nfs4_pnfs_ds_addr *da; 633 int status = 0; 634 635 dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr); 636 637 if (!load_v3_ds_connect()) 638 goto out; 639 640 list_for_each_entry(da, &ds->ds_addrs, da_node) { 641 dprintk("%s: DS %s: trying address %s\n", 642 __func__, ds->ds_remotestr, da->da_remotestr); 643 644 if (!IS_ERR(clp)) { 645 struct xprt_create xprt_args = { 646 .ident = XPRT_TRANSPORT_TCP, 647 .net = clp->cl_net, 648 .dstaddr = (struct sockaddr *)&da->da_addr, 649 .addrlen = da->da_addrlen, 650 .servername = clp->cl_hostname, 651 }; 652 /* Add this address as an alias */ 653 rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, 654 rpc_clnt_test_and_add_xprt, NULL); 655 } else 656 clp = get_v3_ds_connect(mds_srv, 657 (struct sockaddr *)&da->da_addr, 658 da->da_addrlen, IPPROTO_TCP, 659 timeo, retrans); 660 } 661 662 if (IS_ERR(clp)) { 663 status = PTR_ERR(clp); 664 goto out; 665 } 666 667 smp_wmb(); 668 ds->ds_clp = clp; 669 dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr); 670 out: 671 return status; 672 } 673 674 static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, 675 struct nfs4_pnfs_ds *ds, 676 unsigned int timeo, 677 unsigned int retrans, 678 u32 minor_version) 679 { 680 struct nfs_client *clp = ERR_PTR(-EIO); 681 struct nfs4_pnfs_ds_addr *da; 682 int status = 0; 683 684 dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr); 685 686 list_for_each_entry(da, &ds->ds_addrs, da_node) { 687 dprintk("%s: DS %s: trying address %s\n", 688 __func__, ds->ds_remotestr, da->da_remotestr); 689 690 if (!IS_ERR(clp) && clp->cl_mvops->session_trunk) { 691 struct xprt_create xprt_args = { 692 .ident = XPRT_TRANSPORT_TCP, 693 .net = clp->cl_net, 694 .dstaddr = (struct sockaddr *)&da->da_addr, 695 .addrlen = da->da_addrlen, 696 .servername = clp->cl_hostname, 697 }; 698 struct nfs4_add_xprt_data xprtdata = { 699 .clp = clp, 700 .cred = nfs4_get_clid_cred(clp), 701 }; 702 struct rpc_add_xprt_test rpcdata = { 703 .add_xprt_test = clp->cl_mvops->session_trunk, 704 .data = &xprtdata, 705 }; 706 707 /** 708 * Test this address for session trunking and 709 * add as an alias 710 */ 711 rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, 712 rpc_clnt_setup_test_and_add_xprt, 713 &rpcdata); 714 if (xprtdata.cred) 715 put_rpccred(xprtdata.cred); 716 } else { 717 clp = nfs4_set_ds_client(mds_srv, 718 (struct sockaddr *)&da->da_addr, 719 da->da_addrlen, IPPROTO_TCP, 720 timeo, retrans, minor_version); 721 if (IS_ERR(clp)) 722 continue; 723 724 status = nfs4_init_ds_session(clp, 725 mds_srv->nfs_client->cl_lease_time); 726 if (status) { 727 nfs_put_client(clp); 728 clp = ERR_PTR(-EIO); 729 continue; 730 } 731 732 } 733 } 734 735 if (IS_ERR(clp)) { 736 status = PTR_ERR(clp); 737 goto out; 738 } 739 740 smp_wmb(); 741 ds->ds_clp = clp; 742 dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr); 743 out: 744 return status; 745 } 746 747 /* 748 * Create an rpc connection to the nfs4_pnfs_ds data server. 749 * Currently only supports IPv4 and IPv6 addresses. 750 * If connection fails, make devid unavailable and return a -errno. 751 */ 752 int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, 753 struct nfs4_deviceid_node *devid, unsigned int timeo, 754 unsigned int retrans, u32 version, u32 minor_version) 755 { 756 int err; 757 758 again: 759 err = 0; 760 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { 761 if (version == 3) { 762 err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, 763 retrans); 764 } else if (version == 4) { 765 err = _nfs4_pnfs_v4_ds_connect(mds_srv, ds, timeo, 766 retrans, minor_version); 767 } else { 768 dprintk("%s: unsupported DS version %d\n", __func__, 769 version); 770 err = -EPROTONOSUPPORT; 771 } 772 773 nfs4_clear_ds_conn_bit(ds); 774 } else { 775 nfs4_wait_ds_connect(ds); 776 777 /* what was waited on didn't connect AND didn't mark unavail */ 778 if (!ds->ds_clp && !nfs4_test_deviceid_unavailable(devid)) 779 goto again; 780 } 781 782 /* 783 * At this point the ds->ds_clp should be ready, but it might have 784 * hit an error. 785 */ 786 if (!err) { 787 if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) { 788 WARN_ON_ONCE(ds->ds_clp || 789 !nfs4_test_deviceid_unavailable(devid)); 790 return -EINVAL; 791 } 792 err = nfs_client_init_status(ds->ds_clp); 793 } 794 795 return err; 796 } 797 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect); 798 799 /* 800 * Currently only supports ipv4, ipv6 and one multi-path address. 801 */ 802 struct nfs4_pnfs_ds_addr * 803 nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags) 804 { 805 struct nfs4_pnfs_ds_addr *da = NULL; 806 char *buf, *portstr; 807 __be16 port; 808 int nlen, rlen; 809 int tmp[2]; 810 __be32 *p; 811 char *netid, *match_netid; 812 size_t len, match_netid_len; 813 char *startsep = ""; 814 char *endsep = ""; 815 816 817 /* r_netid */ 818 p = xdr_inline_decode(xdr, 4); 819 if (unlikely(!p)) 820 goto out_err; 821 nlen = be32_to_cpup(p++); 822 823 p = xdr_inline_decode(xdr, nlen); 824 if (unlikely(!p)) 825 goto out_err; 826 827 netid = kmalloc(nlen+1, gfp_flags); 828 if (unlikely(!netid)) 829 goto out_err; 830 831 netid[nlen] = '\0'; 832 memcpy(netid, p, nlen); 833 834 /* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */ 835 p = xdr_inline_decode(xdr, 4); 836 if (unlikely(!p)) 837 goto out_free_netid; 838 rlen = be32_to_cpup(p); 839 840 p = xdr_inline_decode(xdr, rlen); 841 if (unlikely(!p)) 842 goto out_free_netid; 843 844 /* port is ".ABC.DEF", 8 chars max */ 845 if (rlen > INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN + 8) { 846 dprintk("%s: Invalid address, length %d\n", __func__, 847 rlen); 848 goto out_free_netid; 849 } 850 buf = kmalloc(rlen + 1, gfp_flags); 851 if (!buf) { 852 dprintk("%s: Not enough memory\n", __func__); 853 goto out_free_netid; 854 } 855 buf[rlen] = '\0'; 856 memcpy(buf, p, rlen); 857 858 /* replace port '.' with '-' */ 859 portstr = strrchr(buf, '.'); 860 if (!portstr) { 861 dprintk("%s: Failed finding expected dot in port\n", 862 __func__); 863 goto out_free_buf; 864 } 865 *portstr = '-'; 866 867 /* find '.' between address and port */ 868 portstr = strrchr(buf, '.'); 869 if (!portstr) { 870 dprintk("%s: Failed finding expected dot between address and " 871 "port\n", __func__); 872 goto out_free_buf; 873 } 874 *portstr = '\0'; 875 876 da = kzalloc(sizeof(*da), gfp_flags); 877 if (unlikely(!da)) 878 goto out_free_buf; 879 880 INIT_LIST_HEAD(&da->da_node); 881 882 if (!rpc_pton(net, buf, portstr-buf, (struct sockaddr *)&da->da_addr, 883 sizeof(da->da_addr))) { 884 dprintk("%s: error parsing address %s\n", __func__, buf); 885 goto out_free_da; 886 } 887 888 portstr++; 889 sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]); 890 port = htons((tmp[0] << 8) | (tmp[1])); 891 892 switch (da->da_addr.ss_family) { 893 case AF_INET: 894 ((struct sockaddr_in *)&da->da_addr)->sin_port = port; 895 da->da_addrlen = sizeof(struct sockaddr_in); 896 match_netid = "tcp"; 897 match_netid_len = 3; 898 break; 899 900 case AF_INET6: 901 ((struct sockaddr_in6 *)&da->da_addr)->sin6_port = port; 902 da->da_addrlen = sizeof(struct sockaddr_in6); 903 match_netid = "tcp6"; 904 match_netid_len = 4; 905 startsep = "["; 906 endsep = "]"; 907 break; 908 909 default: 910 dprintk("%s: unsupported address family: %u\n", 911 __func__, da->da_addr.ss_family); 912 goto out_free_da; 913 } 914 915 if (nlen != match_netid_len || strncmp(netid, match_netid, nlen)) { 916 dprintk("%s: ERROR: r_netid \"%s\" != \"%s\"\n", 917 __func__, netid, match_netid); 918 goto out_free_da; 919 } 920 921 /* save human readable address */ 922 len = strlen(startsep) + strlen(buf) + strlen(endsep) + 7; 923 da->da_remotestr = kzalloc(len, gfp_flags); 924 925 /* NULL is ok, only used for dprintk */ 926 if (da->da_remotestr) 927 snprintf(da->da_remotestr, len, "%s%s%s:%u", startsep, 928 buf, endsep, ntohs(port)); 929 930 dprintk("%s: Parsed DS addr %s\n", __func__, da->da_remotestr); 931 kfree(buf); 932 kfree(netid); 933 return da; 934 935 out_free_da: 936 kfree(da); 937 out_free_buf: 938 dprintk("%s: Error parsing DS addr: %s\n", __func__, buf); 939 kfree(buf); 940 out_free_netid: 941 kfree(netid); 942 out_err: 943 return NULL; 944 } 945 EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr); 946 947 void 948 pnfs_layout_mark_request_commit(struct nfs_page *req, 949 struct pnfs_layout_segment *lseg, 950 struct nfs_commit_info *cinfo, 951 u32 ds_commit_idx) 952 { 953 struct list_head *list; 954 struct pnfs_commit_bucket *buckets; 955 956 spin_lock(&cinfo->inode->i_lock); 957 buckets = cinfo->ds->buckets; 958 list = &buckets[ds_commit_idx].written; 959 if (list_empty(list)) { 960 if (!pnfs_is_valid_lseg(lseg)) { 961 spin_unlock(&cinfo->inode->i_lock); 962 cinfo->completion_ops->resched_write(cinfo, req); 963 return; 964 } 965 /* Non-empty buckets hold a reference on the lseg. That ref 966 * is normally transferred to the COMMIT call and released 967 * there. It could also be released if the last req is pulled 968 * off due to a rewrite, in which case it will be done in 969 * pnfs_common_clear_request_commit 970 */ 971 WARN_ON_ONCE(buckets[ds_commit_idx].wlseg != NULL); 972 buckets[ds_commit_idx].wlseg = pnfs_get_lseg(lseg); 973 } 974 set_bit(PG_COMMIT_TO_DS, &req->wb_flags); 975 cinfo->ds->nwritten++; 976 977 nfs_request_add_commit_list_locked(req, list, cinfo); 978 spin_unlock(&cinfo->inode->i_lock); 979 nfs_mark_page_unstable(req->wb_page, cinfo); 980 } 981 EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit); 982 983 int 984 pnfs_nfs_generic_sync(struct inode *inode, bool datasync) 985 { 986 int ret; 987 988 if (!pnfs_layoutcommit_outstanding(inode)) 989 return 0; 990 ret = nfs_commit_inode(inode, FLUSH_SYNC); 991 if (ret < 0) 992 return ret; 993 if (datasync) 994 return 0; 995 return pnfs_layoutcommit_inode(inode, true); 996 } 997 EXPORT_SYMBOL_GPL(pnfs_nfs_generic_sync); 998 999