aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c425
1 files changed, 354 insertions, 71 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0a07e353a961..dfd1e6d7e6c3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -41,6 +41,7 @@
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/sunrpc/clnt.h> 43#include <linux/sunrpc/clnt.h>
44#include <linux/sunrpc/gss_api.h>
44#include <linux/nfs.h> 45#include <linux/nfs.h>
45#include <linux/nfs4.h> 46#include <linux/nfs4.h>
46#include <linux/nfs_fs.h> 47#include <linux/nfs_fs.h>
@@ -71,7 +72,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data);
71static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 72static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
72static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 73static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
73static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 74static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
74static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 75static int _nfs4_proc_lookup(struct rpc_clnt *client, struct inode *dir,
76 const struct qstr *name, struct nfs_fh *fhandle,
77 struct nfs_fattr *fattr);
75static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 78static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
76static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 79static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
77 struct nfs_fattr *fattr, struct iattr *sattr, 80 struct nfs_fattr *fattr, struct iattr *sattr,
@@ -85,6 +88,11 @@ static int nfs4_map_errors(int err)
85 switch (err) { 88 switch (err) {
86 case -NFS4ERR_RESOURCE: 89 case -NFS4ERR_RESOURCE:
87 return -EREMOTEIO; 90 return -EREMOTEIO;
91 case -NFS4ERR_WRONGSEC:
92 return -EPERM;
93 case -NFS4ERR_BADOWNER:
94 case -NFS4ERR_BADNAME:
95 return -EINVAL;
88 default: 96 default:
89 dprintk("%s could not handle NFSv4 error %d\n", 97 dprintk("%s could not handle NFSv4 error %d\n",
90 __func__, -err); 98 __func__, -err);
@@ -241,7 +249,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
241/* This is the error handling routine for processes that are allowed 249/* This is the error handling routine for processes that are allowed
242 * to sleep. 250 * to sleep.
243 */ 251 */
244static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) 252static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
245{ 253{
246 struct nfs_client *clp = server->nfs_client; 254 struct nfs_client *clp = server->nfs_client;
247 struct nfs4_state *state = exception->state; 255 struct nfs4_state *state = exception->state;
@@ -293,6 +301,19 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
293 break; 301 break;
294 case -NFS4ERR_OLD_STATEID: 302 case -NFS4ERR_OLD_STATEID:
295 exception->retry = 1; 303 exception->retry = 1;
304 break;
305 case -NFS4ERR_BADOWNER:
306 /* The following works around a Linux server bug! */
307 case -NFS4ERR_BADNAME:
308 if (server->caps & NFS_CAP_UIDGID_NOMAP) {
309 server->caps &= ~NFS_CAP_UIDGID_NOMAP;
310 exception->retry = 1;
311 printk(KERN_WARNING "NFS: v4 server %s "
312 "does not accept raw "
313 "uid/gids. "
314 "Reenabling the idmapper.\n",
315 server->nfs_client->cl_hostname);
316 }
296 } 317 }
297 /* We failed to handle the error */ 318 /* We failed to handle the error */
298 return nfs4_map_errors(ret); 319 return nfs4_map_errors(ret);
@@ -505,7 +526,7 @@ out:
505 return ret_id; 526 return ret_id;
506} 527}
507 528
508static int nfs41_setup_sequence(struct nfs4_session *session, 529int nfs41_setup_sequence(struct nfs4_session *session,
509 struct nfs4_sequence_args *args, 530 struct nfs4_sequence_args *args,
510 struct nfs4_sequence_res *res, 531 struct nfs4_sequence_res *res,
511 int cache_reply, 532 int cache_reply,
@@ -571,6 +592,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
571 res->sr_status = 1; 592 res->sr_status = 1;
572 return 0; 593 return 0;
573} 594}
595EXPORT_SYMBOL_GPL(nfs41_setup_sequence);
574 596
575int nfs4_setup_sequence(const struct nfs_server *server, 597int nfs4_setup_sequence(const struct nfs_server *server,
576 struct nfs4_sequence_args *args, 598 struct nfs4_sequence_args *args,
@@ -640,7 +662,8 @@ struct rpc_call_ops nfs41_call_priv_sync_ops = {
640 .rpc_call_done = nfs41_call_sync_done, 662 .rpc_call_done = nfs41_call_sync_done,
641}; 663};
642 664
643static int nfs4_call_sync_sequence(struct nfs_server *server, 665static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
666 struct nfs_server *server,
644 struct rpc_message *msg, 667 struct rpc_message *msg,
645 struct nfs4_sequence_args *args, 668 struct nfs4_sequence_args *args,
646 struct nfs4_sequence_res *res, 669 struct nfs4_sequence_res *res,
@@ -656,7 +679,7 @@ static int nfs4_call_sync_sequence(struct nfs_server *server,
656 .cache_reply = cache_reply, 679 .cache_reply = cache_reply,
657 }; 680 };
658 struct rpc_task_setup task_setup = { 681 struct rpc_task_setup task_setup = {
659 .rpc_client = server->client, 682 .rpc_client = clnt,
660 .rpc_message = msg, 683 .rpc_message = msg,
661 .callback_ops = &nfs41_call_sync_ops, 684 .callback_ops = &nfs41_call_sync_ops,
662 .callback_data = &data 685 .callback_data = &data
@@ -675,13 +698,14 @@ static int nfs4_call_sync_sequence(struct nfs_server *server,
675 return ret; 698 return ret;
676} 699}
677 700
678int _nfs4_call_sync_session(struct nfs_server *server, 701int _nfs4_call_sync_session(struct rpc_clnt *clnt,
702 struct nfs_server *server,
679 struct rpc_message *msg, 703 struct rpc_message *msg,
680 struct nfs4_sequence_args *args, 704 struct nfs4_sequence_args *args,
681 struct nfs4_sequence_res *res, 705 struct nfs4_sequence_res *res,
682 int cache_reply) 706 int cache_reply)
683{ 707{
684 return nfs4_call_sync_sequence(server, msg, args, res, cache_reply, 0); 708 return nfs4_call_sync_sequence(clnt, server, msg, args, res, cache_reply, 0);
685} 709}
686 710
687#else 711#else
@@ -692,19 +716,28 @@ static int nfs4_sequence_done(struct rpc_task *task,
692} 716}
693#endif /* CONFIG_NFS_V4_1 */ 717#endif /* CONFIG_NFS_V4_1 */
694 718
695int _nfs4_call_sync(struct nfs_server *server, 719int _nfs4_call_sync(struct rpc_clnt *clnt,
720 struct nfs_server *server,
696 struct rpc_message *msg, 721 struct rpc_message *msg,
697 struct nfs4_sequence_args *args, 722 struct nfs4_sequence_args *args,
698 struct nfs4_sequence_res *res, 723 struct nfs4_sequence_res *res,
699 int cache_reply) 724 int cache_reply)
700{ 725{
701 args->sa_session = res->sr_session = NULL; 726 args->sa_session = res->sr_session = NULL;
702 return rpc_call_sync(server->client, msg, 0); 727 return rpc_call_sync(clnt, msg, 0);
703} 728}
704 729
705#define nfs4_call_sync(server, msg, args, res, cache_reply) \ 730static inline
706 (server)->nfs_client->cl_mvops->call_sync((server), (msg), &(args)->seq_args, \ 731int nfs4_call_sync(struct rpc_clnt *clnt,
707 &(res)->seq_res, (cache_reply)) 732 struct nfs_server *server,
733 struct rpc_message *msg,
734 struct nfs4_sequence_args *args,
735 struct nfs4_sequence_res *res,
736 int cache_reply)
737{
738 return server->nfs_client->cl_mvops->call_sync(clnt, server, msg,
739 args, res, cache_reply);
740}
708 741
709static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 742static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
710{ 743{
@@ -1573,9 +1606,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1573 return 0; 1606 return 0;
1574} 1607}
1575 1608
1576static int nfs4_recover_expired_lease(struct nfs_server *server) 1609static int nfs4_client_recover_expired_lease(struct nfs_client *clp)
1577{ 1610{
1578 struct nfs_client *clp = server->nfs_client;
1579 unsigned int loop; 1611 unsigned int loop;
1580 int ret; 1612 int ret;
1581 1613
@@ -1592,6 +1624,11 @@ static int nfs4_recover_expired_lease(struct nfs_server *server)
1592 return ret; 1624 return ret;
1593} 1625}
1594 1626
1627static int nfs4_recover_expired_lease(struct nfs_server *server)
1628{
1629 return nfs4_client_recover_expired_lease(server->nfs_client);
1630}
1631
1595/* 1632/*
1596 * OPEN_EXPIRED: 1633 * OPEN_EXPIRED:
1597 * reclaim state on the server after a network partition. 1634 * reclaim state on the server after a network partition.
@@ -1810,7 +1847,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
1810 } else 1847 } else
1811 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); 1848 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
1812 1849
1813 status = nfs4_call_sync(server, &msg, &arg, &res, 1); 1850 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
1814 if (status == 0 && state != NULL) 1851 if (status == 0 && state != NULL)
1815 renew_lease(server, timestamp); 1852 renew_lease(server, timestamp);
1816 return status; 1853 return status;
@@ -2069,7 +2106,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
2069 }; 2106 };
2070 int status; 2107 int status;
2071 2108
2072 status = nfs4_call_sync(server, &msg, &args, &res, 0); 2109 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2073 if (status == 0) { 2110 if (status == 0) {
2074 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); 2111 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
2075 server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| 2112 server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
@@ -2139,7 +2176,7 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2139 }; 2176 };
2140 2177
2141 nfs_fattr_init(info->fattr); 2178 nfs_fattr_init(info->fattr);
2142 return nfs4_call_sync(server, &msg, &args, &res, 0); 2179 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2143} 2180}
2144 2181
2145static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, 2182static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -2155,15 +2192,43 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2155 return err; 2192 return err;
2156} 2193}
2157 2194
2195static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2196 struct nfs_fsinfo *info, rpc_authflavor_t flavor)
2197{
2198 struct rpc_auth *auth;
2199 int ret;
2200
2201 auth = rpcauth_create(flavor, server->client);
2202 if (!auth) {
2203 ret = -EIO;
2204 goto out;
2205 }
2206 ret = nfs4_lookup_root(server, fhandle, info);
2207 if (ret < 0)
2208 ret = -EAGAIN;
2209out:
2210 return ret;
2211}
2212
2158/* 2213/*
2159 * get the file handle for the "/" directory on the server 2214 * get the file handle for the "/" directory on the server
2160 */ 2215 */
2161static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 2216static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
2162 struct nfs_fsinfo *info) 2217 struct nfs_fsinfo *info)
2163{ 2218{
2164 int status; 2219 int i, len, status = 0;
2220 rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS + 2];
2221
2222 flav_array[0] = RPC_AUTH_UNIX;
2223 len = gss_mech_list_pseudoflavors(&flav_array[1]);
2224 flav_array[1+len] = RPC_AUTH_NULL;
2225 len += 2;
2165 2226
2166 status = nfs4_lookup_root(server, fhandle, info); 2227 for (i = 0; i < len; i++) {
2228 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
2229 if (status == 0)
2230 break;
2231 }
2167 if (status == 0) 2232 if (status == 0)
2168 status = nfs4_server_capabilities(server, fhandle); 2233 status = nfs4_server_capabilities(server, fhandle);
2169 if (status == 0) 2234 if (status == 0)
@@ -2228,7 +2293,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2228 }; 2293 };
2229 2294
2230 nfs_fattr_init(fattr); 2295 nfs_fattr_init(fattr);
2231 return nfs4_call_sync(server, &msg, &args, &res, 0); 2296 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2232} 2297}
2233 2298
2234static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2299static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
@@ -2288,9 +2353,9 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2288 return status; 2353 return status;
2289} 2354}
2290 2355
2291static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *dirfh, 2356static int _nfs4_proc_lookupfh(struct rpc_clnt *clnt, struct nfs_server *server,
2292 const struct qstr *name, struct nfs_fh *fhandle, 2357 const struct nfs_fh *dirfh, const struct qstr *name,
2293 struct nfs_fattr *fattr) 2358 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
2294{ 2359{
2295 int status; 2360 int status;
2296 struct nfs4_lookup_arg args = { 2361 struct nfs4_lookup_arg args = {
@@ -2312,7 +2377,7 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d
2312 nfs_fattr_init(fattr); 2377 nfs_fattr_init(fattr);
2313 2378
2314 dprintk("NFS call lookupfh %s\n", name->name); 2379 dprintk("NFS call lookupfh %s\n", name->name);
2315 status = nfs4_call_sync(server, &msg, &args, &res, 0); 2380 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
2316 dprintk("NFS reply lookupfh: %d\n", status); 2381 dprintk("NFS reply lookupfh: %d\n", status);
2317 return status; 2382 return status;
2318} 2383}
@@ -2324,7 +2389,7 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2324 struct nfs4_exception exception = { }; 2389 struct nfs4_exception exception = { };
2325 int err; 2390 int err;
2326 do { 2391 do {
2327 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr); 2392 err = _nfs4_proc_lookupfh(server->client, server, dirfh, name, fhandle, fattr);
2328 /* FIXME: !!!! */ 2393 /* FIXME: !!!! */
2329 if (err == -NFS4ERR_MOVED) { 2394 if (err == -NFS4ERR_MOVED) {
2330 err = -EREMOTE; 2395 err = -EREMOTE;
@@ -2335,27 +2400,41 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2335 return err; 2400 return err;
2336} 2401}
2337 2402
2338static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, 2403static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2339 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2404 const struct qstr *name, struct nfs_fh *fhandle,
2405 struct nfs_fattr *fattr)
2340{ 2406{
2341 int status; 2407 int status;
2342 2408
2343 dprintk("NFS call lookup %s\n", name->name); 2409 dprintk("NFS call lookup %s\n", name->name);
2344 status = _nfs4_proc_lookupfh(NFS_SERVER(dir), NFS_FH(dir), name, fhandle, fattr); 2410 status = _nfs4_proc_lookupfh(clnt, NFS_SERVER(dir), NFS_FH(dir), name, fhandle, fattr);
2345 if (status == -NFS4ERR_MOVED) 2411 if (status == -NFS4ERR_MOVED)
2346 status = nfs4_get_referral(dir, name, fattr, fhandle); 2412 status = nfs4_get_referral(dir, name, fattr, fhandle);
2347 dprintk("NFS reply lookup: %d\n", status); 2413 dprintk("NFS reply lookup: %d\n", status);
2348 return status; 2414 return status;
2349} 2415}
2350 2416
2351static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2417void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr, struct nfs_fh *fh)
2418{
2419 memset(fh, 0, sizeof(struct nfs_fh));
2420 fattr->fsid.major = 1;
2421 fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
2422 NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_FSID | NFS_ATTR_FATTR_MOUNTPOINT;
2423 fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
2424 fattr->nlink = 2;
2425}
2426
2427static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name,
2428 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
2352{ 2429{
2353 struct nfs4_exception exception = { }; 2430 struct nfs4_exception exception = { };
2354 int err; 2431 int err;
2355 do { 2432 do {
2356 err = nfs4_handle_exception(NFS_SERVER(dir), 2433 err = nfs4_handle_exception(NFS_SERVER(dir),
2357 _nfs4_proc_lookup(dir, name, fhandle, fattr), 2434 _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr),
2358 &exception); 2435 &exception);
2436 if (err == -EPERM)
2437 nfs_fixup_secinfo_attributes(fattr, fhandle);
2359 } while (exception.retry); 2438 } while (exception.retry);
2360 return err; 2439 return err;
2361} 2440}
@@ -2400,7 +2479,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
2400 if (res.fattr == NULL) 2479 if (res.fattr == NULL)
2401 return -ENOMEM; 2480 return -ENOMEM;
2402 2481
2403 status = nfs4_call_sync(server, &msg, &args, &res, 0); 2482 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2404 if (!status) { 2483 if (!status) {
2405 entry->mask = 0; 2484 entry->mask = 0;
2406 if (res.access & NFS4_ACCESS_READ) 2485 if (res.access & NFS4_ACCESS_READ)
@@ -2467,7 +2546,7 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
2467 .rpc_resp = &res, 2546 .rpc_resp = &res,
2468 }; 2547 };
2469 2548
2470 return nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0); 2549 return nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0);
2471} 2550}
2472 2551
2473static int nfs4_proc_readlink(struct inode *inode, struct page *page, 2552static int nfs4_proc_readlink(struct inode *inode, struct page *page,
@@ -2556,7 +2635,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
2556 if (res.dir_attr == NULL) 2635 if (res.dir_attr == NULL)
2557 goto out; 2636 goto out;
2558 2637
2559 status = nfs4_call_sync(server, &msg, &args, &res, 1); 2638 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
2560 if (status == 0) { 2639 if (status == 0) {
2561 update_changeattr(dir, &res.cinfo); 2640 update_changeattr(dir, &res.cinfo);
2562 nfs_post_op_update_inode(dir, res.dir_attr); 2641 nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2657,7 +2736,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2657 if (res.old_fattr == NULL || res.new_fattr == NULL) 2736 if (res.old_fattr == NULL || res.new_fattr == NULL)
2658 goto out; 2737 goto out;
2659 2738
2660 status = nfs4_call_sync(server, &msg, &arg, &res, 1); 2739 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
2661 if (!status) { 2740 if (!status) {
2662 update_changeattr(old_dir, &res.old_cinfo); 2741 update_changeattr(old_dir, &res.old_cinfo);
2663 nfs_post_op_update_inode(old_dir, res.old_fattr); 2742 nfs_post_op_update_inode(old_dir, res.old_fattr);
@@ -2708,7 +2787,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
2708 if (res.fattr == NULL || res.dir_attr == NULL) 2787 if (res.fattr == NULL || res.dir_attr == NULL)
2709 goto out; 2788 goto out;
2710 2789
2711 status = nfs4_call_sync(server, &msg, &arg, &res, 1); 2790 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
2712 if (!status) { 2791 if (!status) {
2713 update_changeattr(dir, &res.cinfo); 2792 update_changeattr(dir, &res.cinfo);
2714 nfs_post_op_update_inode(dir, res.dir_attr); 2793 nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2771,8 +2850,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
2771 2850
2772static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) 2851static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
2773{ 2852{
2774 int status = nfs4_call_sync(NFS_SERVER(dir), &data->msg, 2853 int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
2775 &data->arg, &data->res, 1); 2854 &data->arg.seq_args, &data->res.seq_res, 1);
2776 if (status == 0) { 2855 if (status == 0) {
2777 update_changeattr(dir, &data->res.dir_cinfo); 2856 update_changeattr(dir, &data->res.dir_cinfo);
2778 nfs_post_op_update_inode(dir, data->res.dir_fattr); 2857 nfs_post_op_update_inode(dir, data->res.dir_fattr);
@@ -2884,7 +2963,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2884 (unsigned long long)cookie); 2963 (unsigned long long)cookie);
2885 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 2964 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
2886 res.pgbase = args.pgbase; 2965 res.pgbase = args.pgbase;
2887 status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0); 2966 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0);
2888 if (status >= 0) { 2967 if (status >= 0) {
2889 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 2968 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
2890 status += args.pgbase; 2969 status += args.pgbase;
@@ -2976,7 +3055,7 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
2976 }; 3055 };
2977 3056
2978 nfs_fattr_init(fsstat->fattr); 3057 nfs_fattr_init(fsstat->fattr);
2979 return nfs4_call_sync(server, &msg, &args, &res, 0); 3058 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2980} 3059}
2981 3060
2982static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat) 3061static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
@@ -3007,7 +3086,7 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
3007 .rpc_resp = &res, 3086 .rpc_resp = &res,
3008 }; 3087 };
3009 3088
3010 return nfs4_call_sync(server, &msg, &args, &res, 0); 3089 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
3011} 3090}
3012 3091
3013static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) 3092static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
@@ -3052,7 +3131,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
3052 } 3131 }
3053 3132
3054 nfs_fattr_init(pathconf->fattr); 3133 nfs_fattr_init(pathconf->fattr);
3055 return nfs4_call_sync(server, &msg, &args, &res, 0); 3134 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
3056} 3135}
3057 3136
3058static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, 3137static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -3069,15 +3148,10 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
3069 return err; 3148 return err;
3070} 3149}
3071 3150
3072static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) 3151static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3073{ 3152{
3074 struct nfs_server *server = NFS_SERVER(data->inode); 3153 struct nfs_server *server = NFS_SERVER(data->inode);
3075 3154
3076 dprintk("--> %s\n", __func__);
3077
3078 if (!nfs4_sequence_done(task, &data->res.seq_res))
3079 return -EAGAIN;
3080
3081 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3155 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
3082 nfs_restart_rpc(task, server->nfs_client); 3156 nfs_restart_rpc(task, server->nfs_client);
3083 return -EAGAIN; 3157 return -EAGAIN;
@@ -3089,19 +3163,44 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
3089 return 0; 3163 return 0;
3090} 3164}
3091 3165
3166static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
3167{
3168
3169 dprintk("--> %s\n", __func__);
3170
3171 if (!nfs4_sequence_done(task, &data->res.seq_res))
3172 return -EAGAIN;
3173
3174 return data->read_done_cb(task, data);
3175}
3176
3092static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) 3177static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
3093{ 3178{
3094 data->timestamp = jiffies; 3179 data->timestamp = jiffies;
3180 data->read_done_cb = nfs4_read_done_cb;
3095 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; 3181 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
3096} 3182}
3097 3183
3098static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) 3184/* Reset the the nfs_read_data to send the read to the MDS. */
3185void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data)
3186{
3187 dprintk("%s Reset task for i/o through\n", __func__);
3188 put_lseg(data->lseg);
3189 data->lseg = NULL;
3190 /* offsets will differ in the dense stripe case */
3191 data->args.offset = data->mds_offset;
3192 data->ds_clp = NULL;
3193 data->args.fh = NFS_FH(data->inode);
3194 data->read_done_cb = nfs4_read_done_cb;
3195 task->tk_ops = data->mds_ops;
3196 rpc_task_reset_client(task, NFS_CLIENT(data->inode));
3197}
3198EXPORT_SYMBOL_GPL(nfs4_reset_read);
3199
3200static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
3099{ 3201{
3100 struct inode *inode = data->inode; 3202 struct inode *inode = data->inode;
3101 3203
3102 if (!nfs4_sequence_done(task, &data->res.seq_res))
3103 return -EAGAIN;
3104
3105 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3204 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3106 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3205 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3107 return -EAGAIN; 3206 return -EAGAIN;
@@ -3113,23 +3212,50 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
3113 return 0; 3212 return 0;
3114} 3213}
3115 3214
3215static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
3216{
3217 if (!nfs4_sequence_done(task, &data->res.seq_res))
3218 return -EAGAIN;
3219 return data->write_done_cb(task, data);
3220}
3221
3222/* Reset the the nfs_write_data to send the write to the MDS. */
3223void nfs4_reset_write(struct rpc_task *task, struct nfs_write_data *data)
3224{
3225 dprintk("%s Reset task for i/o through\n", __func__);
3226 put_lseg(data->lseg);
3227 data->lseg = NULL;
3228 data->ds_clp = NULL;
3229 data->write_done_cb = nfs4_write_done_cb;
3230 data->args.fh = NFS_FH(data->inode);
3231 data->args.bitmask = data->res.server->cache_consistency_bitmask;
3232 data->args.offset = data->mds_offset;
3233 data->res.fattr = &data->fattr;
3234 task->tk_ops = data->mds_ops;
3235 rpc_task_reset_client(task, NFS_CLIENT(data->inode));
3236}
3237EXPORT_SYMBOL_GPL(nfs4_reset_write);
3238
3116static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg) 3239static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
3117{ 3240{
3118 struct nfs_server *server = NFS_SERVER(data->inode); 3241 struct nfs_server *server = NFS_SERVER(data->inode);
3119 3242
3120 data->args.bitmask = server->cache_consistency_bitmask; 3243 if (data->lseg) {
3244 data->args.bitmask = NULL;
3245 data->res.fattr = NULL;
3246 } else
3247 data->args.bitmask = server->cache_consistency_bitmask;
3248 if (!data->write_done_cb)
3249 data->write_done_cb = nfs4_write_done_cb;
3121 data->res.server = server; 3250 data->res.server = server;
3122 data->timestamp = jiffies; 3251 data->timestamp = jiffies;
3123 3252
3124 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; 3253 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
3125} 3254}
3126 3255
3127static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) 3256static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *data)
3128{ 3257{
3129 struct inode *inode = data->inode; 3258 struct inode *inode = data->inode;
3130
3131 if (!nfs4_sequence_done(task, &data->res.seq_res))
3132 return -EAGAIN;
3133 3259
3134 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3260 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
3135 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3261 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
@@ -3139,11 +3265,24 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
3139 return 0; 3265 return 0;
3140} 3266}
3141 3267
3268static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
3269{
3270 if (!nfs4_sequence_done(task, &data->res.seq_res))
3271 return -EAGAIN;
3272 return data->write_done_cb(task, data);
3273}
3274
3142static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg) 3275static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
3143{ 3276{
3144 struct nfs_server *server = NFS_SERVER(data->inode); 3277 struct nfs_server *server = NFS_SERVER(data->inode);
3145 3278
3146 data->args.bitmask = server->cache_consistency_bitmask; 3279 if (data->lseg) {
3280 data->args.bitmask = NULL;
3281 data->res.fattr = NULL;
3282 } else
3283 data->args.bitmask = server->cache_consistency_bitmask;
3284 if (!data->write_done_cb)
3285 data->write_done_cb = nfs4_commit_done_cb;
3147 data->res.server = server; 3286 data->res.server = server;
3148 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; 3287 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
3149} 3288}
@@ -3381,7 +3520,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3381 resp_buf = buf; 3520 resp_buf = buf;
3382 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase); 3521 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
3383 } 3522 }
3384 ret = nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0); 3523 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0);
3385 if (ret) 3524 if (ret)
3386 goto out_free; 3525 goto out_free;
3387 if (res.acl_len > args.acl_len) 3526 if (res.acl_len > args.acl_len)
@@ -3456,7 +3595,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
3456 if (i < 0) 3595 if (i < 0)
3457 return i; 3596 return i;
3458 nfs_inode_return_delegation(inode); 3597 nfs_inode_return_delegation(inode);
3459 ret = nfs4_call_sync(server, &msg, &arg, &res, 1); 3598 ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3460 3599
3461 /* 3600 /*
3462 * Free each page after tx, so the only ref left is 3601 * Free each page after tx, so the only ref left is
@@ -3819,7 +3958,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3819 lsp = request->fl_u.nfs4_fl.owner; 3958 lsp = request->fl_u.nfs4_fl.owner;
3820 arg.lock_owner.id = lsp->ls_id.id; 3959 arg.lock_owner.id = lsp->ls_id.id;
3821 arg.lock_owner.s_dev = server->s_dev; 3960 arg.lock_owner.s_dev = server->s_dev;
3822 status = nfs4_call_sync(server, &msg, &arg, &res, 1); 3961 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3823 switch (status) { 3962 switch (status) {
3824 case 0: 3963 case 0:
3825 request->fl_type = F_UNLCK; 3964 request->fl_type = F_UNLCK;
@@ -4547,12 +4686,46 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4547 nfs_fattr_init(&fs_locations->fattr); 4686 nfs_fattr_init(&fs_locations->fattr);
4548 fs_locations->server = server; 4687 fs_locations->server = server;
4549 fs_locations->nlocations = 0; 4688 fs_locations->nlocations = 0;
4550 status = nfs4_call_sync(server, &msg, &args, &res, 0); 4689 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
4551 nfs_fixup_referral_attributes(&fs_locations->fattr); 4690 nfs_fixup_referral_attributes(&fs_locations->fattr);
4552 dprintk("%s: returned status = %d\n", __func__, status); 4691 dprintk("%s: returned status = %d\n", __func__, status);
4553 return status; 4692 return status;
4554} 4693}
4555 4694
4695static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors)
4696{
4697 int status;
4698 struct nfs4_secinfo_arg args = {
4699 .dir_fh = NFS_FH(dir),
4700 .name = name,
4701 };
4702 struct nfs4_secinfo_res res = {
4703 .flavors = flavors,
4704 };
4705 struct rpc_message msg = {
4706 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SECINFO],
4707 .rpc_argp = &args,
4708 .rpc_resp = &res,
4709 };
4710
4711 dprintk("NFS call secinfo %s\n", name->name);
4712 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0);
4713 dprintk("NFS reply secinfo: %d\n", status);
4714 return status;
4715}
4716
4717int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors)
4718{
4719 struct nfs4_exception exception = { };
4720 int err;
4721 do {
4722 err = nfs4_handle_exception(NFS_SERVER(dir),
4723 _nfs4_proc_secinfo(dir, name, flavors),
4724 &exception);
4725 } while (exception.retry);
4726 return err;
4727}
4728
4556#ifdef CONFIG_NFS_V4_1 4729#ifdef CONFIG_NFS_V4_1
4557/* 4730/*
4558 * Check the exchange flags returned by the server for invalid flags, having 4731 * Check the exchange flags returned by the server for invalid flags, having
@@ -5118,6 +5291,27 @@ int nfs4_init_session(struct nfs_server *server)
5118 return ret; 5291 return ret;
5119} 5292}
5120 5293
5294int nfs4_init_ds_session(struct nfs_client *clp)
5295{
5296 struct nfs4_session *session = clp->cl_session;
5297 int ret;
5298
5299 if (!test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state))
5300 return 0;
5301
5302 ret = nfs4_client_recover_expired_lease(clp);
5303 if (!ret)
5304 /* Test for the DS role */
5305 if (!is_ds_client(clp))
5306 ret = -ENODEV;
5307 if (!ret)
5308 ret = nfs4_check_client_ready(clp);
5309 return ret;
5310
5311}
5312EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
5313
5314
5121/* 5315/*
5122 * Renew the cl_session lease. 5316 * Renew the cl_session lease.
5123 */ 5317 */
@@ -5424,8 +5618,6 @@ static void nfs4_layoutget_release(void *calldata)
5424 struct nfs4_layoutget *lgp = calldata; 5618 struct nfs4_layoutget *lgp = calldata;
5425 5619
5426 dprintk("--> %s\n", __func__); 5620 dprintk("--> %s\n", __func__);
5427 if (lgp->res.layout.buf != NULL)
5428 free_page((unsigned long) lgp->res.layout.buf);
5429 put_nfs_open_context(lgp->args.ctx); 5621 put_nfs_open_context(lgp->args.ctx);
5430 kfree(calldata); 5622 kfree(calldata);
5431 dprintk("<-- %s\n", __func__); 5623 dprintk("<-- %s\n", __func__);
@@ -5457,12 +5649,7 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
5457 5649
5458 dprintk("--> %s\n", __func__); 5650 dprintk("--> %s\n", __func__);
5459 5651
5460 lgp->res.layout.buf = (void *)__get_free_page(GFP_NOFS); 5652 lgp->res.layoutp = &lgp->args.layout;
5461 if (lgp->res.layout.buf == NULL) {
5462 nfs4_layoutget_release(lgp);
5463 return -ENOMEM;
5464 }
5465
5466 lgp->res.seq_res.sr_slot = NULL; 5653 lgp->res.seq_res.sr_slot = NULL;
5467 task = rpc_run_task(&task_setup_data); 5654 task = rpc_run_task(&task_setup_data);
5468 if (IS_ERR(task)) 5655 if (IS_ERR(task))
@@ -5494,7 +5681,7 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
5494 int status; 5681 int status;
5495 5682
5496 dprintk("--> %s\n", __func__); 5683 dprintk("--> %s\n", __func__);
5497 status = nfs4_call_sync(server, &msg, &args, &res, 0); 5684 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
5498 dprintk("<-- %s status=%d\n", __func__, status); 5685 dprintk("<-- %s status=%d\n", __func__, status);
5499 5686
5500 return status; 5687 return status;
@@ -5514,6 +5701,100 @@ int nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
5514} 5701}
5515EXPORT_SYMBOL_GPL(nfs4_proc_getdeviceinfo); 5702EXPORT_SYMBOL_GPL(nfs4_proc_getdeviceinfo);
5516 5703
5704static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata)
5705{
5706 struct nfs4_layoutcommit_data *data = calldata;
5707 struct nfs_server *server = NFS_SERVER(data->args.inode);
5708
5709 if (nfs4_setup_sequence(server, &data->args.seq_args,
5710 &data->res.seq_res, 1, task))
5711 return;
5712 rpc_call_start(task);
5713}
5714
5715static void
5716nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
5717{
5718 struct nfs4_layoutcommit_data *data = calldata;
5719 struct nfs_server *server = NFS_SERVER(data->args.inode);
5720
5721 if (!nfs4_sequence_done(task, &data->res.seq_res))
5722 return;
5723
5724 switch (task->tk_status) { /* Just ignore these failures */
5725 case NFS4ERR_DELEG_REVOKED: /* layout was recalled */
5726 case NFS4ERR_BADIOMODE: /* no IOMODE_RW layout for range */
5727 case NFS4ERR_BADLAYOUT: /* no layout */
5728 case NFS4ERR_GRACE: /* loca_recalim always false */
5729 task->tk_status = 0;
5730 }
5731
5732 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
5733 nfs_restart_rpc(task, server->nfs_client);
5734 return;
5735 }
5736
5737 if (task->tk_status == 0)
5738 nfs_post_op_update_inode_force_wcc(data->args.inode,
5739 data->res.fattr);
5740}
5741
5742static void nfs4_layoutcommit_release(void *calldata)
5743{
5744 struct nfs4_layoutcommit_data *data = calldata;
5745
5746 /* Matched by references in pnfs_set_layoutcommit */
5747 put_lseg(data->lseg);
5748 put_rpccred(data->cred);
5749 kfree(data);
5750}
5751
5752static const struct rpc_call_ops nfs4_layoutcommit_ops = {
5753 .rpc_call_prepare = nfs4_layoutcommit_prepare,
5754 .rpc_call_done = nfs4_layoutcommit_done,
5755 .rpc_release = nfs4_layoutcommit_release,
5756};
5757
5758int
5759nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
5760{
5761 struct rpc_message msg = {
5762 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTCOMMIT],
5763 .rpc_argp = &data->args,
5764 .rpc_resp = &data->res,
5765 .rpc_cred = data->cred,
5766 };
5767 struct rpc_task_setup task_setup_data = {
5768 .task = &data->task,
5769 .rpc_client = NFS_CLIENT(data->args.inode),
5770 .rpc_message = &msg,
5771 .callback_ops = &nfs4_layoutcommit_ops,
5772 .callback_data = data,
5773 .flags = RPC_TASK_ASYNC,
5774 };
5775 struct rpc_task *task;
5776 int status = 0;
5777
5778 dprintk("NFS: %4d initiating layoutcommit call. sync %d "
5779 "lbw: %llu inode %lu\n",
5780 data->task.tk_pid, sync,
5781 data->args.lastbytewritten,
5782 data->args.inode->i_ino);
5783
5784 task = rpc_run_task(&task_setup_data);
5785 if (IS_ERR(task))
5786 return PTR_ERR(task);
5787 if (sync == false)
5788 goto out;
5789 status = nfs4_wait_for_completion_rpc_task(task);
5790 if (status != 0)
5791 goto out;
5792 status = task->tk_status;
5793out:
5794 dprintk("%s: status %d\n", __func__, status);
5795 rpc_put_task(task);
5796 return status;
5797}
5517#endif /* CONFIG_NFS_V4_1 */ 5798#endif /* CONFIG_NFS_V4_1 */
5518 5799
5519struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { 5800struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
@@ -5648,6 +5929,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
5648 .clear_acl_cache = nfs4_zap_acl_attr, 5929 .clear_acl_cache = nfs4_zap_acl_attr,
5649 .close_context = nfs4_close_context, 5930 .close_context = nfs4_close_context,
5650 .open_context = nfs4_atomic_open, 5931 .open_context = nfs4_atomic_open,
5932 .init_client = nfs4_init_client,
5933 .secinfo = nfs4_proc_secinfo,
5651}; 5934};
5652 5935
5653static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { 5936static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {