aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 17:57:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 17:57:40 -0500
commit57eccf1c2acae2fcb748730881ba75643fc31c81 (patch)
treebe47ac42ef0b2e3e7157ce196ad2ed1224739c6c /fs/nfs
parent5c395ae7033099fc657114ea997858aa622f08b2 (diff)
parent074b1d12fe2500d7d453902f9266e6674b30d84c (diff)
Merge branch 'nfs-for-3.3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'nfs-for-3.3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFSv4: Change the default setting of the nfs4_disable_idmapping parameter NFSv4: Save the owner/group name string when doing open NFS: Remove pNFS bloat from the generic write path pnfs-obj: Must return layout on IO error pnfs-obj: pNFS errors are communicated on iodata->pnfs_error NFS: Cache state owners after files are closed NFS: Clean up nfs4_find_state_owners_locked() NFSv4: include bitmap in nfsv4 get acl data nfs: fix a minor do_div portability issue NFSv4.1: cleanup comment and debug printk NFSv4.1: change nfs4_free_slot parameters for dynamic slots NFSv4.1: cleanup init and reset of session slot tables NFSv4.1: fix backchannel slotid off-by-one bug nfs: fix regression in handling of context= option in NFSv4 NFS - fix recent breakage to NFS error handling. NFS: Retry mounting NFSROOT SUNRPC: Clean up the RPCSEC_GSS service ticket requests
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/callback_proc.c2
-rw-r--r--fs/nfs/client.c12
-rw-r--r--fs/nfs/file.c4
-rw-r--r--fs/nfs/idmap.c83
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/nfs4_fs.h3
-rw-r--r--fs/nfs/nfs4filelayout.c9
-rw-r--r--fs/nfs/nfs4proc.c177
-rw-r--r--fs/nfs/nfs4state.c104
-rw-r--r--fs/nfs/nfs4xdr.c137
-rw-r--r--fs/nfs/objlayout/objio_osd.c3
-rw-r--r--fs/nfs/objlayout/objlayout.c4
-rw-r--r--fs/nfs/pnfs.c42
-rw-r--r--fs/nfs/pnfs.h1
-rw-r--r--fs/nfs/super.c43
-rw-r--r--fs/nfs/write.c27
17 files changed, 422 insertions, 233 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 43926add945b..54cea8ad5a76 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -339,7 +339,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
339 dprintk("%s enter. slotid %d seqid %d\n", 339 dprintk("%s enter. slotid %d seqid %d\n",
340 __func__, args->csa_slotid, args->csa_sequenceid); 340 __func__, args->csa_slotid, args->csa_sequenceid);
341 341
342 if (args->csa_slotid > NFS41_BC_MAX_CALLBACKS) 342 if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS)
343 return htonl(NFS4ERR_BADSLOT); 343 return htonl(NFS4ERR_BADSLOT);
344 344
345 slot = tbl->slots + args->csa_slotid; 345 slot = tbl->slots + args->csa_slotid;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 873bf00d51a2..277dfaf2e99a 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -84,7 +84,7 @@ retry:
84/* 84/*
85 * Turn off NFSv4 uid/gid mapping when using AUTH_SYS 85 * Turn off NFSv4 uid/gid mapping when using AUTH_SYS
86 */ 86 */
87static int nfs4_disable_idmapping = 0; 87static int nfs4_disable_idmapping = 1;
88 88
89/* 89/*
90 * RPC cruft for NFS 90 * RPC cruft for NFS
@@ -185,7 +185,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
185 clp->cl_minorversion = cl_init->minorversion; 185 clp->cl_minorversion = cl_init->minorversion;
186 clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; 186 clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
187#endif 187#endif
188 cred = rpc_lookup_machine_cred(); 188 cred = rpc_lookup_machine_cred("*");
189 if (!IS_ERR(cred)) 189 if (!IS_ERR(cred))
190 clp->cl_machine_cred = cred; 190 clp->cl_machine_cred = cred;
191 nfs_fscache_get_client_cookie(clp); 191 nfs_fscache_get_client_cookie(clp);
@@ -250,6 +250,11 @@ static void pnfs_init_server(struct nfs_server *server)
250 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC"); 250 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC");
251} 251}
252 252
253static void nfs4_destroy_server(struct nfs_server *server)
254{
255 nfs4_purge_state_owners(server);
256}
257
253#else 258#else
254static void nfs4_shutdown_client(struct nfs_client *clp) 259static void nfs4_shutdown_client(struct nfs_client *clp)
255{ 260{
@@ -1065,6 +1070,7 @@ static struct nfs_server *nfs_alloc_server(void)
1065 INIT_LIST_HEAD(&server->master_link); 1070 INIT_LIST_HEAD(&server->master_link);
1066 INIT_LIST_HEAD(&server->delegations); 1071 INIT_LIST_HEAD(&server->delegations);
1067 INIT_LIST_HEAD(&server->layouts); 1072 INIT_LIST_HEAD(&server->layouts);
1073 INIT_LIST_HEAD(&server->state_owners_lru);
1068 1074
1069 atomic_set(&server->active, 0); 1075 atomic_set(&server->active, 0);
1070 1076
@@ -1538,6 +1544,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
1538 1544
1539 nfs_server_insert_lists(server); 1545 nfs_server_insert_lists(server);
1540 server->mount_time = jiffies; 1546 server->mount_time = jiffies;
1547 server->destroy = nfs4_destroy_server;
1541out: 1548out:
1542 nfs_free_fattr(fattr); 1549 nfs_free_fattr(fattr);
1543 return error; 1550 return error;
@@ -1719,6 +1726,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1719 1726
1720 /* Copy data from the source */ 1727 /* Copy data from the source */
1721 server->nfs_client = source->nfs_client; 1728 server->nfs_client = source->nfs_client;
1729 server->destroy = source->destroy;
1722 atomic_inc(&server->nfs_client->cl_count); 1730 atomic_inc(&server->nfs_client->cl_count);
1723 nfs_server_copy_userdata(server, source); 1731 nfs_server_copy_userdata(server, source);
1724 1732
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 606ef0f20aed..c43a452f7da2 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -272,13 +272,13 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
272 datasync); 272 datasync);
273 273
274 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 274 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
275 if (ret)
276 return ret;
277 mutex_lock(&inode->i_mutex); 275 mutex_lock(&inode->i_mutex);
278 276
279 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 277 nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
280 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); 278 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
281 status = nfs_commit_inode(inode, FLUSH_SYNC); 279 status = nfs_commit_inode(inode, FLUSH_SYNC);
280 if (status >= 0 && ret < 0)
281 status = ret;
282 have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); 282 have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
283 if (have_error) 283 if (have_error)
284 ret = xchg(&ctx->error, 0); 284 ret = xchg(&ctx->error, 0);
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 47d1c6ff2d8e..2c05f1991e1e 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -38,6 +38,89 @@
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/nfs_idmap.h> 40#include <linux/nfs_idmap.h>
41#include <linux/nfs_fs.h>
42
43/**
44 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
45 * @fattr: fully initialised struct nfs_fattr
46 * @owner_name: owner name string cache
47 * @group_name: group name string cache
48 */
49void nfs_fattr_init_names(struct nfs_fattr *fattr,
50 struct nfs4_string *owner_name,
51 struct nfs4_string *group_name)
52{
53 fattr->owner_name = owner_name;
54 fattr->group_name = group_name;
55}
56
57static void nfs_fattr_free_owner_name(struct nfs_fattr *fattr)
58{
59 fattr->valid &= ~NFS_ATTR_FATTR_OWNER_NAME;
60 kfree(fattr->owner_name->data);
61}
62
63static void nfs_fattr_free_group_name(struct nfs_fattr *fattr)
64{
65 fattr->valid &= ~NFS_ATTR_FATTR_GROUP_NAME;
66 kfree(fattr->group_name->data);
67}
68
69static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr)
70{
71 struct nfs4_string *owner = fattr->owner_name;
72 __u32 uid;
73
74 if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME))
75 return false;
76 if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) {
77 fattr->uid = uid;
78 fattr->valid |= NFS_ATTR_FATTR_OWNER;
79 }
80 return true;
81}
82
83static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr)
84{
85 struct nfs4_string *group = fattr->group_name;
86 __u32 gid;
87
88 if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME))
89 return false;
90 if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) {
91 fattr->gid = gid;
92 fattr->valid |= NFS_ATTR_FATTR_GROUP;
93 }
94 return true;
95}
96
97/**
98 * nfs_fattr_free_names - free up the NFSv4 owner and group strings
99 * @fattr: a fully initialised nfs_fattr structure
100 */
101void nfs_fattr_free_names(struct nfs_fattr *fattr)
102{
103 if (fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)
104 nfs_fattr_free_owner_name(fattr);
105 if (fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)
106 nfs_fattr_free_group_name(fattr);
107}
108
109/**
110 * nfs_fattr_map_and_free_names - map owner/group strings into uid/gid and free
111 * @server: pointer to the filesystem nfs_server structure
112 * @fattr: a fully initialised nfs_fattr structure
113 *
114 * This helper maps the cached NFSv4 owner/group strings in fattr into
115 * their numeric uid/gid equivalents, and then frees the cached strings.
116 */
117void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *fattr)
118{
119 if (nfs_fattr_map_owner_name(server, fattr))
120 nfs_fattr_free_owner_name(fattr);
121 if (nfs_fattr_map_group_name(server, fattr))
122 nfs_fattr_free_group_name(fattr);
123}
41 124
42static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res) 125static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res)
43{ 126{
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 81db25e92e10..25c3bfad7953 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1020,6 +1020,8 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
1020 fattr->valid = 0; 1020 fattr->valid = 0;
1021 fattr->time_start = jiffies; 1021 fattr->time_start = jiffies;
1022 fattr->gencount = nfs_inc_attr_generation_counter(); 1022 fattr->gencount = nfs_inc_attr_generation_counter();
1023 fattr->owner_name = NULL;
1024 fattr->group_name = NULL;
1023} 1025}
1024 1026
1025struct nfs_fattr *nfs_alloc_fattr(void) 1027struct nfs_fattr *nfs_alloc_fattr(void)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 3f4d95751d52..5ee92538b063 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -307,6 +307,8 @@ extern void nfs_readdata_release(struct nfs_read_data *rdata);
307/* write.c */ 307/* write.c */
308extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc, 308extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
309 struct list_head *head); 309 struct list_head *head);
310extern void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
311 struct inode *inode, int ioflags);
310extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio); 312extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
311extern void nfs_writedata_release(struct nfs_write_data *wdata); 313extern void nfs_writedata_release(struct nfs_write_data *wdata);
312extern void nfs_commit_free(struct nfs_write_data *p); 314extern void nfs_commit_free(struct nfs_write_data *p);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 693ae22f8731..4d7d0aedc101 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -94,6 +94,8 @@ struct nfs_unique_id {
94struct nfs4_state_owner { 94struct nfs4_state_owner {
95 struct nfs_unique_id so_owner_id; 95 struct nfs_unique_id so_owner_id;
96 struct nfs_server *so_server; 96 struct nfs_server *so_server;
97 struct list_head so_lru;
98 unsigned long so_expires;
97 struct rb_node so_server_node; 99 struct rb_node so_server_node;
98 100
99 struct rpc_cred *so_cred; /* Associated cred */ 101 struct rpc_cred *so_cred; /* Associated cred */
@@ -319,6 +321,7 @@ static inline void nfs4_schedule_session_recovery(struct nfs4_session *session)
319 321
320extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); 322extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
321extern void nfs4_put_state_owner(struct nfs4_state_owner *); 323extern void nfs4_put_state_owner(struct nfs4_state_owner *);
324extern void nfs4_purge_state_owners(struct nfs_server *);
322extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); 325extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
323extern void nfs4_put_open_state(struct nfs4_state *); 326extern void nfs4_put_open_state(struct nfs4_state *);
324extern void nfs4_close_state(struct nfs4_state *, fmode_t); 327extern void nfs4_close_state(struct nfs4_state *, fmode_t);
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index a62d36b9a99e..71ec08617e23 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -49,13 +49,14 @@ filelayout_get_dense_offset(struct nfs4_filelayout_segment *flseg,
49 loff_t offset) 49 loff_t offset)
50{ 50{
51 u32 stripe_width = flseg->stripe_unit * flseg->dsaddr->stripe_count; 51 u32 stripe_width = flseg->stripe_unit * flseg->dsaddr->stripe_count;
52 u64 tmp; 52 u64 stripe_no;
53 u32 rem;
53 54
54 offset -= flseg->pattern_offset; 55 offset -= flseg->pattern_offset;
55 tmp = offset; 56 stripe_no = div_u64(offset, stripe_width);
56 do_div(tmp, stripe_width); 57 div_u64_rem(offset, flseg->stripe_unit, &rem);
57 58
58 return tmp * flseg->stripe_unit + do_div(offset, flseg->stripe_unit); 59 return stripe_no * flseg->stripe_unit + rem;
59} 60}
60 61
61/* This function is used by the layout driver to calculate the 62/* This function is used by the layout driver to calculate the
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dcda0ba7af60..75366dc89686 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -52,6 +52,7 @@
52#include <linux/namei.h> 52#include <linux/namei.h>
53#include <linux/mount.h> 53#include <linux/mount.h>
54#include <linux/module.h> 54#include <linux/module.h>
55#include <linux/nfs_idmap.h>
55#include <linux/sunrpc/bc_xprt.h> 56#include <linux/sunrpc/bc_xprt.h>
56#include <linux/xattr.h> 57#include <linux/xattr.h>
57#include <linux/utsname.h> 58#include <linux/utsname.h>
@@ -364,9 +365,8 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
364 * Must be called while holding tbl->slot_tbl_lock 365 * Must be called while holding tbl->slot_tbl_lock
365 */ 366 */
366static void 367static void
367nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *free_slot) 368nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
368{ 369{
369 int free_slotid = free_slot - tbl->slots;
370 int slotid = free_slotid; 370 int slotid = free_slotid;
371 371
372 BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE); 372 BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE);
@@ -431,7 +431,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
431 } 431 }
432 432
433 spin_lock(&tbl->slot_tbl_lock); 433 spin_lock(&tbl->slot_tbl_lock);
434 nfs4_free_slot(tbl, res->sr_slot); 434 nfs4_free_slot(tbl, res->sr_slot - tbl->slots);
435 nfs4_check_drain_fc_complete(res->sr_session); 435 nfs4_check_drain_fc_complete(res->sr_session);
436 spin_unlock(&tbl->slot_tbl_lock); 436 spin_unlock(&tbl->slot_tbl_lock);
437 res->sr_slot = NULL; 437 res->sr_slot = NULL;
@@ -554,13 +554,10 @@ int nfs41_setup_sequence(struct nfs4_session *session,
554 spin_lock(&tbl->slot_tbl_lock); 554 spin_lock(&tbl->slot_tbl_lock);
555 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && 555 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) &&
556 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { 556 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
557 /* 557 /* The state manager will wait until the slot table is empty */
558 * The state manager will wait until the slot table is empty.
559 * Schedule the reset thread
560 */
561 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 558 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
562 spin_unlock(&tbl->slot_tbl_lock); 559 spin_unlock(&tbl->slot_tbl_lock);
563 dprintk("%s Schedule Session Reset\n", __func__); 560 dprintk("%s session is draining\n", __func__);
564 return -EAGAIN; 561 return -EAGAIN;
565 } 562 }
566 563
@@ -765,6 +762,8 @@ struct nfs4_opendata {
765 struct nfs_openres o_res; 762 struct nfs_openres o_res;
766 struct nfs_open_confirmargs c_arg; 763 struct nfs_open_confirmargs c_arg;
767 struct nfs_open_confirmres c_res; 764 struct nfs_open_confirmres c_res;
765 struct nfs4_string owner_name;
766 struct nfs4_string group_name;
768 struct nfs_fattr f_attr; 767 struct nfs_fattr f_attr;
769 struct nfs_fattr dir_attr; 768 struct nfs_fattr dir_attr;
770 struct dentry *dir; 769 struct dentry *dir;
@@ -788,6 +787,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
788 p->o_res.server = p->o_arg.server; 787 p->o_res.server = p->o_arg.server;
789 nfs_fattr_init(&p->f_attr); 788 nfs_fattr_init(&p->f_attr);
790 nfs_fattr_init(&p->dir_attr); 789 nfs_fattr_init(&p->dir_attr);
790 nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
791} 791}
792 792
793static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, 793static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
@@ -819,6 +819,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
819 p->o_arg.name = &dentry->d_name; 819 p->o_arg.name = &dentry->d_name;
820 p->o_arg.server = server; 820 p->o_arg.server = server;
821 p->o_arg.bitmask = server->attr_bitmask; 821 p->o_arg.bitmask = server->attr_bitmask;
822 p->o_arg.dir_bitmask = server->cache_consistency_bitmask;
822 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 823 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
823 if (flags & O_CREAT) { 824 if (flags & O_CREAT) {
824 u32 *s; 825 u32 *s;
@@ -855,6 +856,7 @@ static void nfs4_opendata_free(struct kref *kref)
855 dput(p->dir); 856 dput(p->dir);
856 dput(p->dentry); 857 dput(p->dentry);
857 nfs_sb_deactive(sb); 858 nfs_sb_deactive(sb);
859 nfs_fattr_free_names(&p->f_attr);
858 kfree(p); 860 kfree(p);
859} 861}
860 862
@@ -1579,6 +1581,8 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1579 if (status != 0 || !data->rpc_done) 1581 if (status != 0 || !data->rpc_done)
1580 return status; 1582 return status;
1581 1583
1584 nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr);
1585
1582 nfs_refresh_inode(dir, o_res->dir_attr); 1586 nfs_refresh_inode(dir, o_res->dir_attr);
1583 1587
1584 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 1588 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
@@ -1611,6 +1615,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1611 return status; 1615 return status;
1612 } 1616 }
1613 1617
1618 nfs_fattr_map_and_free_names(server, &data->f_attr);
1619
1614 if (o_arg->open_flags & O_CREAT) { 1620 if (o_arg->open_flags & O_CREAT) {
1615 update_changeattr(dir, &o_res->cinfo); 1621 update_changeattr(dir, &o_res->cinfo);
1616 nfs_post_op_update_inode(dir, o_res->dir_attr); 1622 nfs_post_op_update_inode(dir, o_res->dir_attr);
@@ -3431,19 +3437,6 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
3431 */ 3437 */
3432#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) 3438#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT)
3433 3439
3434static void buf_to_pages(const void *buf, size_t buflen,
3435 struct page **pages, unsigned int *pgbase)
3436{
3437 const void *p = buf;
3438
3439 *pgbase = offset_in_page(buf);
3440 p -= *pgbase;
3441 while (p < buf + buflen) {
3442 *(pages++) = virt_to_page(p);
3443 p += PAGE_CACHE_SIZE;
3444 }
3445}
3446
3447static int buf_to_pages_noslab(const void *buf, size_t buflen, 3440static int buf_to_pages_noslab(const void *buf, size_t buflen,
3448 struct page **pages, unsigned int *pgbase) 3441 struct page **pages, unsigned int *pgbase)
3449{ 3442{
@@ -3540,9 +3533,19 @@ out:
3540 nfs4_set_cached_acl(inode, acl); 3533 nfs4_set_cached_acl(inode, acl);
3541} 3534}
3542 3535
3536/*
3537 * The getxattr API returns the required buffer length when called with a
3538 * NULL buf. The NFSv4 acl tool then calls getxattr again after allocating
3539 * the required buf. On a NULL buf, we send a page of data to the server
3540 * guessing that the ACL request can be serviced by a page. If so, we cache
3541 * up to the page of ACL data, and the 2nd call to getxattr is serviced by
3542 * the cache. If not so, we throw away the page, and cache the required
3543 * length. The next getxattr call will then produce another round trip to
3544 * the server, this time with the input buf of the required size.
3545 */
3543static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) 3546static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
3544{ 3547{
3545 struct page *pages[NFS4ACL_MAXPAGES]; 3548 struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
3546 struct nfs_getaclargs args = { 3549 struct nfs_getaclargs args = {
3547 .fh = NFS_FH(inode), 3550 .fh = NFS_FH(inode),
3548 .acl_pages = pages, 3551 .acl_pages = pages,
@@ -3557,41 +3560,60 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3557 .rpc_argp = &args, 3560 .rpc_argp = &args,
3558 .rpc_resp = &res, 3561 .rpc_resp = &res,
3559 }; 3562 };
3560 struct page *localpage = NULL; 3563 int ret = -ENOMEM, npages, i, acl_len = 0;
3561 int ret;
3562 3564
3563 if (buflen < PAGE_SIZE) { 3565 npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
3564 /* As long as we're doing a round trip to the server anyway, 3566 /* As long as we're doing a round trip to the server anyway,
3565 * let's be prepared for a page of acl data. */ 3567 * let's be prepared for a page of acl data. */
3566 localpage = alloc_page(GFP_KERNEL); 3568 if (npages == 0)
3567 resp_buf = page_address(localpage); 3569 npages = 1;
3568 if (localpage == NULL) 3570
3569 return -ENOMEM; 3571 for (i = 0; i < npages; i++) {
3570 args.acl_pages[0] = localpage; 3572 pages[i] = alloc_page(GFP_KERNEL);
3571 args.acl_pgbase = 0; 3573 if (!pages[i])
3572 args.acl_len = PAGE_SIZE; 3574 goto out_free;
3573 } else {
3574 resp_buf = buf;
3575 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
3576 } 3575 }
3577 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0); 3576 if (npages > 1) {
3577 /* for decoding across pages */
3578 args.acl_scratch = alloc_page(GFP_KERNEL);
3579 if (!args.acl_scratch)
3580 goto out_free;
3581 }
3582 args.acl_len = npages * PAGE_SIZE;
3583 args.acl_pgbase = 0;
3584 /* Let decode_getfacl know not to fail if the ACL data is larger than
3585 * the page we send as a guess */
3586 if (buf == NULL)
3587 res.acl_flags |= NFS4_ACL_LEN_REQUEST;
3588 resp_buf = page_address(pages[0]);
3589
3590 dprintk("%s buf %p buflen %ld npages %d args.acl_len %ld\n",
3591 __func__, buf, buflen, npages, args.acl_len);
3592 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
3593 &msg, &args.seq_args, &res.seq_res, 0);
3578 if (ret) 3594 if (ret)
3579 goto out_free; 3595 goto out_free;
3580 if (res.acl_len > args.acl_len) 3596
3581 nfs4_write_cached_acl(inode, NULL, res.acl_len); 3597 acl_len = res.acl_len - res.acl_data_offset;
3598 if (acl_len > args.acl_len)
3599 nfs4_write_cached_acl(inode, NULL, acl_len);
3582 else 3600 else
3583 nfs4_write_cached_acl(inode, resp_buf, res.acl_len); 3601 nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset,
3602 acl_len);
3584 if (buf) { 3603 if (buf) {
3585 ret = -ERANGE; 3604 ret = -ERANGE;
3586 if (res.acl_len > buflen) 3605 if (acl_len > buflen)
3587 goto out_free; 3606 goto out_free;
3588 if (localpage) 3607 _copy_from_pages(buf, pages, res.acl_data_offset,
3589 memcpy(buf, resp_buf, res.acl_len); 3608 res.acl_len);
3590 } 3609 }
3591 ret = res.acl_len; 3610 ret = acl_len;
3592out_free: 3611out_free:
3593 if (localpage) 3612 for (i = 0; i < npages; i++)
3594 __free_page(localpage); 3613 if (pages[i])
3614 __free_page(pages[i]);
3615 if (args.acl_scratch)
3616 __free_page(args.acl_scratch);
3595 return ret; 3617 return ret;
3596} 3618}
3597 3619
@@ -3622,6 +3644,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
3622 nfs_zap_acl_cache(inode); 3644 nfs_zap_acl_cache(inode);
3623 ret = nfs4_read_cached_acl(inode, buf, buflen); 3645 ret = nfs4_read_cached_acl(inode, buf, buflen);
3624 if (ret != -ENOENT) 3646 if (ret != -ENOENT)
3647 /* -ENOENT is returned if there is no ACL or if there is an ACL
3648 * but no cached acl data, just the acl length */
3625 return ret; 3649 return ret;
3626 return nfs4_get_acl_uncached(inode, buf, buflen); 3650 return nfs4_get_acl_uncached(inode, buf, buflen);
3627} 3651}
@@ -5022,23 +5046,6 @@ out:
5022 return ret; 5046 return ret;
5023} 5047}
5024 5048
5025/*
5026 * Reset the forechannel and backchannel slot tables
5027 */
5028static int nfs4_reset_slot_tables(struct nfs4_session *session)
5029{
5030 int status;
5031
5032 status = nfs4_reset_slot_table(&session->fc_slot_table,
5033 session->fc_attrs.max_reqs, 1);
5034 if (status)
5035 return status;
5036
5037 status = nfs4_reset_slot_table(&session->bc_slot_table,
5038 session->bc_attrs.max_reqs, 0);
5039 return status;
5040}
5041
5042/* Destroy the slot table */ 5049/* Destroy the slot table */
5043static void nfs4_destroy_slot_tables(struct nfs4_session *session) 5050static void nfs4_destroy_slot_tables(struct nfs4_session *session)
5044{ 5051{
@@ -5084,29 +5091,35 @@ out:
5084} 5091}
5085 5092
5086/* 5093/*
5087 * Initialize the forechannel and backchannel tables 5094 * Initialize or reset the forechannel and backchannel tables
5088 */ 5095 */
5089static int nfs4_init_slot_tables(struct nfs4_session *session) 5096static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
5090{ 5097{
5091 struct nfs4_slot_table *tbl; 5098 struct nfs4_slot_table *tbl;
5092 int status = 0; 5099 int status;
5093 5100
5094 tbl = &session->fc_slot_table; 5101 dprintk("--> %s\n", __func__);
5102 /* Fore channel */
5103 tbl = &ses->fc_slot_table;
5095 if (tbl->slots == NULL) { 5104 if (tbl->slots == NULL) {
5096 status = nfs4_init_slot_table(tbl, 5105 status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5097 session->fc_attrs.max_reqs, 1); 5106 if (status) /* -ENOMEM */
5107 return status;
5108 } else {
5109 status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5098 if (status) 5110 if (status)
5099 return status; 5111 return status;
5100 } 5112 }
5101 5113 /* Back channel */
5102 tbl = &session->bc_slot_table; 5114 tbl = &ses->bc_slot_table;
5103 if (tbl->slots == NULL) { 5115 if (tbl->slots == NULL) {
5104 status = nfs4_init_slot_table(tbl, 5116 status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5105 session->bc_attrs.max_reqs, 0);
5106 if (status) 5117 if (status)
5107 nfs4_destroy_slot_tables(session); 5118 /* Fore and back channel share a connection so get
5108 } 5119 * both slot tables or neither */
5109 5120 nfs4_destroy_slot_tables(ses);
5121 } else
5122 status = nfs4_reset_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5110 return status; 5123 return status;
5111} 5124}
5112 5125
@@ -5294,13 +5307,9 @@ int nfs4_proc_create_session(struct nfs_client *clp)
5294 if (status) 5307 if (status)
5295 goto out; 5308 goto out;
5296 5309
5297 /* Init and reset the fore channel */ 5310 /* Init or reset the session slot tables */
5298 status = nfs4_init_slot_tables(session); 5311 status = nfs4_setup_session_slot_tables(session);
5299 dprintk("slot table initialization returned %d\n", status); 5312 dprintk("slot table setup returned %d\n", status);
5300 if (status)
5301 goto out;
5302 status = nfs4_reset_slot_tables(session);
5303 dprintk("slot table reset returned %d\n", status);
5304 if (status) 5313 if (status)
5305 goto out; 5314 goto out;
5306 5315
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 6a7107ae6b72..a53f33b4ac3a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -49,6 +49,7 @@
49#include <linux/ratelimit.h> 49#include <linux/ratelimit.h>
50#include <linux/workqueue.h> 50#include <linux/workqueue.h>
51#include <linux/bitops.h> 51#include <linux/bitops.h>
52#include <linux/jiffies.h>
52 53
53#include "nfs4_fs.h" 54#include "nfs4_fs.h"
54#include "callback.h" 55#include "callback.h"
@@ -377,31 +378,24 @@ nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
377{ 378{
378 struct rb_node **p = &server->state_owners.rb_node, 379 struct rb_node **p = &server->state_owners.rb_node,
379 *parent = NULL; 380 *parent = NULL;
380 struct nfs4_state_owner *sp, *res = NULL; 381 struct nfs4_state_owner *sp;
381 382
382 while (*p != NULL) { 383 while (*p != NULL) {
383 parent = *p; 384 parent = *p;
384 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node); 385 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
385 386
386 if (server < sp->so_server) {
387 p = &parent->rb_left;
388 continue;
389 }
390 if (server > sp->so_server) {
391 p = &parent->rb_right;
392 continue;
393 }
394 if (cred < sp->so_cred) 387 if (cred < sp->so_cred)
395 p = &parent->rb_left; 388 p = &parent->rb_left;
396 else if (cred > sp->so_cred) 389 else if (cred > sp->so_cred)
397 p = &parent->rb_right; 390 p = &parent->rb_right;
398 else { 391 else {
392 if (!list_empty(&sp->so_lru))
393 list_del_init(&sp->so_lru);
399 atomic_inc(&sp->so_count); 394 atomic_inc(&sp->so_count);
400 res = sp; 395 return sp;
401 break;
402 } 396 }
403 } 397 }
404 return res; 398 return NULL;
405} 399}
406 400
407static struct nfs4_state_owner * 401static struct nfs4_state_owner *
@@ -421,6 +415,8 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
421 else if (new->so_cred > sp->so_cred) 415 else if (new->so_cred > sp->so_cred)
422 p = &parent->rb_right; 416 p = &parent->rb_right;
423 else { 417 else {
418 if (!list_empty(&sp->so_lru))
419 list_del_init(&sp->so_lru);
424 atomic_inc(&sp->so_count); 420 atomic_inc(&sp->so_count);
425 return sp; 421 return sp;
426 } 422 }
@@ -462,6 +458,7 @@ nfs4_alloc_state_owner(void)
462 spin_lock_init(&sp->so_sequence.lock); 458 spin_lock_init(&sp->so_sequence.lock);
463 INIT_LIST_HEAD(&sp->so_sequence.list); 459 INIT_LIST_HEAD(&sp->so_sequence.list);
464 atomic_set(&sp->so_count, 1); 460 atomic_set(&sp->so_count, 1);
461 INIT_LIST_HEAD(&sp->so_lru);
465 return sp; 462 return sp;
466} 463}
467 464
@@ -479,6 +476,38 @@ nfs4_drop_state_owner(struct nfs4_state_owner *sp)
479 } 476 }
480} 477}
481 478
479static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
480{
481 rpc_destroy_wait_queue(&sp->so_sequence.wait);
482 put_rpccred(sp->so_cred);
483 kfree(sp);
484}
485
486static void nfs4_gc_state_owners(struct nfs_server *server)
487{
488 struct nfs_client *clp = server->nfs_client;
489 struct nfs4_state_owner *sp, *tmp;
490 unsigned long time_min, time_max;
491 LIST_HEAD(doomed);
492
493 spin_lock(&clp->cl_lock);
494 time_max = jiffies;
495 time_min = (long)time_max - (long)clp->cl_lease_time;
496 list_for_each_entry_safe(sp, tmp, &server->state_owners_lru, so_lru) {
497 /* NB: LRU is sorted so that oldest is at the head */
498 if (time_in_range(sp->so_expires, time_min, time_max))
499 break;
500 list_move(&sp->so_lru, &doomed);
501 nfs4_remove_state_owner_locked(sp);
502 }
503 spin_unlock(&clp->cl_lock);
504
505 list_for_each_entry_safe(sp, tmp, &doomed, so_lru) {
506 list_del(&sp->so_lru);
507 nfs4_free_state_owner(sp);
508 }
509}
510
482/** 511/**
483 * nfs4_get_state_owner - Look up a state owner given a credential 512 * nfs4_get_state_owner - Look up a state owner given a credential
484 * @server: nfs_server to search 513 * @server: nfs_server to search
@@ -496,10 +525,10 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
496 sp = nfs4_find_state_owner_locked(server, cred); 525 sp = nfs4_find_state_owner_locked(server, cred);
497 spin_unlock(&clp->cl_lock); 526 spin_unlock(&clp->cl_lock);
498 if (sp != NULL) 527 if (sp != NULL)
499 return sp; 528 goto out;
500 new = nfs4_alloc_state_owner(); 529 new = nfs4_alloc_state_owner();
501 if (new == NULL) 530 if (new == NULL)
502 return NULL; 531 goto out;
503 new->so_server = server; 532 new->so_server = server;
504 new->so_cred = cred; 533 new->so_cred = cred;
505 spin_lock(&clp->cl_lock); 534 spin_lock(&clp->cl_lock);
@@ -511,26 +540,58 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
511 rpc_destroy_wait_queue(&new->so_sequence.wait); 540 rpc_destroy_wait_queue(&new->so_sequence.wait);
512 kfree(new); 541 kfree(new);
513 } 542 }
543out:
544 nfs4_gc_state_owners(server);
514 return sp; 545 return sp;
515} 546}
516 547
517/** 548/**
518 * nfs4_put_state_owner - Release a nfs4_state_owner 549 * nfs4_put_state_owner - Release a nfs4_state_owner
519 * @sp: state owner data to release 550 * @sp: state owner data to release
520 *
521 */ 551 */
522void nfs4_put_state_owner(struct nfs4_state_owner *sp) 552void nfs4_put_state_owner(struct nfs4_state_owner *sp)
523{ 553{
524 struct nfs_client *clp = sp->so_server->nfs_client; 554 struct nfs_server *server = sp->so_server;
525 struct rpc_cred *cred = sp->so_cred; 555 struct nfs_client *clp = server->nfs_client;
526 556
527 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) 557 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
528 return; 558 return;
529 nfs4_remove_state_owner_locked(sp); 559
560 if (!RB_EMPTY_NODE(&sp->so_server_node)) {
561 sp->so_expires = jiffies;
562 list_add_tail(&sp->so_lru, &server->state_owners_lru);
563 spin_unlock(&clp->cl_lock);
564 } else {
565 nfs4_remove_state_owner_locked(sp);
566 spin_unlock(&clp->cl_lock);
567 nfs4_free_state_owner(sp);
568 }
569}
570
571/**
572 * nfs4_purge_state_owners - Release all cached state owners
573 * @server: nfs_server with cached state owners to release
574 *
575 * Called at umount time. Remaining state owners will be on
576 * the LRU with ref count of zero.
577 */
578void nfs4_purge_state_owners(struct nfs_server *server)
579{
580 struct nfs_client *clp = server->nfs_client;
581 struct nfs4_state_owner *sp, *tmp;
582 LIST_HEAD(doomed);
583
584 spin_lock(&clp->cl_lock);
585 list_for_each_entry_safe(sp, tmp, &server->state_owners_lru, so_lru) {
586 list_move(&sp->so_lru, &doomed);
587 nfs4_remove_state_owner_locked(sp);
588 }
530 spin_unlock(&clp->cl_lock); 589 spin_unlock(&clp->cl_lock);
531 rpc_destroy_wait_queue(&sp->so_sequence.wait); 590
532 put_rpccred(cred); 591 list_for_each_entry_safe(sp, tmp, &doomed, so_lru) {
533 kfree(sp); 592 list_del(&sp->so_lru);
593 nfs4_free_state_owner(sp);
594 }
534} 595}
535 596
536static struct nfs4_state * 597static struct nfs4_state *
@@ -1402,6 +1463,7 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov
1402restart: 1463restart:
1403 rcu_read_lock(); 1464 rcu_read_lock();
1404 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 1465 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
1466 nfs4_purge_state_owners(server);
1405 spin_lock(&clp->cl_lock); 1467 spin_lock(&clp->cl_lock);
1406 for (pos = rb_first(&server->state_owners); 1468 for (pos = rb_first(&server->state_owners);
1407 pos != NULL; 1469 pos != NULL;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e6161b213ed1..95e92e438407 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2298,7 +2298,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
2298 encode_getfh(xdr, &hdr); 2298 encode_getfh(xdr, &hdr);
2299 encode_getfattr(xdr, args->bitmask, &hdr); 2299 encode_getfattr(xdr, args->bitmask, &hdr);
2300 encode_restorefh(xdr, &hdr); 2300 encode_restorefh(xdr, &hdr);
2301 encode_getfattr(xdr, args->bitmask, &hdr); 2301 encode_getfattr(xdr, args->dir_bitmask, &hdr);
2302 encode_nops(&hdr); 2302 encode_nops(&hdr);
2303} 2303}
2304 2304
@@ -2517,11 +2517,13 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
2517 encode_compound_hdr(xdr, req, &hdr); 2517 encode_compound_hdr(xdr, req, &hdr);
2518 encode_sequence(xdr, &args->seq_args, &hdr); 2518 encode_sequence(xdr, &args->seq_args, &hdr);
2519 encode_putfh(xdr, args->fh, &hdr); 2519 encode_putfh(xdr, args->fh, &hdr);
2520 replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1; 2520 replen = hdr.replen + op_decode_hdr_maxsz + 1;
2521 encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); 2521 encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
2522 2522
2523 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, 2523 xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
2524 args->acl_pages, args->acl_pgbase, args->acl_len); 2524 args->acl_pages, args->acl_pgbase, args->acl_len);
2525 xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
2526
2525 encode_nops(&hdr); 2527 encode_nops(&hdr);
2526} 2528}
2527 2529
@@ -3790,7 +3792,8 @@ out_overflow:
3790} 3792}
3791 3793
3792static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, 3794static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
3793 const struct nfs_server *server, uint32_t *uid, int may_sleep) 3795 const struct nfs_server *server, uint32_t *uid,
3796 struct nfs4_string *owner_name)
3794{ 3797{
3795 uint32_t len; 3798 uint32_t len;
3796 __be32 *p; 3799 __be32 *p;
@@ -3807,8 +3810,12 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
3807 p = xdr_inline_decode(xdr, len); 3810 p = xdr_inline_decode(xdr, len);
3808 if (unlikely(!p)) 3811 if (unlikely(!p))
3809 goto out_overflow; 3812 goto out_overflow;
3810 if (!may_sleep) { 3813 if (owner_name != NULL) {
3811 /* do nothing */ 3814 owner_name->data = kmemdup(p, len, GFP_NOWAIT);
3815 if (owner_name->data != NULL) {
3816 owner_name->len = len;
3817 ret = NFS_ATTR_FATTR_OWNER_NAME;
3818 }
3812 } else if (len < XDR_MAX_NETOBJ) { 3819 } else if (len < XDR_MAX_NETOBJ) {
3813 if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) 3820 if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0)
3814 ret = NFS_ATTR_FATTR_OWNER; 3821 ret = NFS_ATTR_FATTR_OWNER;
@@ -3828,7 +3835,8 @@ out_overflow:
3828} 3835}
3829 3836
3830static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, 3837static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
3831 const struct nfs_server *server, uint32_t *gid, int may_sleep) 3838 const struct nfs_server *server, uint32_t *gid,
3839 struct nfs4_string *group_name)
3832{ 3840{
3833 uint32_t len; 3841 uint32_t len;
3834 __be32 *p; 3842 __be32 *p;
@@ -3845,8 +3853,12 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
3845 p = xdr_inline_decode(xdr, len); 3853 p = xdr_inline_decode(xdr, len);
3846 if (unlikely(!p)) 3854 if (unlikely(!p))
3847 goto out_overflow; 3855 goto out_overflow;
3848 if (!may_sleep) { 3856 if (group_name != NULL) {
3849 /* do nothing */ 3857 group_name->data = kmemdup(p, len, GFP_NOWAIT);
3858 if (group_name->data != NULL) {
3859 group_name->len = len;
3860 ret = NFS_ATTR_FATTR_GROUP_NAME;
3861 }
3850 } else if (len < XDR_MAX_NETOBJ) { 3862 } else if (len < XDR_MAX_NETOBJ) {
3851 if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) 3863 if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0)
3852 ret = NFS_ATTR_FATTR_GROUP; 3864 ret = NFS_ATTR_FATTR_GROUP;
@@ -4283,7 +4295,7 @@ xdr_error:
4283 4295
4284static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, 4296static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4285 struct nfs_fattr *fattr, struct nfs_fh *fh, 4297 struct nfs_fattr *fattr, struct nfs_fh *fh,
4286 const struct nfs_server *server, int may_sleep) 4298 const struct nfs_server *server)
4287{ 4299{
4288 int status; 4300 int status;
4289 umode_t fmode = 0; 4301 umode_t fmode = 0;
@@ -4350,12 +4362,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4350 goto xdr_error; 4362 goto xdr_error;
4351 fattr->valid |= status; 4363 fattr->valid |= status;
4352 4364
4353 status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, may_sleep); 4365 status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, fattr->owner_name);
4354 if (status < 0) 4366 if (status < 0)
4355 goto xdr_error; 4367 goto xdr_error;
4356 fattr->valid |= status; 4368 fattr->valid |= status;
4357 4369
4358 status = decode_attr_group(xdr, bitmap, server, &fattr->gid, may_sleep); 4370 status = decode_attr_group(xdr, bitmap, server, &fattr->gid, fattr->group_name);
4359 if (status < 0) 4371 if (status < 0)
4360 goto xdr_error; 4372 goto xdr_error;
4361 fattr->valid |= status; 4373 fattr->valid |= status;
@@ -4396,7 +4408,7 @@ xdr_error:
4396} 4408}
4397 4409
4398static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4410static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4399 struct nfs_fh *fh, const struct nfs_server *server, int may_sleep) 4411 struct nfs_fh *fh, const struct nfs_server *server)
4400{ 4412{
4401 __be32 *savep; 4413 __be32 *savep;
4402 uint32_t attrlen, 4414 uint32_t attrlen,
@@ -4415,7 +4427,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
4415 if (status < 0) 4427 if (status < 0)
4416 goto xdr_error; 4428 goto xdr_error;
4417 4429
4418 status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server, may_sleep); 4430 status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server);
4419 if (status < 0) 4431 if (status < 0)
4420 goto xdr_error; 4432 goto xdr_error;
4421 4433
@@ -4426,9 +4438,9 @@ xdr_error:
4426} 4438}
4427 4439
4428static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4440static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4429 const struct nfs_server *server, int may_sleep) 4441 const struct nfs_server *server)
4430{ 4442{
4431 return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep); 4443 return decode_getfattr_generic(xdr, fattr, NULL, server);
4432} 4444}
4433 4445
4434/* 4446/*
@@ -4957,17 +4969,18 @@ decode_restorefh(struct xdr_stream *xdr)
4957} 4969}
4958 4970
4959static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, 4971static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4960 size_t *acl_len) 4972 struct nfs_getaclres *res)
4961{ 4973{
4962 __be32 *savep; 4974 __be32 *savep, *bm_p;
4963 uint32_t attrlen, 4975 uint32_t attrlen,
4964 bitmap[3] = {0}; 4976 bitmap[3] = {0};
4965 struct kvec *iov = req->rq_rcv_buf.head; 4977 struct kvec *iov = req->rq_rcv_buf.head;
4966 int status; 4978 int status;
4967 4979
4968 *acl_len = 0; 4980 res->acl_len = 0;
4969 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 4981 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
4970 goto out; 4982 goto out;
4983 bm_p = xdr->p;
4971 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 4984 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
4972 goto out; 4985 goto out;
4973 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 4986 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
@@ -4979,18 +4992,30 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4979 size_t hdrlen; 4992 size_t hdrlen;
4980 u32 recvd; 4993 u32 recvd;
4981 4994
4995 /* The bitmap (xdr len + bitmaps) and the attr xdr len words
4996 * are stored with the acl data to handle the problem of
4997 * variable length bitmaps.*/
4998 xdr->p = bm_p;
4999 res->acl_data_offset = be32_to_cpup(bm_p) + 2;
5000 res->acl_data_offset <<= 2;
5001
4982 /* We ignore &savep and don't do consistency checks on 5002 /* We ignore &savep and don't do consistency checks on
4983 * the attr length. Let userspace figure it out.... */ 5003 * the attr length. Let userspace figure it out.... */
4984 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; 5004 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
5005 attrlen += res->acl_data_offset;
4985 recvd = req->rq_rcv_buf.len - hdrlen; 5006 recvd = req->rq_rcv_buf.len - hdrlen;
4986 if (attrlen > recvd) { 5007 if (attrlen > recvd) {
4987 dprintk("NFS: server cheating in getattr" 5008 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
4988 " acl reply: attrlen %u > recvd %u\n", 5009 /* getxattr interface called with a NULL buf */
5010 res->acl_len = attrlen;
5011 goto out;
5012 }
5013 dprintk("NFS: acl reply: attrlen %u > recvd %u\n",
4989 attrlen, recvd); 5014 attrlen, recvd);
4990 return -EINVAL; 5015 return -EINVAL;
4991 } 5016 }
4992 xdr_read_pages(xdr, attrlen); 5017 xdr_read_pages(xdr, attrlen);
4993 *acl_len = attrlen; 5018 res->acl_len = attrlen;
4994 } else 5019 } else
4995 status = -EOPNOTSUPP; 5020 status = -EOPNOTSUPP;
4996 5021
@@ -5696,8 +5721,7 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp,
5696 status = decode_open_downgrade(xdr, res); 5721 status = decode_open_downgrade(xdr, res);
5697 if (status != 0) 5722 if (status != 0)
5698 goto out; 5723 goto out;
5699 decode_getfattr(xdr, res->fattr, res->server, 5724 decode_getfattr(xdr, res->fattr, res->server);
5700 !RPC_IS_ASYNC(rqstp->rq_task));
5701out: 5725out:
5702 return status; 5726 return status;
5703} 5727}
@@ -5723,8 +5747,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5723 status = decode_access(xdr, res); 5747 status = decode_access(xdr, res);
5724 if (status != 0) 5748 if (status != 0)
5725 goto out; 5749 goto out;
5726 decode_getfattr(xdr, res->fattr, res->server, 5750 decode_getfattr(xdr, res->fattr, res->server);
5727 !RPC_IS_ASYNC(rqstp->rq_task));
5728out: 5751out:
5729 return status; 5752 return status;
5730} 5753}
@@ -5753,8 +5776,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5753 status = decode_getfh(xdr, res->fh); 5776 status = decode_getfh(xdr, res->fh);
5754 if (status) 5777 if (status)
5755 goto out; 5778 goto out;
5756 status = decode_getfattr(xdr, res->fattr, res->server 5779 status = decode_getfattr(xdr, res->fattr, res->server);
5757 ,!RPC_IS_ASYNC(rqstp->rq_task));
5758out: 5780out:
5759 return status; 5781 return status;
5760} 5782}
@@ -5780,8 +5802,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
5780 goto out; 5802 goto out;
5781 status = decode_getfh(xdr, res->fh); 5803 status = decode_getfh(xdr, res->fh);
5782 if (status == 0) 5804 if (status == 0)
5783 status = decode_getfattr(xdr, res->fattr, res->server, 5805 status = decode_getfattr(xdr, res->fattr, res->server);
5784 !RPC_IS_ASYNC(rqstp->rq_task));
5785out: 5806out:
5786 return status; 5807 return status;
5787} 5808}
@@ -5807,8 +5828,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5807 status = decode_remove(xdr, &res->cinfo); 5828 status = decode_remove(xdr, &res->cinfo);
5808 if (status) 5829 if (status)
5809 goto out; 5830 goto out;
5810 decode_getfattr(xdr, res->dir_attr, res->server, 5831 decode_getfattr(xdr, res->dir_attr, res->server);
5811 !RPC_IS_ASYNC(rqstp->rq_task));
5812out: 5832out:
5813 return status; 5833 return status;
5814} 5834}
@@ -5841,14 +5861,12 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5841 if (status) 5861 if (status)
5842 goto out; 5862 goto out;
5843 /* Current FH is target directory */ 5863 /* Current FH is target directory */
5844 if (decode_getfattr(xdr, res->new_fattr, res->server, 5864 if (decode_getfattr(xdr, res->new_fattr, res->server))
5845 !RPC_IS_ASYNC(rqstp->rq_task)) != 0)
5846 goto out; 5865 goto out;
5847 status = decode_restorefh(xdr); 5866 status = decode_restorefh(xdr);
5848 if (status) 5867 if (status)
5849 goto out; 5868 goto out;
5850 decode_getfattr(xdr, res->old_fattr, res->server, 5869 decode_getfattr(xdr, res->old_fattr, res->server);
5851 !RPC_IS_ASYNC(rqstp->rq_task));
5852out: 5870out:
5853 return status; 5871 return status;
5854} 5872}
@@ -5884,14 +5902,12 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5884 * Note order: OP_LINK leaves the directory as the current 5902 * Note order: OP_LINK leaves the directory as the current
5885 * filehandle. 5903 * filehandle.
5886 */ 5904 */
5887 if (decode_getfattr(xdr, res->dir_attr, res->server, 5905 if (decode_getfattr(xdr, res->dir_attr, res->server))
5888 !RPC_IS_ASYNC(rqstp->rq_task)) != 0)
5889 goto out; 5906 goto out;
5890 status = decode_restorefh(xdr); 5907 status = decode_restorefh(xdr);
5891 if (status) 5908 if (status)
5892 goto out; 5909 goto out;
5893 decode_getfattr(xdr, res->fattr, res->server, 5910 decode_getfattr(xdr, res->fattr, res->server);
5894 !RPC_IS_ASYNC(rqstp->rq_task));
5895out: 5911out:
5896 return status; 5912 return status;
5897} 5913}
@@ -5923,14 +5939,12 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5923 status = decode_getfh(xdr, res->fh); 5939 status = decode_getfh(xdr, res->fh);
5924 if (status) 5940 if (status)
5925 goto out; 5941 goto out;
5926 if (decode_getfattr(xdr, res->fattr, res->server, 5942 if (decode_getfattr(xdr, res->fattr, res->server))
5927 !RPC_IS_ASYNC(rqstp->rq_task)) != 0)
5928 goto out; 5943 goto out;
5929 status = decode_restorefh(xdr); 5944 status = decode_restorefh(xdr);
5930 if (status) 5945 if (status)
5931 goto out; 5946 goto out;
5932 decode_getfattr(xdr, res->dir_fattr, res->server, 5947 decode_getfattr(xdr, res->dir_fattr, res->server);
5933 !RPC_IS_ASYNC(rqstp->rq_task));
5934out: 5948out:
5935 return status; 5949 return status;
5936} 5950}
@@ -5962,8 +5976,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5962 status = decode_putfh(xdr); 5976 status = decode_putfh(xdr);
5963 if (status) 5977 if (status)
5964 goto out; 5978 goto out;
5965 status = decode_getfattr(xdr, res->fattr, res->server, 5979 status = decode_getfattr(xdr, res->fattr, res->server);
5966 !RPC_IS_ASYNC(rqstp->rq_task));
5967out: 5980out:
5968 return status; 5981 return status;
5969} 5982}
@@ -6028,7 +6041,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6028 status = decode_putfh(xdr); 6041 status = decode_putfh(xdr);
6029 if (status) 6042 if (status)
6030 goto out; 6043 goto out;
6031 status = decode_getacl(xdr, rqstp, &res->acl_len); 6044 status = decode_getacl(xdr, rqstp, res);
6032 6045
6033out: 6046out:
6034 return status; 6047 return status;
@@ -6061,8 +6074,7 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6061 * an ESTALE error. Shouldn't be a problem, 6074 * an ESTALE error. Shouldn't be a problem,
6062 * though, since fattr->valid will remain unset. 6075 * though, since fattr->valid will remain unset.
6063 */ 6076 */
6064 decode_getfattr(xdr, res->fattr, res->server, 6077 decode_getfattr(xdr, res->fattr, res->server);
6065 !RPC_IS_ASYNC(rqstp->rq_task));
6066out: 6078out:
6067 return status; 6079 return status;
6068} 6080}
@@ -6093,13 +6105,11 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6093 goto out; 6105 goto out;
6094 if (decode_getfh(xdr, &res->fh) != 0) 6106 if (decode_getfh(xdr, &res->fh) != 0)
6095 goto out; 6107 goto out;
6096 if (decode_getfattr(xdr, res->f_attr, res->server, 6108 if (decode_getfattr(xdr, res->f_attr, res->server) != 0)
6097 !RPC_IS_ASYNC(rqstp->rq_task)) != 0)
6098 goto out; 6109 goto out;
6099 if (decode_restorefh(xdr) != 0) 6110 if (decode_restorefh(xdr) != 0)
6100 goto out; 6111 goto out;
6101 decode_getfattr(xdr, res->dir_attr, res->server, 6112 decode_getfattr(xdr, res->dir_attr, res->server);
6102 !RPC_IS_ASYNC(rqstp->rq_task));
6103out: 6113out:
6104 return status; 6114 return status;
6105} 6115}
@@ -6147,8 +6157,7 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
6147 status = decode_open(xdr, res); 6157 status = decode_open(xdr, res);
6148 if (status) 6158 if (status)
6149 goto out; 6159 goto out;
6150 decode_getfattr(xdr, res->f_attr, res->server, 6160 decode_getfattr(xdr, res->f_attr, res->server);
6151 !RPC_IS_ASYNC(rqstp->rq_task));
6152out: 6161out:
6153 return status; 6162 return status;
6154} 6163}
@@ -6175,8 +6184,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
6175 status = decode_setattr(xdr); 6184 status = decode_setattr(xdr);
6176 if (status) 6185 if (status)
6177 goto out; 6186 goto out;
6178 decode_getfattr(xdr, res->fattr, res->server, 6187 decode_getfattr(xdr, res->fattr, res->server);
6179 !RPC_IS_ASYNC(rqstp->rq_task));
6180out: 6188out:
6181 return status; 6189 return status;
6182} 6190}
@@ -6356,8 +6364,7 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6356 if (status) 6364 if (status)
6357 goto out; 6365 goto out;
6358 if (res->fattr) 6366 if (res->fattr)
6359 decode_getfattr(xdr, res->fattr, res->server, 6367 decode_getfattr(xdr, res->fattr, res->server);
6360 !RPC_IS_ASYNC(rqstp->rq_task));
6361 if (!status) 6368 if (!status)
6362 status = res->count; 6369 status = res->count;
6363out: 6370out:
@@ -6386,8 +6393,7 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6386 if (status) 6393 if (status)
6387 goto out; 6394 goto out;
6388 if (res->fattr) 6395 if (res->fattr)
6389 decode_getfattr(xdr, res->fattr, res->server, 6396 decode_getfattr(xdr, res->fattr, res->server);
6390 !RPC_IS_ASYNC(rqstp->rq_task));
6391out: 6397out:
6392 return status; 6398 return status;
6393} 6399}
@@ -6546,8 +6552,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp,
6546 status = decode_delegreturn(xdr); 6552 status = decode_delegreturn(xdr);
6547 if (status != 0) 6553 if (status != 0)
6548 goto out; 6554 goto out;
6549 decode_getfattr(xdr, res->fattr, res->server, 6555 decode_getfattr(xdr, res->fattr, res->server);
6550 !RPC_IS_ASYNC(rqstp->rq_task));
6551out: 6556out:
6552 return status; 6557 return status;
6553} 6558}
@@ -6576,8 +6581,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
6576 goto out; 6581 goto out;
6577 xdr_enter_page(xdr, PAGE_SIZE); 6582 xdr_enter_page(xdr, PAGE_SIZE);
6578 status = decode_getfattr(xdr, &res->fs_locations->fattr, 6583 status = decode_getfattr(xdr, &res->fs_locations->fattr,
6579 res->fs_locations->server, 6584 res->fs_locations->server);
6580 !RPC_IS_ASYNC(req->rq_task));
6581out: 6585out:
6582 return status; 6586 return status;
6583} 6587}
@@ -6826,8 +6830,7 @@ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
6826 status = decode_layoutcommit(xdr, rqstp, res); 6830 status = decode_layoutcommit(xdr, rqstp, res);
6827 if (status) 6831 if (status)
6828 goto out; 6832 goto out;
6829 decode_getfattr(xdr, res->fattr, res->server, 6833 decode_getfattr(xdr, res->fattr, res->server);
6830 !RPC_IS_ASYNC(rqstp->rq_task));
6831out: 6834out:
6832 return status; 6835 return status;
6833} 6836}
@@ -6958,7 +6961,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
6958 goto out_overflow; 6961 goto out_overflow;
6959 6962
6960 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, 6963 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
6961 entry->server, 1) < 0) 6964 entry->server) < 0)
6962 goto out_overflow; 6965 goto out_overflow;
6963 if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) 6966 if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
6964 entry->ino = entry->fattr->mounted_on_fileid; 6967 entry->ino = entry->fattr->mounted_on_fileid;
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index c807ab93140e..55d01280a609 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -551,7 +551,8 @@ static const struct nfs_pageio_ops objio_pg_write_ops = {
551static struct pnfs_layoutdriver_type objlayout_type = { 551static struct pnfs_layoutdriver_type objlayout_type = {
552 .id = LAYOUT_OSD2_OBJECTS, 552 .id = LAYOUT_OSD2_OBJECTS,
553 .name = "LAYOUT_OSD2_OBJECTS", 553 .name = "LAYOUT_OSD2_OBJECTS",
554 .flags = PNFS_LAYOUTRET_ON_SETATTR, 554 .flags = PNFS_LAYOUTRET_ON_SETATTR |
555 PNFS_LAYOUTRET_ON_ERROR,
555 556
556 .alloc_layout_hdr = objlayout_alloc_layout_hdr, 557 .alloc_layout_hdr = objlayout_alloc_layout_hdr,
557 .free_layout_hdr = objlayout_free_layout_hdr, 558 .free_layout_hdr = objlayout_free_layout_hdr,
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index 72074e3a04f9..b3c29039f5b8 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -254,6 +254,8 @@ objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
254 oir->status = rdata->task.tk_status = status; 254 oir->status = rdata->task.tk_status = status;
255 if (status >= 0) 255 if (status >= 0)
256 rdata->res.count = status; 256 rdata->res.count = status;
257 else
258 rdata->pnfs_error = status;
257 objlayout_iodone(oir); 259 objlayout_iodone(oir);
258 /* must not use oir after this point */ 260 /* must not use oir after this point */
259 261
@@ -334,6 +336,8 @@ objlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
334 if (status >= 0) { 336 if (status >= 0) {
335 wdata->res.count = status; 337 wdata->res.count = status;
336 wdata->verf.committed = oir->committed; 338 wdata->verf.committed = oir->committed;
339 } else {
340 wdata->pnfs_error = status;
337 } 341 }
338 objlayout_iodone(oir); 342 objlayout_iodone(oir);
339 /* must not use oir after this point */ 343 /* must not use oir after this point */
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 8e672a2b2d69..17149a490065 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1166,6 +1166,33 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1166} 1166}
1167EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); 1167EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
1168 1168
1169static int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head)
1170{
1171 struct nfs_pageio_descriptor pgio;
1172 LIST_HEAD(failed);
1173
1174 /* Resend all requests through the MDS */
1175 nfs_pageio_init_write_mds(&pgio, inode, FLUSH_STABLE);
1176 while (!list_empty(head)) {
1177 struct nfs_page *req = nfs_list_entry(head->next);
1178
1179 nfs_list_remove_request(req);
1180 if (!nfs_pageio_add_request(&pgio, req))
1181 nfs_list_add_request(req, &failed);
1182 }
1183 nfs_pageio_complete(&pgio);
1184
1185 if (!list_empty(&failed)) {
1186 /* For some reason our attempt to resend pages. Mark the
1187 * overall send request as having failed, and let
1188 * nfs_writeback_release_full deal with the error.
1189 */
1190 list_move(&failed, head);
1191 return -EIO;
1192 }
1193 return 0;
1194}
1195
1169/* 1196/*
1170 * Called by non rpc-based layout drivers 1197 * Called by non rpc-based layout drivers
1171 */ 1198 */
@@ -1175,9 +1202,17 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
1175 pnfs_set_layoutcommit(data); 1202 pnfs_set_layoutcommit(data);
1176 data->mds_ops->rpc_call_done(&data->task, data); 1203 data->mds_ops->rpc_call_done(&data->task, data);
1177 } else { 1204 } else {
1178 put_lseg(data->lseg);
1179 data->lseg = NULL;
1180 dprintk("pnfs write error = %d\n", data->pnfs_error); 1205 dprintk("pnfs write error = %d\n", data->pnfs_error);
1206 if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
1207 PNFS_LAYOUTRET_ON_ERROR) {
1208 /* Don't lo_commit on error, Server will needs to
1209 * preform a file recovery.
1210 */
1211 clear_bit(NFS_INO_LAYOUTCOMMIT,
1212 &NFS_I(data->inode)->flags);
1213 pnfs_return_layout(data->inode);
1214 }
1215 data->task.tk_status = pnfs_write_done_resend_to_mds(data->inode, &data->pages);
1181 } 1216 }
1182 data->mds_ops->rpc_release(data); 1217 data->mds_ops->rpc_release(data);
1183} 1218}
@@ -1267,6 +1302,9 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
1267 put_lseg(data->lseg); 1302 put_lseg(data->lseg);
1268 data->lseg = NULL; 1303 data->lseg = NULL;
1269 dprintk("pnfs write error = %d\n", data->pnfs_error); 1304 dprintk("pnfs write error = %d\n", data->pnfs_error);
1305 if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
1306 PNFS_LAYOUTRET_ON_ERROR)
1307 pnfs_return_layout(data->inode);
1270 1308
1271 nfs_pageio_init_read_mds(&pgio, data->inode); 1309 nfs_pageio_init_read_mds(&pgio, data->inode);
1272 1310
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 1509530cb111..53d593a0a4f2 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -68,6 +68,7 @@ enum {
68enum layoutdriver_policy_flags { 68enum layoutdriver_policy_flags {
69 /* Should the pNFS client commit and return the layout upon a setattr */ 69 /* Should the pNFS client commit and return the layout upon a setattr */
70 PNFS_LAYOUTRET_ON_SETATTR = 1 << 0, 70 PNFS_LAYOUTRET_ON_SETATTR = 1 << 0,
71 PNFS_LAYOUTRET_ON_ERROR = 1 << 1,
71}; 72};
72 73
73struct nfs4_deviceid_node; 74struct nfs4_deviceid_node;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index e463967aafb8..3dfa4f112c0a 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -908,10 +908,24 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
908 data->auth_flavor_len = 1; 908 data->auth_flavor_len = 1;
909 data->version = version; 909 data->version = version;
910 data->minorversion = 0; 910 data->minorversion = 0;
911 security_init_mnt_opts(&data->lsm_opts);
911 } 912 }
912 return data; 913 return data;
913} 914}
914 915
916static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data)
917{
918 if (data) {
919 kfree(data->client_address);
920 kfree(data->mount_server.hostname);
921 kfree(data->nfs_server.export_path);
922 kfree(data->nfs_server.hostname);
923 kfree(data->fscache_uniq);
924 security_free_mnt_opts(&data->lsm_opts);
925 kfree(data);
926 }
927}
928
915/* 929/*
916 * Sanity-check a server address provided by the mount command. 930 * Sanity-check a server address provided by the mount command.
917 * 931 *
@@ -2219,9 +2233,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2219 data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION); 2233 data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
2220 mntfh = nfs_alloc_fhandle(); 2234 mntfh = nfs_alloc_fhandle();
2221 if (data == NULL || mntfh == NULL) 2235 if (data == NULL || mntfh == NULL)
2222 goto out_free_fh; 2236 goto out;
2223
2224 security_init_mnt_opts(&data->lsm_opts);
2225 2237
2226 /* Validate the mount data */ 2238 /* Validate the mount data */
2227 error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); 2239 error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
@@ -2233,8 +2245,6 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2233#ifdef CONFIG_NFS_V4 2245#ifdef CONFIG_NFS_V4
2234 if (data->version == 4) { 2246 if (data->version == 4) {
2235 mntroot = nfs4_try_mount(flags, dev_name, data); 2247 mntroot = nfs4_try_mount(flags, dev_name, data);
2236 kfree(data->client_address);
2237 kfree(data->nfs_server.export_path);
2238 goto out; 2248 goto out;
2239 } 2249 }
2240#endif /* CONFIG_NFS_V4 */ 2250#endif /* CONFIG_NFS_V4 */
@@ -2289,13 +2299,8 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2289 s->s_flags |= MS_ACTIVE; 2299 s->s_flags |= MS_ACTIVE;
2290 2300
2291out: 2301out:
2292 kfree(data->nfs_server.hostname); 2302 nfs_free_parsed_mount_data(data);
2293 kfree(data->mount_server.hostname);
2294 kfree(data->fscache_uniq);
2295 security_free_mnt_opts(&data->lsm_opts);
2296out_free_fh:
2297 nfs_free_fhandle(mntfh); 2303 nfs_free_fhandle(mntfh);
2298 kfree(data);
2299 return mntroot; 2304 return mntroot;
2300 2305
2301out_err_nosb: 2306out_err_nosb:
@@ -2622,9 +2627,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
2622 2627
2623 mntfh = nfs_alloc_fhandle(); 2628 mntfh = nfs_alloc_fhandle();
2624 if (data == NULL || mntfh == NULL) 2629 if (data == NULL || mntfh == NULL)
2625 goto out_free_fh; 2630 goto out;
2626
2627 security_init_mnt_opts(&data->lsm_opts);
2628 2631
2629 /* Get a volume representation */ 2632 /* Get a volume representation */
2630 server = nfs4_create_server(data, mntfh); 2633 server = nfs4_create_server(data, mntfh);
@@ -2676,13 +2679,10 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
2676 2679
2677 s->s_flags |= MS_ACTIVE; 2680 s->s_flags |= MS_ACTIVE;
2678 2681
2679 security_free_mnt_opts(&data->lsm_opts);
2680 nfs_free_fhandle(mntfh); 2682 nfs_free_fhandle(mntfh);
2681 return mntroot; 2683 return mntroot;
2682 2684
2683out: 2685out:
2684 security_free_mnt_opts(&data->lsm_opts);
2685out_free_fh:
2686 nfs_free_fhandle(mntfh); 2686 nfs_free_fhandle(mntfh);
2687 return ERR_PTR(error); 2687 return ERR_PTR(error);
2688 2688
@@ -2839,7 +2839,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
2839 2839
2840 data = nfs_alloc_parsed_mount_data(4); 2840 data = nfs_alloc_parsed_mount_data(4);
2841 if (data == NULL) 2841 if (data == NULL)
2842 goto out_free_data; 2842 goto out;
2843 2843
2844 /* Validate the mount data */ 2844 /* Validate the mount data */
2845 error = nfs4_validate_mount_data(raw_data, data, dev_name); 2845 error = nfs4_validate_mount_data(raw_data, data, dev_name);
@@ -2853,12 +2853,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
2853 error = PTR_ERR(res); 2853 error = PTR_ERR(res);
2854 2854
2855out: 2855out:
2856 kfree(data->client_address); 2856 nfs_free_parsed_mount_data(data);
2857 kfree(data->nfs_server.export_path);
2858 kfree(data->nfs_server.hostname);
2859 kfree(data->fscache_uniq);
2860out_free_data:
2861 kfree(data);
2862 dprintk("<-- nfs4_mount() = %d%s\n", error, 2857 dprintk("<-- nfs4_mount() = %d%s\n", error,
2863 error != 0 ? " [error]" : ""); 2858 error != 0 ? " [error]" : "");
2864 return res; 2859 return res;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 1dda78db6a73..0c3885255f97 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1052,7 +1052,7 @@ static const struct nfs_pageio_ops nfs_pageio_write_ops = {
1052 .pg_doio = nfs_generic_pg_writepages, 1052 .pg_doio = nfs_generic_pg_writepages,
1053}; 1053};
1054 1054
1055static void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio, 1055void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
1056 struct inode *inode, int ioflags) 1056 struct inode *inode, int ioflags)
1057{ 1057{
1058 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, 1058 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops,
@@ -1166,13 +1166,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1166static void nfs_writeback_release_full(void *calldata) 1166static void nfs_writeback_release_full(void *calldata)
1167{ 1167{
1168 struct nfs_write_data *data = calldata; 1168 struct nfs_write_data *data = calldata;
1169 int ret, status = data->task.tk_status; 1169 int status = data->task.tk_status;
1170 struct nfs_pageio_descriptor pgio;
1171
1172 if (data->pnfs_error) {
1173 nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE);
1174 pgio.pg_recoalesce = 1;
1175 }
1176 1170
1177 /* Update attributes as result of writeback. */ 1171 /* Update attributes as result of writeback. */
1178 while (!list_empty(&data->pages)) { 1172 while (!list_empty(&data->pages)) {
@@ -1188,11 +1182,6 @@ static void nfs_writeback_release_full(void *calldata)
1188 req->wb_bytes, 1182 req->wb_bytes,
1189 (long long)req_offset(req)); 1183 (long long)req_offset(req));
1190 1184
1191 if (data->pnfs_error) {
1192 dprintk(", pnfs error = %d\n", data->pnfs_error);
1193 goto next;
1194 }
1195
1196 if (status < 0) { 1185 if (status < 0) {
1197 nfs_set_pageerror(page); 1186 nfs_set_pageerror(page);
1198 nfs_context_set_write_error(req->wb_context, status); 1187 nfs_context_set_write_error(req->wb_context, status);
@@ -1212,19 +1201,7 @@ remove_request:
1212 next: 1201 next:
1213 nfs_clear_page_tag_locked(req); 1202 nfs_clear_page_tag_locked(req);
1214 nfs_end_page_writeback(page); 1203 nfs_end_page_writeback(page);
1215 if (data->pnfs_error) {
1216 lock_page(page);
1217 nfs_pageio_cond_complete(&pgio, page->index);
1218 ret = nfs_page_async_flush(&pgio, page, 0);
1219 if (ret) {
1220 nfs_set_pageerror(page);
1221 dprintk("rewrite to MDS error = %d\n", ret);
1222 }
1223 unlock_page(page);
1224 }
1225 } 1204 }
1226 if (data->pnfs_error)
1227 nfs_pageio_complete(&pgio);
1228 nfs_writedata_release(calldata); 1205 nfs_writedata_release(calldata);
1229} 1206}
1230 1207