aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--Documentation/kernel-parameters.txt17
-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
-rw-r--r--fs/nfsd/nfs4callback.c2
-rw-r--r--include/linux/nfs_fs_sb.h1
-rw-r--r--include/linux/nfs_idmap.h8
-rw-r--r--include/linux/nfs_xdr.h22
-rw-r--r--include/linux/sunrpc/auth.h3
-rw-r--r--include/linux/sunrpc/auth_gss.h2
-rw-r--r--include/linux/sunrpc/xdr.h2
-rw-r--r--init/do_mounts.c35
-rw-r--r--net/sunrpc/auth_generic.c6
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c40
-rw-r--r--net/sunrpc/xdr.c3
29 files changed, 525 insertions, 271 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9373d95319c1..73baff1e0c70 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1634,12 +1634,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1634 The default is to return 64-bit inode numbers. 1634 The default is to return 64-bit inode numbers.
1635 1635
1636 nfs.nfs4_disable_idmapping= 1636 nfs.nfs4_disable_idmapping=
1637 [NFSv4] When set, this option disables the NFSv4 1637 [NFSv4] When set to the default of '1', this option
1638 idmapper on the client, but only if the mount 1638 ensures that both the RPC level authentication
1639 is using the 'sec=sys' security flavour. This may 1639 scheme and the NFS level operations agree to use
1640 make migration from legacy NFSv2/v3 systems easier 1640 numeric uids/gids if the mount is using the
1641 provided that the server has the appropriate support. 1641 'sec=sys' security flavour. In effect it is
1642 The default is to always enable NFSv4 idmapping. 1642 disabling idmapping, which can make migration from
1643 legacy NFSv2/v3 systems to NFSv4 easier.
1644 Servers that do not support this mode of operation
1645 will be autodetected by the client, and it will fall
1646 back to using the idmapper.
1647 To turn off this behaviour, set the value to '0'.
1643 1648
1644 nmi_debug= [KNL,AVR32,SH] Specify one or more actions to take 1649 nmi_debug= [KNL,AVR32,SH] Specify one or more actions to take
1645 when a NMI is triggered. 1650 when a NMI is triggered.
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
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 7748d6a18d97..6f3ebb48b12f 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -718,7 +718,7 @@ int set_callback_cred(void)
718{ 718{
719 if (callback_cred) 719 if (callback_cred)
720 return 0; 720 return 0;
721 callback_cred = rpc_lookup_machine_cred(); 721 callback_cred = rpc_lookup_machine_cred("nfs");
722 if (!callback_cred) 722 if (!callback_cred)
723 return -ENOMEM; 723 return -ENOMEM;
724 return 0; 724 return 0;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index b5479df8378d..ba4d7656ecfd 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -153,6 +153,7 @@ struct nfs_server {
153 struct rb_root openowner_id; 153 struct rb_root openowner_id;
154 struct rb_root lockowner_id; 154 struct rb_root lockowner_id;
155#endif 155#endif
156 struct list_head state_owners_lru;
156 struct list_head layouts; 157 struct list_head layouts;
157 struct list_head delegations; 158 struct list_head delegations;
158 void (*destroy)(struct nfs_server *); 159 void (*destroy)(struct nfs_server *);
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index ae7d6a380dae..308c18877018 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -66,6 +66,8 @@ struct idmap_msg {
66/* Forward declaration to make this header independent of others */ 66/* Forward declaration to make this header independent of others */
67struct nfs_client; 67struct nfs_client;
68struct nfs_server; 68struct nfs_server;
69struct nfs_fattr;
70struct nfs4_string;
69 71
70#ifdef CONFIG_NFS_USE_NEW_IDMAPPER 72#ifdef CONFIG_NFS_USE_NEW_IDMAPPER
71 73
@@ -97,6 +99,12 @@ void nfs_idmap_delete(struct nfs_client *);
97 99
98#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */ 100#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
99 101
102void nfs_fattr_init_names(struct nfs_fattr *fattr,
103 struct nfs4_string *owner_name,
104 struct nfs4_string *group_name);
105void nfs_fattr_free_names(struct nfs_fattr *);
106void nfs_fattr_map_and_free_names(struct nfs_server *, struct nfs_fattr *);
107
100int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *); 108int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *);
101int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *); 109int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *);
102int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t); 110int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 2a7c533be5dd..a764cef06b73 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -18,6 +18,11 @@
18/* Forward declaration for NFS v3 */ 18/* Forward declaration for NFS v3 */
19struct nfs4_secinfo_flavors; 19struct nfs4_secinfo_flavors;
20 20
21struct nfs4_string {
22 unsigned int len;
23 char *data;
24};
25
21struct nfs_fsid { 26struct nfs_fsid {
22 uint64_t major; 27 uint64_t major;
23 uint64_t minor; 28 uint64_t minor;
@@ -61,6 +66,8 @@ struct nfs_fattr {
61 struct timespec pre_ctime; /* pre_op_attr.ctime */ 66 struct timespec pre_ctime; /* pre_op_attr.ctime */
62 unsigned long time_start; 67 unsigned long time_start;
63 unsigned long gencount; 68 unsigned long gencount;
69 struct nfs4_string *owner_name;
70 struct nfs4_string *group_name;
64}; 71};
65 72
66#define NFS_ATTR_FATTR_TYPE (1U << 0) 73#define NFS_ATTR_FATTR_TYPE (1U << 0)
@@ -85,6 +92,8 @@ struct nfs_fattr {
85#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ 92#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */
86#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ 93#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */
87#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) 94#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21)
95#define NFS_ATTR_FATTR_OWNER_NAME (1U << 22)
96#define NFS_ATTR_FATTR_GROUP_NAME (1U << 23)
88 97
89#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ 98#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
90 | NFS_ATTR_FATTR_MODE \ 99 | NFS_ATTR_FATTR_MODE \
@@ -324,6 +333,7 @@ struct nfs_openargs {
324 const struct qstr * name; 333 const struct qstr * name;
325 const struct nfs_server *server; /* Needed for ID mapping */ 334 const struct nfs_server *server; /* Needed for ID mapping */
326 const u32 * bitmask; 335 const u32 * bitmask;
336 const u32 * dir_bitmask;
327 __u32 claim; 337 __u32 claim;
328 struct nfs4_sequence_args seq_args; 338 struct nfs4_sequence_args seq_args;
329}; 339};
@@ -342,6 +352,8 @@ struct nfs_openres {
342 __u32 do_recall; 352 __u32 do_recall;
343 __u64 maxsize; 353 __u64 maxsize;
344 __u32 attrset[NFS4_BITMAP_SIZE]; 354 __u32 attrset[NFS4_BITMAP_SIZE];
355 struct nfs4_string *owner;
356 struct nfs4_string *group_owner;
345 struct nfs4_sequence_res seq_res; 357 struct nfs4_sequence_res seq_res;
346}; 358};
347 359
@@ -602,11 +614,16 @@ struct nfs_getaclargs {
602 size_t acl_len; 614 size_t acl_len;
603 unsigned int acl_pgbase; 615 unsigned int acl_pgbase;
604 struct page ** acl_pages; 616 struct page ** acl_pages;
617 struct page * acl_scratch;
605 struct nfs4_sequence_args seq_args; 618 struct nfs4_sequence_args seq_args;
606}; 619};
607 620
621/* getxattr ACL interface flags */
622#define NFS4_ACL_LEN_REQUEST 0x0001 /* zero length getxattr buffer */
608struct nfs_getaclres { 623struct nfs_getaclres {
609 size_t acl_len; 624 size_t acl_len;
625 size_t acl_data_offset;
626 int acl_flags;
610 struct nfs4_sequence_res seq_res; 627 struct nfs4_sequence_res seq_res;
611}; 628};
612 629
@@ -773,11 +790,6 @@ struct nfs3_getaclres {
773 struct posix_acl * acl_default; 790 struct posix_acl * acl_default;
774}; 791};
775 792
776struct nfs4_string {
777 unsigned int len;
778 char *data;
779};
780
781#ifdef CONFIG_NFS_V4 793#ifdef CONFIG_NFS_V4
782 794
783typedef u64 clientid4; 795typedef u64 clientid4;
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index febc4dbec2ca..7874a8a56638 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -26,6 +26,7 @@ struct auth_cred {
26 uid_t uid; 26 uid_t uid;
27 gid_t gid; 27 gid_t gid;
28 struct group_info *group_info; 28 struct group_info *group_info;
29 const char *principal;
29 unsigned char machine_cred : 1; 30 unsigned char machine_cred : 1;
30}; 31};
31 32
@@ -127,7 +128,7 @@ void rpc_destroy_generic_auth(void);
127void rpc_destroy_authunix(void); 128void rpc_destroy_authunix(void);
128 129
129struct rpc_cred * rpc_lookup_cred(void); 130struct rpc_cred * rpc_lookup_cred(void);
130struct rpc_cred * rpc_lookup_machine_cred(void); 131struct rpc_cred * rpc_lookup_machine_cred(const char *service_name);
131int rpcauth_register(const struct rpc_authops *); 132int rpcauth_register(const struct rpc_authops *);
132int rpcauth_unregister(const struct rpc_authops *); 133int rpcauth_unregister(const struct rpc_authops *);
133struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); 134struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
index 8eee9dbbfe7a..f1cfd4c85cd0 100644
--- a/include/linux/sunrpc/auth_gss.h
+++ b/include/linux/sunrpc/auth_gss.h
@@ -82,8 +82,8 @@ struct gss_cred {
82 enum rpc_gss_svc gc_service; 82 enum rpc_gss_svc gc_service;
83 struct gss_cl_ctx __rcu *gc_ctx; 83 struct gss_cl_ctx __rcu *gc_ctx;
84 struct gss_upcall_msg *gc_upcall; 84 struct gss_upcall_msg *gc_upcall;
85 const char *gc_principal;
85 unsigned long gc_upcall_timestamp; 86 unsigned long gc_upcall_timestamp;
86 unsigned char gc_machine_cred : 1;
87}; 87};
88 88
89#endif /* __KERNEL__ */ 89#endif /* __KERNEL__ */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index a20970ef9e4e..af70af333546 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -191,6 +191,8 @@ extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
191 struct xdr_array2_desc *desc); 191 struct xdr_array2_desc *desc);
192extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base, 192extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
193 struct xdr_array2_desc *desc); 193 struct xdr_array2_desc *desc);
194extern void _copy_from_pages(char *p, struct page **pages, size_t pgbase,
195 size_t len);
194 196
195/* 197/*
196 * Provide some simple tools for XDR buffer overflow-checking etc. 198 * Provide some simple tools for XDR buffer overflow-checking etc.
diff --git a/init/do_mounts.c b/init/do_mounts.c
index b2eee02e0f83..2974c8b3b351 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -400,15 +400,42 @@ out:
400} 400}
401 401
402#ifdef CONFIG_ROOT_NFS 402#ifdef CONFIG_ROOT_NFS
403
404#define NFSROOT_TIMEOUT_MIN 5
405#define NFSROOT_TIMEOUT_MAX 30
406#define NFSROOT_RETRY_MAX 5
407
403static int __init mount_nfs_root(void) 408static int __init mount_nfs_root(void)
404{ 409{
405 char *root_dev, *root_data; 410 char *root_dev, *root_data;
411 unsigned int timeout;
412 int try, err;
406 413
407 if (nfs_root_data(&root_dev, &root_data) != 0) 414 err = nfs_root_data(&root_dev, &root_data);
408 return 0; 415 if (err != 0)
409 if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0)
410 return 0; 416 return 0;
411 return 1; 417
418 /*
419 * The server or network may not be ready, so try several
420 * times. Stop after a few tries in case the client wants
421 * to fall back to other boot methods.
422 */
423 timeout = NFSROOT_TIMEOUT_MIN;
424 for (try = 1; ; try++) {
425 err = do_mount_root(root_dev, "nfs",
426 root_mountflags, root_data);
427 if (err == 0)
428 return 1;
429 if (try > NFSROOT_RETRY_MAX)
430 break;
431
432 /* Wait, in case the server refused us immediately */
433 ssleep(timeout);
434 timeout <<= 1;
435 if (timeout > NFSROOT_TIMEOUT_MAX)
436 timeout = NFSROOT_TIMEOUT_MAX;
437 }
438 return 0;
412} 439}
413#endif 440#endif
414 441
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index e010a015d996..1426ec3d0a53 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -41,15 +41,17 @@ EXPORT_SYMBOL_GPL(rpc_lookup_cred);
41/* 41/*
42 * Public call interface for looking up machine creds. 42 * Public call interface for looking up machine creds.
43 */ 43 */
44struct rpc_cred *rpc_lookup_machine_cred(void) 44struct rpc_cred *rpc_lookup_machine_cred(const char *service_name)
45{ 45{
46 struct auth_cred acred = { 46 struct auth_cred acred = {
47 .uid = RPC_MACHINE_CRED_USERID, 47 .uid = RPC_MACHINE_CRED_USERID,
48 .gid = RPC_MACHINE_CRED_GROUPID, 48 .gid = RPC_MACHINE_CRED_GROUPID,
49 .principal = service_name,
49 .machine_cred = 1, 50 .machine_cred = 1,
50 }; 51 };
51 52
52 dprintk("RPC: looking up machine cred\n"); 53 dprintk("RPC: looking up machine cred for service %s\n",
54 service_name);
53 return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0); 55 return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
54} 56}
55EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred); 57EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index afb56553dfe7..28d72d298735 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -392,7 +392,8 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
392} 392}
393 393
394static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, 394static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
395 struct rpc_clnt *clnt, int machine_cred) 395 struct rpc_clnt *clnt,
396 const char *service_name)
396{ 397{
397 struct gss_api_mech *mech = gss_msg->auth->mech; 398 struct gss_api_mech *mech = gss_msg->auth->mech;
398 char *p = gss_msg->databuf; 399 char *p = gss_msg->databuf;
@@ -407,12 +408,8 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
407 p += len; 408 p += len;
408 gss_msg->msg.len += len; 409 gss_msg->msg.len += len;
409 } 410 }
410 if (machine_cred) { 411 if (service_name != NULL) {
411 len = sprintf(p, "service=* "); 412 len = sprintf(p, "service=%s ", service_name);
412 p += len;
413 gss_msg->msg.len += len;
414 } else if (!strcmp(clnt->cl_program->name, "nfs4_cb")) {
415 len = sprintf(p, "service=nfs ");
416 p += len; 413 p += len;
417 gss_msg->msg.len += len; 414 gss_msg->msg.len += len;
418 } 415 }
@@ -429,17 +426,18 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
429} 426}
430 427
431static void gss_encode_msg(struct gss_upcall_msg *gss_msg, 428static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
432 struct rpc_clnt *clnt, int machine_cred) 429 struct rpc_clnt *clnt,
430 const char *service_name)
433{ 431{
434 if (pipe_version == 0) 432 if (pipe_version == 0)
435 gss_encode_v0_msg(gss_msg); 433 gss_encode_v0_msg(gss_msg);
436 else /* pipe_version == 1 */ 434 else /* pipe_version == 1 */
437 gss_encode_v1_msg(gss_msg, clnt, machine_cred); 435 gss_encode_v1_msg(gss_msg, clnt, service_name);
438} 436}
439 437
440static inline struct gss_upcall_msg * 438static struct gss_upcall_msg *
441gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid, struct rpc_clnt *clnt, 439gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
442 int machine_cred) 440 uid_t uid, const char *service_name)
443{ 441{
444 struct gss_upcall_msg *gss_msg; 442 struct gss_upcall_msg *gss_msg;
445 int vers; 443 int vers;
@@ -459,7 +457,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid, struct rpc_clnt *clnt,
459 atomic_set(&gss_msg->count, 1); 457 atomic_set(&gss_msg->count, 1);
460 gss_msg->uid = uid; 458 gss_msg->uid = uid;
461 gss_msg->auth = gss_auth; 459 gss_msg->auth = gss_auth;
462 gss_encode_msg(gss_msg, clnt, machine_cred); 460 gss_encode_msg(gss_msg, clnt, service_name);
463 return gss_msg; 461 return gss_msg;
464} 462}
465 463
@@ -471,7 +469,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr
471 struct gss_upcall_msg *gss_new, *gss_msg; 469 struct gss_upcall_msg *gss_new, *gss_msg;
472 uid_t uid = cred->cr_uid; 470 uid_t uid = cred->cr_uid;
473 471
474 gss_new = gss_alloc_msg(gss_auth, uid, clnt, gss_cred->gc_machine_cred); 472 gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal);
475 if (IS_ERR(gss_new)) 473 if (IS_ERR(gss_new))
476 return gss_new; 474 return gss_new;
477 gss_msg = gss_add_msg(gss_new); 475 gss_msg = gss_add_msg(gss_new);
@@ -995,7 +993,9 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
995 */ 993 */
996 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; 994 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
997 cred->gc_service = gss_auth->service; 995 cred->gc_service = gss_auth->service;
998 cred->gc_machine_cred = acred->machine_cred; 996 cred->gc_principal = NULL;
997 if (acred->machine_cred)
998 cred->gc_principal = acred->principal;
999 kref_get(&gss_auth->kref); 999 kref_get(&gss_auth->kref);
1000 return &cred->gc_base; 1000 return &cred->gc_base;
1001 1001
@@ -1030,7 +1030,12 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
1030 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags)) 1030 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags))
1031 return 0; 1031 return 0;
1032out: 1032out:
1033 if (acred->machine_cred != gss_cred->gc_machine_cred) 1033 if (acred->principal != NULL) {
1034 if (gss_cred->gc_principal == NULL)
1035 return 0;
1036 return strcmp(acred->principal, gss_cred->gc_principal) == 0;
1037 }
1038 if (gss_cred->gc_principal != NULL)
1034 return 0; 1039 return 0;
1035 return rc->cr_uid == acred->uid; 1040 return rc->cr_uid == acred->uid;
1036} 1041}
@@ -1104,7 +1109,8 @@ static int gss_renew_cred(struct rpc_task *task)
1104 struct rpc_auth *auth = oldcred->cr_auth; 1109 struct rpc_auth *auth = oldcred->cr_auth;
1105 struct auth_cred acred = { 1110 struct auth_cred acred = {
1106 .uid = oldcred->cr_uid, 1111 .uid = oldcred->cr_uid,
1107 .machine_cred = gss_cred->gc_machine_cred, 1112 .principal = gss_cred->gc_principal,
1113 .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
1108 }; 1114 };
1109 struct rpc_cred *new; 1115 struct rpc_cred *new;
1110 1116
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 277ebd4bf095..593f4c605305 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -296,7 +296,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
296 * Copies data into an arbitrary memory location from an array of pages 296 * Copies data into an arbitrary memory location from an array of pages
297 * The copy is assumed to be non-overlapping. 297 * The copy is assumed to be non-overlapping.
298 */ 298 */
299static void 299void
300_copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len) 300_copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
301{ 301{
302 struct page **pgfrom; 302 struct page **pgfrom;
@@ -324,6 +324,7 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
324 324
325 } while ((len -= copy) != 0); 325 } while ((len -= copy) != 0);
326} 326}
327EXPORT_SYMBOL_GPL(_copy_from_pages);
327 328
328/* 329/*
329 * xdr_shrink_bufhead 330 * xdr_shrink_bufhead