1 /* client.c: NFS client sharing and management code 2 * 3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/sched.h> 16 #include <linux/time.h> 17 #include <linux/kernel.h> 18 #include <linux/mm.h> 19 #include <linux/string.h> 20 #include <linux/stat.h> 21 #include <linux/errno.h> 22 #include <linux/unistd.h> 23 #include <linux/sunrpc/clnt.h> 24 #include <linux/sunrpc/stats.h> 25 #include <linux/sunrpc/metrics.h> 26 #include <linux/sunrpc/xprtsock.h> 27 #include <linux/sunrpc/xprtrdma.h> 28 #include <linux/nfs_fs.h> 29 #include <linux/nfs_mount.h> 30 #include <linux/nfs4_mount.h> 31 #include <linux/lockd/bind.h> 32 #include <linux/seq_file.h> 33 #include <linux/mount.h> 34 #include <linux/nfs_idmap.h> 35 #include <linux/vfs.h> 36 #include <linux/inet.h> 37 #include <linux/in6.h> 38 #include <net/ipv6.h> 39 #include <linux/nfs_xdr.h> 40 41 #include <asm/system.h> 42 43 #include "nfs4_fs.h" 44 #include "callback.h" 45 #include "delegation.h" 46 #include "iostat.h" 47 #include "internal.h" 48 49 #define NFSDBG_FACILITY NFSDBG_CLIENT 50 51 static DEFINE_SPINLOCK(nfs_client_lock); 52 static LIST_HEAD(nfs_client_list); 53 static LIST_HEAD(nfs_volume_list); 54 static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); 55 56 /* 57 * RPC cruft for NFS 58 */ 59 static struct rpc_version *nfs_version[5] = { 60 [2] = &nfs_version2, 61 #ifdef CONFIG_NFS_V3 62 [3] = &nfs_version3, 63 #endif 64 #ifdef CONFIG_NFS_V4 65 [4] = &nfs_version4, 66 #endif 67 }; 68 69 struct rpc_program nfs_program = { 70 .name = "nfs", 71 .number = NFS_PROGRAM, 72 .nrvers = ARRAY_SIZE(nfs_version), 73 .version = nfs_version, 74 .stats = &nfs_rpcstat, 75 .pipe_dir_name = "/nfs", 76 }; 77 78 struct rpc_stat nfs_rpcstat = { 79 .program = &nfs_program 80 }; 81 82 83 #ifdef CONFIG_NFS_V3_ACL 84 static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; 85 static struct rpc_version * nfsacl_version[] = { 86 [3] = &nfsacl_version3, 87 }; 88 89 struct rpc_program nfsacl_program = { 90 .name = "nfsacl", 91 .number = NFS_ACL_PROGRAM, 92 .nrvers = ARRAY_SIZE(nfsacl_version), 93 .version = nfsacl_version, 94 .stats = &nfsacl_rpcstat, 95 }; 96 #endif /* CONFIG_NFS_V3_ACL */ 97 98 struct nfs_client_initdata { 99 const char *hostname; 100 const struct sockaddr *addr; 101 size_t addrlen; 102 const struct nfs_rpc_ops *rpc_ops; 103 int proto; 104 }; 105 106 /* 107 * Allocate a shared client record 108 * 109 * Since these are allocated/deallocated very rarely, we don't 110 * bother putting them in a slab cache... 111 */ 112 static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) 113 { 114 struct nfs_client *clp; 115 116 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) 117 goto error_0; 118 119 clp->rpc_ops = cl_init->rpc_ops; 120 121 if (cl_init->rpc_ops->version == 4) { 122 if (nfs_callback_up() < 0) 123 goto error_2; 124 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state); 125 } 126 127 atomic_set(&clp->cl_count, 1); 128 clp->cl_cons_state = NFS_CS_INITING; 129 130 memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen); 131 clp->cl_addrlen = cl_init->addrlen; 132 133 if (cl_init->hostname) { 134 clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL); 135 if (!clp->cl_hostname) 136 goto error_3; 137 } 138 139 INIT_LIST_HEAD(&clp->cl_superblocks); 140 clp->cl_rpcclient = ERR_PTR(-EINVAL); 141 142 clp->cl_proto = cl_init->proto; 143 144 #ifdef CONFIG_NFS_V4 145 init_rwsem(&clp->cl_sem); 146 INIT_LIST_HEAD(&clp->cl_delegations); 147 spin_lock_init(&clp->cl_lock); 148 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); 149 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); 150 clp->cl_boot_time = CURRENT_TIME; 151 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 152 #endif 153 154 return clp; 155 156 error_3: 157 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) 158 nfs_callback_down(); 159 error_2: 160 kfree(clp); 161 error_0: 162 return NULL; 163 } 164 165 static void nfs4_shutdown_client(struct nfs_client *clp) 166 { 167 #ifdef CONFIG_NFS_V4 168 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state)) 169 nfs4_kill_renewd(clp); 170 BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners)); 171 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) 172 nfs_idmap_delete(clp); 173 #endif 174 } 175 176 /* 177 * Destroy a shared client record 178 */ 179 static void nfs_free_client(struct nfs_client *clp) 180 { 181 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); 182 183 nfs4_shutdown_client(clp); 184 185 /* -EIO all pending I/O */ 186 if (!IS_ERR(clp->cl_rpcclient)) 187 rpc_shutdown_client(clp->cl_rpcclient); 188 189 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) 190 nfs_callback_down(); 191 192 kfree(clp->cl_hostname); 193 kfree(clp); 194 195 dprintk("<-- nfs_free_client()\n"); 196 } 197 198 /* 199 * Release a reference to a shared client record 200 */ 201 void nfs_put_client(struct nfs_client *clp) 202 { 203 if (!clp) 204 return; 205 206 dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count)); 207 208 if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) { 209 list_del(&clp->cl_share_link); 210 spin_unlock(&nfs_client_lock); 211 212 BUG_ON(!list_empty(&clp->cl_superblocks)); 213 214 nfs_free_client(clp); 215 } 216 } 217 218 static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, 219 const struct sockaddr_in *sa2) 220 { 221 return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; 222 } 223 224 static int nfs_sockaddr_match_ipaddr6(const struct sockaddr_in6 *sa1, 225 const struct sockaddr_in6 *sa2) 226 { 227 return ipv6_addr_equal(&sa1->sin6_addr, &sa2->sin6_addr); 228 } 229 230 static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, 231 const struct sockaddr *sa2) 232 { 233 switch (sa1->sa_family) { 234 case AF_INET: 235 return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, 236 (const struct sockaddr_in *)sa2); 237 case AF_INET6: 238 return nfs_sockaddr_match_ipaddr6((const struct sockaddr_in6 *)sa1, 239 (const struct sockaddr_in6 *)sa2); 240 } 241 BUG(); 242 } 243 244 /* 245 * Find a client by IP address and protocol version 246 * - returns NULL if no such client 247 */ 248 struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion) 249 { 250 struct nfs_client *clp; 251 252 spin_lock(&nfs_client_lock); 253 list_for_each_entry(clp, &nfs_client_list, cl_share_link) { 254 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; 255 256 /* Don't match clients that failed to initialise properly */ 257 if (clp->cl_cons_state != NFS_CS_READY) 258 continue; 259 260 /* Different NFS versions cannot share the same nfs_client */ 261 if (clp->rpc_ops->version != nfsversion) 262 continue; 263 264 if (addr->sa_family != clap->sa_family) 265 continue; 266 /* Match only the IP address, not the port number */ 267 if (!nfs_sockaddr_match_ipaddr(addr, clap)) 268 continue; 269 270 atomic_inc(&clp->cl_count); 271 spin_unlock(&nfs_client_lock); 272 return clp; 273 } 274 spin_unlock(&nfs_client_lock); 275 return NULL; 276 } 277 278 /* 279 * Find a client by IP address and protocol version 280 * - returns NULL if no such client 281 */ 282 struct nfs_client *nfs_find_client_next(struct nfs_client *clp) 283 { 284 struct sockaddr *sap = (struct sockaddr *)&clp->cl_addr; 285 u32 nfsvers = clp->rpc_ops->version; 286 287 spin_lock(&nfs_client_lock); 288 list_for_each_entry_continue(clp, &nfs_client_list, cl_share_link) { 289 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; 290 291 /* Don't match clients that failed to initialise properly */ 292 if (clp->cl_cons_state != NFS_CS_READY) 293 continue; 294 295 /* Different NFS versions cannot share the same nfs_client */ 296 if (clp->rpc_ops->version != nfsvers) 297 continue; 298 299 if (sap->sa_family != clap->sa_family) 300 continue; 301 /* Match only the IP address, not the port number */ 302 if (!nfs_sockaddr_match_ipaddr(sap, clap)) 303 continue; 304 305 atomic_inc(&clp->cl_count); 306 spin_unlock(&nfs_client_lock); 307 return clp; 308 } 309 spin_unlock(&nfs_client_lock); 310 return NULL; 311 } 312 313 /* 314 * Find an nfs_client on the list that matches the initialisation data 315 * that is supplied. 316 */ 317 static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) 318 { 319 struct nfs_client *clp; 320 321 list_for_each_entry(clp, &nfs_client_list, cl_share_link) { 322 /* Don't match clients that failed to initialise properly */ 323 if (clp->cl_cons_state < 0) 324 continue; 325 326 /* Different NFS versions cannot share the same nfs_client */ 327 if (clp->rpc_ops != data->rpc_ops) 328 continue; 329 330 if (clp->cl_proto != data->proto) 331 continue; 332 333 /* Match the full socket address */ 334 if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0) 335 continue; 336 337 atomic_inc(&clp->cl_count); 338 return clp; 339 } 340 return NULL; 341 } 342 343 /* 344 * Look up a client by IP address and protocol version 345 * - creates a new record if one doesn't yet exist 346 */ 347 static struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init) 348 { 349 struct nfs_client *clp, *new = NULL; 350 int error; 351 352 dprintk("--> nfs_get_client(%s,v%u)\n", 353 cl_init->hostname ?: "", cl_init->rpc_ops->version); 354 355 /* see if the client already exists */ 356 do { 357 spin_lock(&nfs_client_lock); 358 359 clp = nfs_match_client(cl_init); 360 if (clp) 361 goto found_client; 362 if (new) 363 goto install_client; 364 365 spin_unlock(&nfs_client_lock); 366 367 new = nfs_alloc_client(cl_init); 368 } while (new); 369 370 return ERR_PTR(-ENOMEM); 371 372 /* install a new client and return with it unready */ 373 install_client: 374 clp = new; 375 list_add(&clp->cl_share_link, &nfs_client_list); 376 spin_unlock(&nfs_client_lock); 377 dprintk("--> nfs_get_client() = %p [new]\n", clp); 378 return clp; 379 380 /* found an existing client 381 * - make sure it's ready before returning 382 */ 383 found_client: 384 spin_unlock(&nfs_client_lock); 385 386 if (new) 387 nfs_free_client(new); 388 389 error = wait_event_killable(nfs_client_active_wq, 390 clp->cl_cons_state != NFS_CS_INITING); 391 if (error < 0) { 392 nfs_put_client(clp); 393 return ERR_PTR(-ERESTARTSYS); 394 } 395 396 if (clp->cl_cons_state < NFS_CS_READY) { 397 error = clp->cl_cons_state; 398 nfs_put_client(clp); 399 return ERR_PTR(error); 400 } 401 402 BUG_ON(clp->cl_cons_state != NFS_CS_READY); 403 404 dprintk("--> nfs_get_client() = %p [share]\n", clp); 405 return clp; 406 } 407 408 /* 409 * Mark a server as ready or failed 410 */ 411 static void nfs_mark_client_ready(struct nfs_client *clp, int state) 412 { 413 clp->cl_cons_state = state; 414 wake_up_all(&nfs_client_active_wq); 415 } 416 417 /* 418 * Initialise the timeout values for a connection 419 */ 420 static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, 421 unsigned int timeo, unsigned int retrans) 422 { 423 to->to_initval = timeo * HZ / 10; 424 to->to_retries = retrans; 425 if (!to->to_retries) 426 to->to_retries = 2; 427 428 switch (proto) { 429 case XPRT_TRANSPORT_TCP: 430 case XPRT_TRANSPORT_RDMA: 431 if (to->to_initval == 0) 432 to->to_initval = 60 * HZ; 433 if (to->to_initval > NFS_MAX_TCP_TIMEOUT) 434 to->to_initval = NFS_MAX_TCP_TIMEOUT; 435 to->to_increment = to->to_initval; 436 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries); 437 if (to->to_maxval > NFS_MAX_TCP_TIMEOUT) 438 to->to_maxval = NFS_MAX_TCP_TIMEOUT; 439 if (to->to_maxval < to->to_initval) 440 to->to_maxval = to->to_initval; 441 to->to_exponential = 0; 442 break; 443 case XPRT_TRANSPORT_UDP: 444 default: 445 if (!to->to_initval) 446 to->to_initval = 11 * HZ / 10; 447 if (to->to_initval > NFS_MAX_UDP_TIMEOUT) 448 to->to_initval = NFS_MAX_UDP_TIMEOUT; 449 to->to_maxval = NFS_MAX_UDP_TIMEOUT; 450 to->to_exponential = 1; 451 break; 452 } 453 } 454 455 /* 456 * Create an RPC client handle 457 */ 458 static int nfs_create_rpc_client(struct nfs_client *clp, 459 const struct rpc_timeout *timeparms, 460 rpc_authflavor_t flavor, 461 int flags) 462 { 463 struct rpc_clnt *clnt = NULL; 464 struct rpc_create_args args = { 465 .protocol = clp->cl_proto, 466 .address = (struct sockaddr *)&clp->cl_addr, 467 .addrsize = clp->cl_addrlen, 468 .timeout = timeparms, 469 .servername = clp->cl_hostname, 470 .program = &nfs_program, 471 .version = clp->rpc_ops->version, 472 .authflavor = flavor, 473 .flags = flags, 474 }; 475 476 if (!IS_ERR(clp->cl_rpcclient)) 477 return 0; 478 479 clnt = rpc_create(&args); 480 if (IS_ERR(clnt)) { 481 dprintk("%s: cannot create RPC client. Error = %ld\n", 482 __FUNCTION__, PTR_ERR(clnt)); 483 return PTR_ERR(clnt); 484 } 485 486 clp->cl_rpcclient = clnt; 487 return 0; 488 } 489 490 /* 491 * Version 2 or 3 client destruction 492 */ 493 static void nfs_destroy_server(struct nfs_server *server) 494 { 495 if (!(server->flags & NFS_MOUNT_NONLM)) 496 nlmclnt_done(server->nlm_host); 497 } 498 499 /* 500 * Version 2 or 3 lockd setup 501 */ 502 static int nfs_start_lockd(struct nfs_server *server) 503 { 504 struct nlm_host *host; 505 struct nfs_client *clp = server->nfs_client; 506 struct nlmclnt_initdata nlm_init = { 507 .hostname = clp->cl_hostname, 508 .address = (struct sockaddr *)&clp->cl_addr, 509 .addrlen = clp->cl_addrlen, 510 .protocol = server->flags & NFS_MOUNT_TCP ? 511 IPPROTO_TCP : IPPROTO_UDP, 512 .nfs_version = clp->rpc_ops->version, 513 }; 514 515 if (nlm_init.nfs_version > 3) 516 return 0; 517 if (server->flags & NFS_MOUNT_NONLM) 518 return 0; 519 520 host = nlmclnt_init(&nlm_init); 521 if (IS_ERR(host)) 522 return PTR_ERR(host); 523 524 server->nlm_host = host; 525 server->destroy = nfs_destroy_server; 526 return 0; 527 } 528 529 /* 530 * Initialise an NFSv3 ACL client connection 531 */ 532 #ifdef CONFIG_NFS_V3_ACL 533 static void nfs_init_server_aclclient(struct nfs_server *server) 534 { 535 if (server->nfs_client->rpc_ops->version != 3) 536 goto out_noacl; 537 if (server->flags & NFS_MOUNT_NOACL) 538 goto out_noacl; 539 540 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3); 541 if (IS_ERR(server->client_acl)) 542 goto out_noacl; 543 544 /* No errors! Assume that Sun nfsacls are supported */ 545 server->caps |= NFS_CAP_ACLS; 546 return; 547 548 out_noacl: 549 server->caps &= ~NFS_CAP_ACLS; 550 } 551 #else 552 static inline void nfs_init_server_aclclient(struct nfs_server *server) 553 { 554 server->flags &= ~NFS_MOUNT_NOACL; 555 server->caps &= ~NFS_CAP_ACLS; 556 } 557 #endif 558 559 /* 560 * Create a general RPC client 561 */ 562 static int nfs_init_server_rpcclient(struct nfs_server *server, 563 const struct rpc_timeout *timeo, 564 rpc_authflavor_t pseudoflavour) 565 { 566 struct nfs_client *clp = server->nfs_client; 567 568 server->client = rpc_clone_client(clp->cl_rpcclient); 569 if (IS_ERR(server->client)) { 570 dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__); 571 return PTR_ERR(server->client); 572 } 573 574 memcpy(&server->client->cl_timeout_default, 575 timeo, 576 sizeof(server->client->cl_timeout_default)); 577 server->client->cl_timeout = &server->client->cl_timeout_default; 578 579 if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) { 580 struct rpc_auth *auth; 581 582 auth = rpcauth_create(pseudoflavour, server->client); 583 if (IS_ERR(auth)) { 584 dprintk("%s: couldn't create credcache!\n", __FUNCTION__); 585 return PTR_ERR(auth); 586 } 587 } 588 server->client->cl_softrtry = 0; 589 if (server->flags & NFS_MOUNT_SOFT) 590 server->client->cl_softrtry = 1; 591 592 return 0; 593 } 594 595 /* 596 * Initialise an NFS2 or NFS3 client 597 */ 598 static int nfs_init_client(struct nfs_client *clp, 599 const struct rpc_timeout *timeparms, 600 const struct nfs_parsed_mount_data *data) 601 { 602 int error; 603 604 if (clp->cl_cons_state == NFS_CS_READY) { 605 /* the client is already initialised */ 606 dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp); 607 return 0; 608 } 609 610 /* 611 * Create a client RPC handle for doing FSSTAT with UNIX auth only 612 * - RFC 2623, sec 2.3.2 613 */ 614 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0); 615 if (error < 0) 616 goto error; 617 nfs_mark_client_ready(clp, NFS_CS_READY); 618 return 0; 619 620 error: 621 nfs_mark_client_ready(clp, error); 622 dprintk("<-- nfs_init_client() = xerror %d\n", error); 623 return error; 624 } 625 626 /* 627 * Create a version 2 or 3 client 628 */ 629 static int nfs_init_server(struct nfs_server *server, 630 const struct nfs_parsed_mount_data *data) 631 { 632 struct nfs_client_initdata cl_init = { 633 .hostname = data->nfs_server.hostname, 634 .addr = (const struct sockaddr *)&data->nfs_server.address, 635 .addrlen = data->nfs_server.addrlen, 636 .rpc_ops = &nfs_v2_clientops, 637 .proto = data->nfs_server.protocol, 638 }; 639 struct rpc_timeout timeparms; 640 struct nfs_client *clp; 641 int error; 642 643 dprintk("--> nfs_init_server()\n"); 644 645 #ifdef CONFIG_NFS_V3 646 if (data->flags & NFS_MOUNT_VER3) 647 cl_init.rpc_ops = &nfs_v3_clientops; 648 #endif 649 650 /* Allocate or find a client reference we can use */ 651 clp = nfs_get_client(&cl_init); 652 if (IS_ERR(clp)) { 653 dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); 654 return PTR_ERR(clp); 655 } 656 657 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 658 data->timeo, data->retrans); 659 error = nfs_init_client(clp, &timeparms, data); 660 if (error < 0) 661 goto error; 662 663 server->nfs_client = clp; 664 665 /* Initialise the client representation from the mount data */ 666 server->flags = data->flags & NFS_MOUNT_FLAGMASK; 667 668 if (data->rsize) 669 server->rsize = nfs_block_size(data->rsize, NULL); 670 if (data->wsize) 671 server->wsize = nfs_block_size(data->wsize, NULL); 672 673 server->acregmin = data->acregmin * HZ; 674 server->acregmax = data->acregmax * HZ; 675 server->acdirmin = data->acdirmin * HZ; 676 server->acdirmax = data->acdirmax * HZ; 677 678 /* Start lockd here, before we might error out */ 679 error = nfs_start_lockd(server); 680 if (error < 0) 681 goto error; 682 683 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 684 if (error < 0) 685 goto error; 686 687 server->namelen = data->namlen; 688 /* Create a client RPC handle for the NFSv3 ACL management interface */ 689 nfs_init_server_aclclient(server); 690 dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp); 691 return 0; 692 693 error: 694 server->nfs_client = NULL; 695 nfs_put_client(clp); 696 dprintk("<-- nfs_init_server() = xerror %d\n", error); 697 return error; 698 } 699 700 /* 701 * Load up the server record from information gained in an fsinfo record 702 */ 703 static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo) 704 { 705 unsigned long max_rpc_payload; 706 707 /* Work out a lot of parameters */ 708 if (server->rsize == 0) 709 server->rsize = nfs_block_size(fsinfo->rtpref, NULL); 710 if (server->wsize == 0) 711 server->wsize = nfs_block_size(fsinfo->wtpref, NULL); 712 713 if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax) 714 server->rsize = nfs_block_size(fsinfo->rtmax, NULL); 715 if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax) 716 server->wsize = nfs_block_size(fsinfo->wtmax, NULL); 717 718 max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); 719 if (server->rsize > max_rpc_payload) 720 server->rsize = max_rpc_payload; 721 if (server->rsize > NFS_MAX_FILE_IO_SIZE) 722 server->rsize = NFS_MAX_FILE_IO_SIZE; 723 server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 724 725 server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD; 726 727 if (server->wsize > max_rpc_payload) 728 server->wsize = max_rpc_payload; 729 if (server->wsize > NFS_MAX_FILE_IO_SIZE) 730 server->wsize = NFS_MAX_FILE_IO_SIZE; 731 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 732 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL); 733 734 server->dtsize = nfs_block_size(fsinfo->dtpref, NULL); 735 if (server->dtsize > PAGE_CACHE_SIZE) 736 server->dtsize = PAGE_CACHE_SIZE; 737 if (server->dtsize > server->rsize) 738 server->dtsize = server->rsize; 739 740 if (server->flags & NFS_MOUNT_NOAC) { 741 server->acregmin = server->acregmax = 0; 742 server->acdirmin = server->acdirmax = 0; 743 } 744 745 server->maxfilesize = fsinfo->maxfilesize; 746 747 /* We're airborne Set socket buffersize */ 748 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); 749 } 750 751 /* 752 * Probe filesystem information, including the FSID on v2/v3 753 */ 754 static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr) 755 { 756 struct nfs_fsinfo fsinfo; 757 struct nfs_client *clp = server->nfs_client; 758 int error; 759 760 dprintk("--> nfs_probe_fsinfo()\n"); 761 762 if (clp->rpc_ops->set_capabilities != NULL) { 763 error = clp->rpc_ops->set_capabilities(server, mntfh); 764 if (error < 0) 765 goto out_error; 766 } 767 768 fsinfo.fattr = fattr; 769 nfs_fattr_init(fattr); 770 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); 771 if (error < 0) 772 goto out_error; 773 774 nfs_server_set_fsinfo(server, &fsinfo); 775 error = bdi_init(&server->backing_dev_info); 776 if (error) 777 goto out_error; 778 779 780 /* Get some general file system info */ 781 if (server->namelen == 0) { 782 struct nfs_pathconf pathinfo; 783 784 pathinfo.fattr = fattr; 785 nfs_fattr_init(fattr); 786 787 if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0) 788 server->namelen = pathinfo.max_namelen; 789 } 790 791 dprintk("<-- nfs_probe_fsinfo() = 0\n"); 792 return 0; 793 794 out_error: 795 dprintk("nfs_probe_fsinfo: error = %d\n", -error); 796 return error; 797 } 798 799 /* 800 * Copy useful information when duplicating a server record 801 */ 802 static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) 803 { 804 target->flags = source->flags; 805 target->acregmin = source->acregmin; 806 target->acregmax = source->acregmax; 807 target->acdirmin = source->acdirmin; 808 target->acdirmax = source->acdirmax; 809 target->caps = source->caps; 810 } 811 812 /* 813 * Allocate and initialise a server record 814 */ 815 static struct nfs_server *nfs_alloc_server(void) 816 { 817 struct nfs_server *server; 818 819 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 820 if (!server) 821 return NULL; 822 823 server->client = server->client_acl = ERR_PTR(-EINVAL); 824 825 /* Zero out the NFS state stuff */ 826 INIT_LIST_HEAD(&server->client_link); 827 INIT_LIST_HEAD(&server->master_link); 828 829 init_waitqueue_head(&server->active_wq); 830 atomic_set(&server->active, 0); 831 832 server->io_stats = nfs_alloc_iostats(); 833 if (!server->io_stats) { 834 kfree(server); 835 return NULL; 836 } 837 838 return server; 839 } 840 841 /* 842 * Free up a server record 843 */ 844 void nfs_free_server(struct nfs_server *server) 845 { 846 dprintk("--> nfs_free_server()\n"); 847 848 spin_lock(&nfs_client_lock); 849 list_del(&server->client_link); 850 list_del(&server->master_link); 851 spin_unlock(&nfs_client_lock); 852 853 if (server->destroy != NULL) 854 server->destroy(server); 855 856 if (!IS_ERR(server->client_acl)) 857 rpc_shutdown_client(server->client_acl); 858 if (!IS_ERR(server->client)) 859 rpc_shutdown_client(server->client); 860 861 nfs_put_client(server->nfs_client); 862 863 nfs_free_iostats(server->io_stats); 864 bdi_destroy(&server->backing_dev_info); 865 kfree(server); 866 nfs_release_automount_timer(); 867 dprintk("<-- nfs_free_server()\n"); 868 } 869 870 /* 871 * Create a version 2 or 3 volume record 872 * - keyed on server and FSID 873 */ 874 struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, 875 struct nfs_fh *mntfh) 876 { 877 struct nfs_server *server; 878 struct nfs_fattr fattr; 879 int error; 880 881 server = nfs_alloc_server(); 882 if (!server) 883 return ERR_PTR(-ENOMEM); 884 885 /* Get a client representation */ 886 error = nfs_init_server(server, data); 887 if (error < 0) 888 goto error; 889 890 BUG_ON(!server->nfs_client); 891 BUG_ON(!server->nfs_client->rpc_ops); 892 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 893 894 /* Probe the root fh to retrieve its FSID */ 895 error = nfs_probe_fsinfo(server, mntfh, &fattr); 896 if (error < 0) 897 goto error; 898 if (server->nfs_client->rpc_ops->version == 3) { 899 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) 900 server->namelen = NFS3_MAXNAMLEN; 901 if (!(data->flags & NFS_MOUNT_NORDIRPLUS)) 902 server->caps |= NFS_CAP_READDIRPLUS; 903 } else { 904 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) 905 server->namelen = NFS2_MAXNAMLEN; 906 } 907 908 if (!(fattr.valid & NFS_ATTR_FATTR)) { 909 error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); 910 if (error < 0) { 911 dprintk("nfs_create_server: getattr error = %d\n", -error); 912 goto error; 913 } 914 } 915 memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); 916 917 dprintk("Server FSID: %llx:%llx\n", 918 (unsigned long long) server->fsid.major, 919 (unsigned long long) server->fsid.minor); 920 921 BUG_ON(!server->nfs_client); 922 BUG_ON(!server->nfs_client->rpc_ops); 923 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 924 925 spin_lock(&nfs_client_lock); 926 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); 927 list_add_tail(&server->master_link, &nfs_volume_list); 928 spin_unlock(&nfs_client_lock); 929 930 server->mount_time = jiffies; 931 return server; 932 933 error: 934 nfs_free_server(server); 935 return ERR_PTR(error); 936 } 937 938 #ifdef CONFIG_NFS_V4 939 /* 940 * Initialise an NFS4 client record 941 */ 942 static int nfs4_init_client(struct nfs_client *clp, 943 const struct rpc_timeout *timeparms, 944 const char *ip_addr, 945 rpc_authflavor_t authflavour) 946 { 947 int error; 948 949 if (clp->cl_cons_state == NFS_CS_READY) { 950 /* the client is initialised already */ 951 dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp); 952 return 0; 953 } 954 955 /* Check NFS protocol revision and initialize RPC op vector */ 956 clp->rpc_ops = &nfs_v4_clientops; 957 958 error = nfs_create_rpc_client(clp, timeparms, authflavour, 959 RPC_CLNT_CREATE_DISCRTRY); 960 if (error < 0) 961 goto error; 962 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); 963 964 error = nfs_idmap_new(clp); 965 if (error < 0) { 966 dprintk("%s: failed to create idmapper. Error = %d\n", 967 __FUNCTION__, error); 968 goto error; 969 } 970 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state); 971 972 nfs_mark_client_ready(clp, NFS_CS_READY); 973 return 0; 974 975 error: 976 nfs_mark_client_ready(clp, error); 977 dprintk("<-- nfs4_init_client() = xerror %d\n", error); 978 return error; 979 } 980 981 /* 982 * Set up an NFS4 client 983 */ 984 static int nfs4_set_client(struct nfs_server *server, 985 const char *hostname, 986 const struct sockaddr *addr, 987 const size_t addrlen, 988 const char *ip_addr, 989 rpc_authflavor_t authflavour, 990 int proto, const struct rpc_timeout *timeparms) 991 { 992 struct nfs_client_initdata cl_init = { 993 .hostname = hostname, 994 .addr = addr, 995 .addrlen = addrlen, 996 .rpc_ops = &nfs_v4_clientops, 997 .proto = proto, 998 }; 999 struct nfs_client *clp; 1000 int error; 1001 1002 dprintk("--> nfs4_set_client()\n"); 1003 1004 /* Allocate or find a client reference we can use */ 1005 clp = nfs_get_client(&cl_init); 1006 if (IS_ERR(clp)) { 1007 error = PTR_ERR(clp); 1008 goto error; 1009 } 1010 error = nfs4_init_client(clp, timeparms, ip_addr, authflavour); 1011 if (error < 0) 1012 goto error_put; 1013 1014 server->nfs_client = clp; 1015 dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp); 1016 return 0; 1017 1018 error_put: 1019 nfs_put_client(clp); 1020 error: 1021 dprintk("<-- nfs4_set_client() = xerror %d\n", error); 1022 return error; 1023 } 1024 1025 /* 1026 * Create a version 4 volume record 1027 */ 1028 static int nfs4_init_server(struct nfs_server *server, 1029 const struct nfs_parsed_mount_data *data) 1030 { 1031 struct rpc_timeout timeparms; 1032 int error; 1033 1034 dprintk("--> nfs4_init_server()\n"); 1035 1036 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 1037 data->timeo, data->retrans); 1038 1039 /* Get a client record */ 1040 error = nfs4_set_client(server, 1041 data->nfs_server.hostname, 1042 (const struct sockaddr *)&data->nfs_server.address, 1043 data->nfs_server.addrlen, 1044 data->client_address, 1045 data->auth_flavors[0], 1046 data->nfs_server.protocol, 1047 &timeparms); 1048 if (error < 0) 1049 goto error; 1050 1051 /* Initialise the client representation from the mount data */ 1052 server->flags = data->flags & NFS_MOUNT_FLAGMASK; 1053 server->caps |= NFS_CAP_ATOMIC_OPEN; 1054 1055 if (data->rsize) 1056 server->rsize = nfs_block_size(data->rsize, NULL); 1057 if (data->wsize) 1058 server->wsize = nfs_block_size(data->wsize, NULL); 1059 1060 server->acregmin = data->acregmin * HZ; 1061 server->acregmax = data->acregmax * HZ; 1062 server->acdirmin = data->acdirmin * HZ; 1063 server->acdirmax = data->acdirmax * HZ; 1064 1065 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 1066 1067 error: 1068 /* Done */ 1069 dprintk("<-- nfs4_init_server() = %d\n", error); 1070 return error; 1071 } 1072 1073 /* 1074 * Create a version 4 volume record 1075 * - keyed on server and FSID 1076 */ 1077 struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, 1078 struct nfs_fh *mntfh) 1079 { 1080 struct nfs_fattr fattr; 1081 struct nfs_server *server; 1082 int error; 1083 1084 dprintk("--> nfs4_create_server()\n"); 1085 1086 server = nfs_alloc_server(); 1087 if (!server) 1088 return ERR_PTR(-ENOMEM); 1089 1090 /* set up the general RPC client */ 1091 error = nfs4_init_server(server, data); 1092 if (error < 0) 1093 goto error; 1094 1095 BUG_ON(!server->nfs_client); 1096 BUG_ON(!server->nfs_client->rpc_ops); 1097 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1098 1099 /* Probe the root fh to retrieve its FSID */ 1100 error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); 1101 if (error < 0) 1102 goto error; 1103 1104 dprintk("Server FSID: %llx:%llx\n", 1105 (unsigned long long) server->fsid.major, 1106 (unsigned long long) server->fsid.minor); 1107 dprintk("Mount FH: %d\n", mntfh->size); 1108 1109 error = nfs_probe_fsinfo(server, mntfh, &fattr); 1110 if (error < 0) 1111 goto error; 1112 1113 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) 1114 server->namelen = NFS4_MAXNAMLEN; 1115 1116 BUG_ON(!server->nfs_client); 1117 BUG_ON(!server->nfs_client->rpc_ops); 1118 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1119 1120 spin_lock(&nfs_client_lock); 1121 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); 1122 list_add_tail(&server->master_link, &nfs_volume_list); 1123 spin_unlock(&nfs_client_lock); 1124 1125 server->mount_time = jiffies; 1126 dprintk("<-- nfs4_create_server() = %p\n", server); 1127 return server; 1128 1129 error: 1130 nfs_free_server(server); 1131 dprintk("<-- nfs4_create_server() = error %d\n", error); 1132 return ERR_PTR(error); 1133 } 1134 1135 /* 1136 * Create an NFS4 referral server record 1137 */ 1138 struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, 1139 struct nfs_fh *mntfh) 1140 { 1141 struct nfs_client *parent_client; 1142 struct nfs_server *server, *parent_server; 1143 struct nfs_fattr fattr; 1144 int error; 1145 1146 dprintk("--> nfs4_create_referral_server()\n"); 1147 1148 server = nfs_alloc_server(); 1149 if (!server) 1150 return ERR_PTR(-ENOMEM); 1151 1152 parent_server = NFS_SB(data->sb); 1153 parent_client = parent_server->nfs_client; 1154 1155 /* Get a client representation. 1156 * Note: NFSv4 always uses TCP, */ 1157 error = nfs4_set_client(server, data->hostname, 1158 data->addr, 1159 data->addrlen, 1160 parent_client->cl_ipaddr, 1161 data->authflavor, 1162 parent_server->client->cl_xprt->prot, 1163 parent_server->client->cl_timeout); 1164 if (error < 0) 1165 goto error; 1166 1167 /* Initialise the client representation from the parent server */ 1168 nfs_server_copy_userdata(server, parent_server); 1169 server->caps |= NFS_CAP_ATOMIC_OPEN; 1170 1171 error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor); 1172 if (error < 0) 1173 goto error; 1174 1175 BUG_ON(!server->nfs_client); 1176 BUG_ON(!server->nfs_client->rpc_ops); 1177 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1178 1179 /* Probe the root fh to retrieve its FSID and filehandle */ 1180 error = nfs4_path_walk(server, mntfh, data->mnt_path); 1181 if (error < 0) 1182 goto error; 1183 1184 /* probe the filesystem info for this server filesystem */ 1185 error = nfs_probe_fsinfo(server, mntfh, &fattr); 1186 if (error < 0) 1187 goto error; 1188 1189 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) 1190 server->namelen = NFS4_MAXNAMLEN; 1191 1192 dprintk("Referral FSID: %llx:%llx\n", 1193 (unsigned long long) server->fsid.major, 1194 (unsigned long long) server->fsid.minor); 1195 1196 spin_lock(&nfs_client_lock); 1197 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); 1198 list_add_tail(&server->master_link, &nfs_volume_list); 1199 spin_unlock(&nfs_client_lock); 1200 1201 server->mount_time = jiffies; 1202 1203 dprintk("<-- nfs_create_referral_server() = %p\n", server); 1204 return server; 1205 1206 error: 1207 nfs_free_server(server); 1208 dprintk("<-- nfs4_create_referral_server() = error %d\n", error); 1209 return ERR_PTR(error); 1210 } 1211 1212 #endif /* CONFIG_NFS_V4 */ 1213 1214 /* 1215 * Clone an NFS2, NFS3 or NFS4 server record 1216 */ 1217 struct nfs_server *nfs_clone_server(struct nfs_server *source, 1218 struct nfs_fh *fh, 1219 struct nfs_fattr *fattr) 1220 { 1221 struct nfs_server *server; 1222 struct nfs_fattr fattr_fsinfo; 1223 int error; 1224 1225 dprintk("--> nfs_clone_server(,%llx:%llx,)\n", 1226 (unsigned long long) fattr->fsid.major, 1227 (unsigned long long) fattr->fsid.minor); 1228 1229 server = nfs_alloc_server(); 1230 if (!server) 1231 return ERR_PTR(-ENOMEM); 1232 1233 /* Copy data from the source */ 1234 server->nfs_client = source->nfs_client; 1235 atomic_inc(&server->nfs_client->cl_count); 1236 nfs_server_copy_userdata(server, source); 1237 1238 server->fsid = fattr->fsid; 1239 1240 error = nfs_init_server_rpcclient(server, 1241 source->client->cl_timeout, 1242 source->client->cl_auth->au_flavor); 1243 if (error < 0) 1244 goto out_free_server; 1245 if (!IS_ERR(source->client_acl)) 1246 nfs_init_server_aclclient(server); 1247 1248 /* probe the filesystem info for this server filesystem */ 1249 error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo); 1250 if (error < 0) 1251 goto out_free_server; 1252 1253 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) 1254 server->namelen = NFS4_MAXNAMLEN; 1255 1256 dprintk("Cloned FSID: %llx:%llx\n", 1257 (unsigned long long) server->fsid.major, 1258 (unsigned long long) server->fsid.minor); 1259 1260 error = nfs_start_lockd(server); 1261 if (error < 0) 1262 goto out_free_server; 1263 1264 spin_lock(&nfs_client_lock); 1265 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); 1266 list_add_tail(&server->master_link, &nfs_volume_list); 1267 spin_unlock(&nfs_client_lock); 1268 1269 server->mount_time = jiffies; 1270 1271 dprintk("<-- nfs_clone_server() = %p\n", server); 1272 return server; 1273 1274 out_free_server: 1275 nfs_free_server(server); 1276 dprintk("<-- nfs_clone_server() = error %d\n", error); 1277 return ERR_PTR(error); 1278 } 1279 1280 #ifdef CONFIG_PROC_FS 1281 static struct proc_dir_entry *proc_fs_nfs; 1282 1283 static int nfs_server_list_open(struct inode *inode, struct file *file); 1284 static void *nfs_server_list_start(struct seq_file *p, loff_t *pos); 1285 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos); 1286 static void nfs_server_list_stop(struct seq_file *p, void *v); 1287 static int nfs_server_list_show(struct seq_file *m, void *v); 1288 1289 static struct seq_operations nfs_server_list_ops = { 1290 .start = nfs_server_list_start, 1291 .next = nfs_server_list_next, 1292 .stop = nfs_server_list_stop, 1293 .show = nfs_server_list_show, 1294 }; 1295 1296 static const struct file_operations nfs_server_list_fops = { 1297 .open = nfs_server_list_open, 1298 .read = seq_read, 1299 .llseek = seq_lseek, 1300 .release = seq_release, 1301 }; 1302 1303 static int nfs_volume_list_open(struct inode *inode, struct file *file); 1304 static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos); 1305 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos); 1306 static void nfs_volume_list_stop(struct seq_file *p, void *v); 1307 static int nfs_volume_list_show(struct seq_file *m, void *v); 1308 1309 static struct seq_operations nfs_volume_list_ops = { 1310 .start = nfs_volume_list_start, 1311 .next = nfs_volume_list_next, 1312 .stop = nfs_volume_list_stop, 1313 .show = nfs_volume_list_show, 1314 }; 1315 1316 static const struct file_operations nfs_volume_list_fops = { 1317 .open = nfs_volume_list_open, 1318 .read = seq_read, 1319 .llseek = seq_lseek, 1320 .release = seq_release, 1321 }; 1322 1323 /* 1324 * open "/proc/fs/nfsfs/servers" which provides a summary of servers with which 1325 * we're dealing 1326 */ 1327 static int nfs_server_list_open(struct inode *inode, struct file *file) 1328 { 1329 struct seq_file *m; 1330 int ret; 1331 1332 ret = seq_open(file, &nfs_server_list_ops); 1333 if (ret < 0) 1334 return ret; 1335 1336 m = file->private_data; 1337 m->private = PDE(inode)->data; 1338 1339 return 0; 1340 } 1341 1342 /* 1343 * set up the iterator to start reading from the server list and return the first item 1344 */ 1345 static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos) 1346 { 1347 /* lock the list against modification */ 1348 spin_lock(&nfs_client_lock); 1349 return seq_list_start_head(&nfs_client_list, *_pos); 1350 } 1351 1352 /* 1353 * move to next server 1354 */ 1355 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos) 1356 { 1357 return seq_list_next(v, &nfs_client_list, pos); 1358 } 1359 1360 /* 1361 * clean up after reading from the transports list 1362 */ 1363 static void nfs_server_list_stop(struct seq_file *p, void *v) 1364 { 1365 spin_unlock(&nfs_client_lock); 1366 } 1367 1368 /* 1369 * display a header line followed by a load of call lines 1370 */ 1371 static int nfs_server_list_show(struct seq_file *m, void *v) 1372 { 1373 struct nfs_client *clp; 1374 1375 /* display header on line 1 */ 1376 if (v == &nfs_client_list) { 1377 seq_puts(m, "NV SERVER PORT USE HOSTNAME\n"); 1378 return 0; 1379 } 1380 1381 /* display one transport per line on subsequent lines */ 1382 clp = list_entry(v, struct nfs_client, cl_share_link); 1383 1384 seq_printf(m, "v%u %s %s %3d %s\n", 1385 clp->rpc_ops->version, 1386 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), 1387 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT), 1388 atomic_read(&clp->cl_count), 1389 clp->cl_hostname); 1390 1391 return 0; 1392 } 1393 1394 /* 1395 * open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes 1396 */ 1397 static int nfs_volume_list_open(struct inode *inode, struct file *file) 1398 { 1399 struct seq_file *m; 1400 int ret; 1401 1402 ret = seq_open(file, &nfs_volume_list_ops); 1403 if (ret < 0) 1404 return ret; 1405 1406 m = file->private_data; 1407 m->private = PDE(inode)->data; 1408 1409 return 0; 1410 } 1411 1412 /* 1413 * set up the iterator to start reading from the volume list and return the first item 1414 */ 1415 static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos) 1416 { 1417 /* lock the list against modification */ 1418 spin_lock(&nfs_client_lock); 1419 return seq_list_start_head(&nfs_volume_list, *_pos); 1420 } 1421 1422 /* 1423 * move to next volume 1424 */ 1425 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos) 1426 { 1427 return seq_list_next(v, &nfs_volume_list, pos); 1428 } 1429 1430 /* 1431 * clean up after reading from the transports list 1432 */ 1433 static void nfs_volume_list_stop(struct seq_file *p, void *v) 1434 { 1435 spin_unlock(&nfs_client_lock); 1436 } 1437 1438 /* 1439 * display a header line followed by a load of call lines 1440 */ 1441 static int nfs_volume_list_show(struct seq_file *m, void *v) 1442 { 1443 struct nfs_server *server; 1444 struct nfs_client *clp; 1445 char dev[8], fsid[17]; 1446 1447 /* display header on line 1 */ 1448 if (v == &nfs_volume_list) { 1449 seq_puts(m, "NV SERVER PORT DEV FSID\n"); 1450 return 0; 1451 } 1452 /* display one transport per line on subsequent lines */ 1453 server = list_entry(v, struct nfs_server, master_link); 1454 clp = server->nfs_client; 1455 1456 snprintf(dev, 8, "%u:%u", 1457 MAJOR(server->s_dev), MINOR(server->s_dev)); 1458 1459 snprintf(fsid, 17, "%llx:%llx", 1460 (unsigned long long) server->fsid.major, 1461 (unsigned long long) server->fsid.minor); 1462 1463 seq_printf(m, "v%u %s %s %-7s %-17s\n", 1464 clp->rpc_ops->version, 1465 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), 1466 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT), 1467 dev, 1468 fsid); 1469 1470 return 0; 1471 } 1472 1473 /* 1474 * initialise the /proc/fs/nfsfs/ directory 1475 */ 1476 int __init nfs_fs_proc_init(void) 1477 { 1478 struct proc_dir_entry *p; 1479 1480 proc_fs_nfs = proc_mkdir("nfsfs", proc_root_fs); 1481 if (!proc_fs_nfs) 1482 goto error_0; 1483 1484 proc_fs_nfs->owner = THIS_MODULE; 1485 1486 /* a file of servers with which we're dealing */ 1487 p = create_proc_entry("servers", S_IFREG|S_IRUGO, proc_fs_nfs); 1488 if (!p) 1489 goto error_1; 1490 1491 p->proc_fops = &nfs_server_list_fops; 1492 p->owner = THIS_MODULE; 1493 1494 /* a file of volumes that we have mounted */ 1495 p = create_proc_entry("volumes", S_IFREG|S_IRUGO, proc_fs_nfs); 1496 if (!p) 1497 goto error_2; 1498 1499 p->proc_fops = &nfs_volume_list_fops; 1500 p->owner = THIS_MODULE; 1501 return 0; 1502 1503 error_2: 1504 remove_proc_entry("servers", proc_fs_nfs); 1505 error_1: 1506 remove_proc_entry("nfsfs", proc_root_fs); 1507 error_0: 1508 return -ENOMEM; 1509 } 1510 1511 /* 1512 * clean up the /proc/fs/nfsfs/ directory 1513 */ 1514 void nfs_fs_proc_exit(void) 1515 { 1516 remove_proc_entry("volumes", proc_fs_nfs); 1517 remove_proc_entry("servers", proc_fs_nfs); 1518 remove_proc_entry("nfsfs", proc_root_fs); 1519 } 1520 1521 #endif /* CONFIG_PROC_FS */ 1522