aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-06-22 14:13:12 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-06-30 15:29:56 -0400
commit5c6e5b60aae4347223f176966455010a5715b863 (patch)
treeb194f61231b17bb8023c374076b2a27bc5f95edb
parent1a0a02d1efa066001fd315c1b4df583d939fa2c4 (diff)
NFS: Fix an Oops in the pNFS files and flexfiles connection setup to the DS
Chris Worley reports: RIP: 0010:[<ffffffffa0245f80>] [<ffffffffa0245f80>] rpc_new_client+0x2a0/0x2e0 [sunrpc] RSP: 0018:ffff880158f6f548 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff880234f8bc00 RCX: 000000000000ea60 RDX: 0000000000074cc0 RSI: 000000000000ea60 RDI: ffff880234f8bcf0 RBP: ffff880158f6f588 R08: 000000000001ac80 R09: ffff880237003300 R10: ffff880201171000 R11: ffffea0000d75200 R12: ffffffffa03afc60 R13: ffff880230c18800 R14: 0000000000000000 R15: ffff880158f6f680 FS: 00007f0e32673740(0000) GS:ffff88023fc40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000008 CR3: 0000000234886000 CR4: 00000000001406e0 Stack: ffffffffa047a680 0000000000000000 ffff880158f6f598 ffff880158f6f680 ffff880158f6f680 ffff880234d11d00 ffff88023357f800 ffff880158f6f7d0 ffff880158f6f5b8 ffffffffa024660a ffff880158f6f5b8 ffffffffa02492ec Call Trace: [<ffffffffa024660a>] rpc_create_xprt+0x1a/0xb0 [sunrpc] [<ffffffffa02492ec>] ? xprt_create_transport+0x13c/0x240 [sunrpc] [<ffffffffa0246766>] rpc_create+0xc6/0x1a0 [sunrpc] [<ffffffffa038e695>] nfs_create_rpc_client+0xf5/0x140 [nfs] [<ffffffffa038f31a>] nfs_init_client+0x3a/0xd0 [nfs] [<ffffffffa038f22f>] nfs_get_client+0x25f/0x310 [nfs] [<ffffffffa025cef8>] ? rpc_ntop+0xe8/0x100 [sunrpc] [<ffffffffa047512c>] nfs3_set_ds_client+0xcc/0x100 [nfsv3] [<ffffffffa041fa10>] nfs4_pnfs_ds_connect+0x120/0x400 [nfsv4] [<ffffffffa03d41c7>] nfs4_ff_layout_prepare_ds+0xe7/0x330 [nfs_layout_flexfiles] [<ffffffffa03d1b1b>] ff_layout_pg_init_write+0xcb/0x280 [nfs_layout_flexfiles] [<ffffffffa03a14dc>] __nfs_pageio_add_request+0x12c/0x490 [nfs] [<ffffffffa03a1fa2>] nfs_pageio_add_request+0xc2/0x2a0 [nfs] [<ffffffffa03a0365>] ? nfs_pageio_init+0x75/0x120 [nfs] [<ffffffffa03a5b50>] nfs_do_writepage+0x120/0x270 [nfs] [<ffffffffa03a5d31>] nfs_writepage_locked+0x61/0xc0 [nfs] [<ffffffff813d4115>] ? __percpu_counter_add+0x55/0x70 [<ffffffffa03a6a9f>] nfs_wb_single_page+0xef/0x1c0 [nfs] [<ffffffff811ca4a3>] ? __dec_zone_page_state+0x33/0x40 [<ffffffffa0395b21>] nfs_launder_page+0x41/0x90 [nfs] [<ffffffff811baba0>] invalidate_inode_pages2_range+0x340/0x3a0 [<ffffffff811bac17>] invalidate_inode_pages2+0x17/0x20 [<ffffffffa039960e>] nfs_release+0x9e/0xb0 [nfs] [<ffffffffa0399570>] ? nfs_open+0x60/0x60 [nfs] [<ffffffffa0394dad>] nfs_file_release+0x3d/0x60 [nfs] [<ffffffff81226e6c>] __fput+0xdc/0x1e0 [<ffffffff81226fbe>] ____fput+0xe/0x10 [<ffffffff810bf2e4>] task_work_run+0xc4/0xe0 [<ffffffff810a4188>] do_exit+0x2e8/0xb30 [<ffffffff8102471c>] ? do_audit_syscall_entry+0x6c/0x70 [<ffffffff811464e6>] ? __audit_syscall_exit+0x1e6/0x280 [<ffffffff810a4a5f>] do_group_exit+0x3f/0xa0 [<ffffffff810a4ad4>] SyS_exit_group+0x14/0x20 [<ffffffff8179b76e>] system_call_fastpath+0x12/0x71 Which seems to be due to a call to utsname() when in a task exit context in order to determine the hostname to set in rpc_new_client(). In reality, what we want here is not the hostname of the current task, but the hostname that was used to set up the metadata server. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/client.c22
-rw-r--r--fs/nfs/internal.h16
-rw-r--r--fs/nfs/nfs3client.c8
-rw-r--r--fs/nfs/nfs4client.c20
-rw-r--r--include/linux/nfs_xdr.h5
5 files changed, 37 insertions, 34 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 0c96528db94a..4849d0f778dc 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -367,8 +367,6 @@ nfs_found_client(const struct nfs_client_initdata *cl_init,
367 */ 367 */
368struct nfs_client * 368struct nfs_client *
369nfs_get_client(const struct nfs_client_initdata *cl_init, 369nfs_get_client(const struct nfs_client_initdata *cl_init,
370 const struct rpc_timeout *timeparms,
371 const char *ip_addr,
372 rpc_authflavor_t authflavour) 370 rpc_authflavor_t authflavour)
373{ 371{
374 struct nfs_client *clp, *new = NULL; 372 struct nfs_client *clp, *new = NULL;
@@ -399,7 +397,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
399 &nn->nfs_client_list); 397 &nn->nfs_client_list);
400 spin_unlock(&nn->nfs_client_lock); 398 spin_unlock(&nn->nfs_client_lock);
401 new->cl_flags = cl_init->init_flags; 399 new->cl_flags = cl_init->init_flags;
402 return rpc_ops->init_client(new, timeparms, ip_addr); 400 return rpc_ops->init_client(new, cl_init);
403 } 401 }
404 402
405 spin_unlock(&nn->nfs_client_lock); 403 spin_unlock(&nn->nfs_client_lock);
@@ -470,7 +468,7 @@ EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
470 * Create an RPC client handle 468 * Create an RPC client handle
471 */ 469 */
472int nfs_create_rpc_client(struct nfs_client *clp, 470int nfs_create_rpc_client(struct nfs_client *clp,
473 const struct rpc_timeout *timeparms, 471 const struct nfs_client_initdata *cl_init,
474 rpc_authflavor_t flavor) 472 rpc_authflavor_t flavor)
475{ 473{
476 struct rpc_clnt *clnt = NULL; 474 struct rpc_clnt *clnt = NULL;
@@ -479,8 +477,9 @@ int nfs_create_rpc_client(struct nfs_client *clp,
479 .protocol = clp->cl_proto, 477 .protocol = clp->cl_proto,
480 .address = (struct sockaddr *)&clp->cl_addr, 478 .address = (struct sockaddr *)&clp->cl_addr,
481 .addrsize = clp->cl_addrlen, 479 .addrsize = clp->cl_addrlen,
482 .timeout = timeparms, 480 .timeout = cl_init->timeparms,
483 .servername = clp->cl_hostname, 481 .servername = clp->cl_hostname,
482 .nodename = cl_init->nodename,
484 .program = &nfs_program, 483 .program = &nfs_program,
485 .version = clp->rpc_ops->version, 484 .version = clp->rpc_ops->version,
486 .authflavor = flavor, 485 .authflavor = flavor,
@@ -591,14 +590,12 @@ EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
591 * nfs_init_client - Initialise an NFS2 or NFS3 client 590 * nfs_init_client - Initialise an NFS2 or NFS3 client
592 * 591 *
593 * @clp: nfs_client to initialise 592 * @clp: nfs_client to initialise
594 * @timeparms: timeout parameters for underlying RPC transport 593 * @cl_init: Initialisation parameters
595 * @ip_addr: IP presentation address (not used)
596 * 594 *
597 * Returns pointer to an NFS client, or an ERR_PTR value. 595 * Returns pointer to an NFS client, or an ERR_PTR value.
598 */ 596 */
599struct nfs_client *nfs_init_client(struct nfs_client *clp, 597struct nfs_client *nfs_init_client(struct nfs_client *clp,
600 const struct rpc_timeout *timeparms, 598 const struct nfs_client_initdata *cl_init)
601 const char *ip_addr)
602{ 599{
603 int error; 600 int error;
604 601
@@ -612,7 +609,7 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
612 * Create a client RPC handle for doing FSSTAT with UNIX auth only 609 * Create a client RPC handle for doing FSSTAT with UNIX auth only
613 * - RFC 2623, sec 2.3.2 610 * - RFC 2623, sec 2.3.2
614 */ 611 */
615 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); 612 error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
616 if (error < 0) 613 if (error < 0)
617 goto error; 614 goto error;
618 nfs_mark_client_ready(clp, NFS_CS_READY); 615 nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -633,6 +630,7 @@ static int nfs_init_server(struct nfs_server *server,
633 const struct nfs_parsed_mount_data *data, 630 const struct nfs_parsed_mount_data *data,
634 struct nfs_subversion *nfs_mod) 631 struct nfs_subversion *nfs_mod)
635{ 632{
633 struct rpc_timeout timeparms;
636 struct nfs_client_initdata cl_init = { 634 struct nfs_client_initdata cl_init = {
637 .hostname = data->nfs_server.hostname, 635 .hostname = data->nfs_server.hostname,
638 .addr = (const struct sockaddr *)&data->nfs_server.address, 636 .addr = (const struct sockaddr *)&data->nfs_server.address,
@@ -640,8 +638,8 @@ static int nfs_init_server(struct nfs_server *server,
640 .nfs_mod = nfs_mod, 638 .nfs_mod = nfs_mod,
641 .proto = data->nfs_server.protocol, 639 .proto = data->nfs_server.protocol,
642 .net = data->net, 640 .net = data->net,
641 .timeparms = &timeparms,
643 }; 642 };
644 struct rpc_timeout timeparms;
645 struct nfs_client *clp; 643 struct nfs_client *clp;
646 int error; 644 int error;
647 645
@@ -653,7 +651,7 @@ static int nfs_init_server(struct nfs_server *server,
653 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); 651 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
654 652
655 /* Allocate or find a client reference we can use */ 653 /* Allocate or find a client reference we can use */
656 clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX); 654 clp = nfs_get_client(&cl_init, RPC_AUTH_UNIX);
657 if (IS_ERR(clp)) { 655 if (IS_ERR(clp)) {
658 dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); 656 dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
659 return PTR_ERR(clp); 657 return PTR_ERR(clp);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 5154fa65a2f2..fa88609f85e3 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -66,13 +66,16 @@ struct nfs_clone_mount {
66 66
67struct nfs_client_initdata { 67struct nfs_client_initdata {
68 unsigned long init_flags; 68 unsigned long init_flags;
69 const char *hostname; 69 const char *hostname; /* Hostname of the server */
70 const struct sockaddr *addr; 70 const struct sockaddr *addr; /* Address of the server */
71 const char *nodename; /* Hostname of the client */
72 const char *ip_addr; /* IP address of the client */
71 size_t addrlen; 73 size_t addrlen;
72 struct nfs_subversion *nfs_mod; 74 struct nfs_subversion *nfs_mod;
73 int proto; 75 int proto;
74 u32 minorversion; 76 u32 minorversion;
75 struct net *net; 77 struct net *net;
78 const struct rpc_timeout *timeparms;
76}; 79};
77 80
78/* 81/*
@@ -147,9 +150,8 @@ extern void nfs_umount(const struct nfs_mount_request *info);
147extern const struct rpc_program nfs_program; 150extern const struct rpc_program nfs_program;
148extern void nfs_clients_init(struct net *net); 151extern void nfs_clients_init(struct net *net);
149extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *); 152extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
150int nfs_create_rpc_client(struct nfs_client *, const struct rpc_timeout *, rpc_authflavor_t); 153int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
151struct nfs_client *nfs_get_client(const struct nfs_client_initdata *, 154struct nfs_client *nfs_get_client(const struct nfs_client_initdata *,
152 const struct rpc_timeout *, const char *,
153 rpc_authflavor_t); 155 rpc_authflavor_t);
154int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *); 156int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
155void nfs_server_insert_lists(struct nfs_server *); 157void nfs_server_insert_lists(struct nfs_server *);
@@ -338,8 +340,7 @@ nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
338/* proc.c */ 340/* proc.c */
339void nfs_close_context(struct nfs_open_context *ctx, int is_sync); 341void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
340extern struct nfs_client *nfs_init_client(struct nfs_client *clp, 342extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
341 const struct rpc_timeout *timeparms, 343 const struct nfs_client_initdata *);
342 const char *ip_addr);
343 344
344/* dir.c */ 345/* dir.c */
345extern void nfs_force_use_readdirplus(struct inode *dir); 346extern void nfs_force_use_readdirplus(struct inode *dir);
@@ -521,8 +522,7 @@ extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
521/* nfs4proc.c */ 522/* nfs4proc.c */
522extern void __nfs4_read_done_cb(struct nfs_pgio_header *); 523extern void __nfs4_read_done_cb(struct nfs_pgio_header *);
523extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, 524extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
524 const struct rpc_timeout *timeparms, 525 const struct nfs_client_initdata *);
525 const char *ip_addr);
526extern int nfs40_walk_client_list(struct nfs_client *clp, 526extern int nfs40_walk_client_list(struct nfs_client *clp,
527 struct nfs_client **result, 527 struct nfs_client **result,
528 struct rpc_cred *cred); 528 struct rpc_cred *cred);
diff --git a/fs/nfs/nfs3client.c b/fs/nfs/nfs3client.c
index 9e9fa347a948..0457b4129421 100644
--- a/fs/nfs/nfs3client.c
+++ b/fs/nfs/nfs3client.c
@@ -81,14 +81,17 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_client *mds_clp,
81 int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans, 81 int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans,
82 rpc_authflavor_t au_flavor) 82 rpc_authflavor_t au_flavor)
83{ 83{
84 struct rpc_timeout ds_timeout;
84 struct nfs_client_initdata cl_init = { 85 struct nfs_client_initdata cl_init = {
85 .addr = ds_addr, 86 .addr = ds_addr,
86 .addrlen = ds_addrlen, 87 .addrlen = ds_addrlen,
88 .nodename = mds_clp->cl_rpcclient->cl_nodename,
89 .ip_addr = mds_clp->cl_ipaddr,
87 .nfs_mod = &nfs_v3, 90 .nfs_mod = &nfs_v3,
88 .proto = ds_proto, 91 .proto = ds_proto,
89 .net = mds_clp->cl_net, 92 .net = mds_clp->cl_net,
93 .timeparms = &ds_timeout,
90 }; 94 };
91 struct rpc_timeout ds_timeout;
92 struct nfs_client *clp; 95 struct nfs_client *clp;
93 char buf[INET6_ADDRSTRLEN + 1]; 96 char buf[INET6_ADDRSTRLEN + 1];
94 97
@@ -99,8 +102,7 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_client *mds_clp,
99 102
100 /* Use the MDS nfs_client cl_ipaddr. */ 103 /* Use the MDS nfs_client cl_ipaddr. */
101 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans); 104 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
102 clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr, 105 clp = nfs_get_client(&cl_init, au_flavor);
103 au_flavor);
104 106
105 return clp; 107 return clp;
106} 108}
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 10410e8b5853..5fc7fbbfdcef 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -349,10 +349,10 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
349 * Returns pointer to an NFS client, or an ERR_PTR value. 349 * Returns pointer to an NFS client, or an ERR_PTR value.
350 */ 350 */
351struct nfs_client *nfs4_init_client(struct nfs_client *clp, 351struct nfs_client *nfs4_init_client(struct nfs_client *clp,
352 const struct rpc_timeout *timeparms, 352 const struct nfs_client_initdata *cl_init)
353 const char *ip_addr)
354{ 353{
355 char buf[INET6_ADDRSTRLEN + 1]; 354 char buf[INET6_ADDRSTRLEN + 1];
355 const char *ip_addr = cl_init->ip_addr;
356 struct nfs_client *old; 356 struct nfs_client *old;
357 int error; 357 int error;
358 358
@@ -370,9 +370,9 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
370 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 370 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
371 __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); 371 __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
372 372
373 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); 373 error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_GSS_KRB5I);
374 if (error == -EINVAL) 374 if (error == -EINVAL)
375 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); 375 error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
376 if (error < 0) 376 if (error < 0)
377 goto error; 377 goto error;
378 378
@@ -793,10 +793,12 @@ static int nfs4_set_client(struct nfs_server *server,
793 .hostname = hostname, 793 .hostname = hostname,
794 .addr = addr, 794 .addr = addr,
795 .addrlen = addrlen, 795 .addrlen = addrlen,
796 .ip_addr = ip_addr,
796 .nfs_mod = &nfs_v4, 797 .nfs_mod = &nfs_v4,
797 .proto = proto, 798 .proto = proto,
798 .minorversion = minorversion, 799 .minorversion = minorversion,
799 .net = net, 800 .net = net,
801 .timeparms = timeparms,
800 }; 802 };
801 struct nfs_client *clp; 803 struct nfs_client *clp;
802 int error; 804 int error;
@@ -809,7 +811,7 @@ static int nfs4_set_client(struct nfs_server *server,
809 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags); 811 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
810 812
811 /* Allocate or find a client reference we can use */ 813 /* Allocate or find a client reference we can use */
812 clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour); 814 clp = nfs_get_client(&cl_init, authflavour);
813 if (IS_ERR(clp)) { 815 if (IS_ERR(clp)) {
814 error = PTR_ERR(clp); 816 error = PTR_ERR(clp);
815 goto error; 817 goto error;
@@ -847,15 +849,18 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
847 int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans, 849 int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans,
848 u32 minor_version, rpc_authflavor_t au_flavor) 850 u32 minor_version, rpc_authflavor_t au_flavor)
849{ 851{
852 struct rpc_timeout ds_timeout;
850 struct nfs_client_initdata cl_init = { 853 struct nfs_client_initdata cl_init = {
851 .addr = ds_addr, 854 .addr = ds_addr,
852 .addrlen = ds_addrlen, 855 .addrlen = ds_addrlen,
856 .nodename = mds_clp->cl_rpcclient->cl_nodename,
857 .ip_addr = mds_clp->cl_ipaddr,
853 .nfs_mod = &nfs_v4, 858 .nfs_mod = &nfs_v4,
854 .proto = ds_proto, 859 .proto = ds_proto,
855 .minorversion = minor_version, 860 .minorversion = minor_version,
856 .net = mds_clp->cl_net, 861 .net = mds_clp->cl_net,
862 .timeparms = &ds_timeout,
857 }; 863 };
858 struct rpc_timeout ds_timeout;
859 struct nfs_client *clp; 864 struct nfs_client *clp;
860 char buf[INET6_ADDRSTRLEN + 1]; 865 char buf[INET6_ADDRSTRLEN + 1];
861 866
@@ -869,8 +874,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
869 * (section 13.1 RFC 5661). 874 * (section 13.1 RFC 5661).
870 */ 875 */
871 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans); 876 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
872 clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr, 877 clp = nfs_get_client(&cl_init, au_flavor);
873 au_flavor);
874 878
875 dprintk("<-- %s %p\n", __func__, clp); 879 dprintk("<-- %s %p\n", __func__, clp);
876 return clp; 880 return clp;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index c304a11b5b1a..82b81a1c2438 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1596,9 +1596,8 @@ struct nfs_rpc_ops {
1596 int (*have_delegation)(struct inode *, fmode_t); 1596 int (*have_delegation)(struct inode *, fmode_t);
1597 int (*return_delegation)(struct inode *); 1597 int (*return_delegation)(struct inode *);
1598 struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *); 1598 struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *);
1599 struct nfs_client * 1599 struct nfs_client *(*init_client) (struct nfs_client *,
1600 (*init_client) (struct nfs_client *, const struct rpc_timeout *, 1600 const struct nfs_client_initdata *);
1601 const char *);
1602 void (*free_client) (struct nfs_client *); 1601 void (*free_client) (struct nfs_client *);
1603 struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *); 1602 struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *);
1604 struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, 1603 struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,