aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorDavid Brown <davidb@codeaurora.org>2011-03-17 01:13:16 -0400
committerDavid Brown <davidb@codeaurora.org>2011-03-17 01:13:16 -0400
commit92c260f755c42337c550d8ac1f8ccd1b32bffb20 (patch)
tree6d04fefc1adeecabfb2b00c201e0db78fa2b5529 /fs/nfs/nfs4proc.c
parent8e76a80960bf06c245160a484d5a363ca6b520bb (diff)
parent05e34754518b6a90d5c392790c032575fab12d66 (diff)
Merge remote branch 'rmk/for-linus' into for-linus
* rmk/for-linus: (1557 commits) ARM: 6806/1: irq: introduce entry and exit functions for chained handlers ARM: 6781/1: Thumb-2: Work around buggy Thumb-2 short branch relocations in gas ARM: 6747/1: P2V: Thumb2 support ARM: 6798/1: aout-core: zero thread debug registers in a.out core dump ARM: 6796/1: Footbridge: Fix I/O mappings for NOMMU mode ARM: 6784/1: errata: no automatic Store Buffer drain on Cortex-A9 ARM: 6772/1: errata: possible fault MMU translations following an ASID switch ARM: 6776/1: mach-ux500: activate fix for errata 753970 ARM: 6794/1: SPEAr: Append UL to device address macros. ARM: 6793/1: SPEAr: Remove unused *_SIZE macros from spear*.h files ARM: 6792/1: SPEAr: Replace SIZE macro's with SZ_4K macros ARM: 6791/1: SPEAr3xx: Declare device structures after shirq code ARM: 6790/1: SPEAr: Clock Framework: Rename usbd clock and align apb_clk entry ARM: 6789/1: SPEAr3xx: Rename sdio to sdhci ARM: 6788/1: SPEAr: Include mach/hardware.h instead of mach/spear.h ARM: 6787/1: SPEAr: Reorder #includes in .h & .c files. ARM: 6681/1: SPEAr: add debugfs support to clk API ARM: 6703/1: SPEAr: update clk API support ARM: 6679/1: SPEAr: make clk API functions more generic ARM: 6737/1: SPEAr: formalized timer support ... Conflicts: arch/arm/mach-msm/board-msm7x27.c arch/arm/mach-msm/board-msm7x30.c arch/arm/mach-msm/board-qsd8x50.c arch/arm/mach-msm/board-sapphire.c arch/arm/mach-msm/include/mach/memory.h
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c74
1 files changed, 52 insertions, 22 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9d992b0346e3..1ff76acc7e98 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -50,6 +50,8 @@
50#include <linux/module.h> 50#include <linux/module.h>
51#include <linux/sunrpc/bc_xprt.h> 51#include <linux/sunrpc/bc_xprt.h>
52#include <linux/xattr.h> 52#include <linux/xattr.h>
53#include <linux/utsname.h>
54#include <linux/mm.h>
53 55
54#include "nfs4_fs.h" 56#include "nfs4_fs.h"
55#include "delegation.h" 57#include "delegation.h"
@@ -3251,6 +3253,35 @@ static void buf_to_pages(const void *buf, size_t buflen,
3251 } 3253 }
3252} 3254}
3253 3255
3256static int buf_to_pages_noslab(const void *buf, size_t buflen,
3257 struct page **pages, unsigned int *pgbase)
3258{
3259 struct page *newpage, **spages;
3260 int rc = 0;
3261 size_t len;
3262 spages = pages;
3263
3264 do {
3265 len = min(PAGE_CACHE_SIZE, buflen);
3266 newpage = alloc_page(GFP_KERNEL);
3267
3268 if (newpage == NULL)
3269 goto unwind;
3270 memcpy(page_address(newpage), buf, len);
3271 buf += len;
3272 buflen -= len;
3273 *pages++ = newpage;
3274 rc++;
3275 } while (buflen != 0);
3276
3277 return rc;
3278
3279unwind:
3280 for(; rc > 0; rc--)
3281 __free_page(spages[rc-1]);
3282 return -ENOMEM;
3283}
3284
3254struct nfs4_cached_acl { 3285struct nfs4_cached_acl {
3255 int cached; 3286 int cached;
3256 size_t len; 3287 size_t len;
@@ -3419,13 +3450,23 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
3419 .rpc_argp = &arg, 3450 .rpc_argp = &arg,
3420 .rpc_resp = &res, 3451 .rpc_resp = &res,
3421 }; 3452 };
3422 int ret; 3453 int ret, i;
3423 3454
3424 if (!nfs4_server_supports_acls(server)) 3455 if (!nfs4_server_supports_acls(server))
3425 return -EOPNOTSUPP; 3456 return -EOPNOTSUPP;
3457 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
3458 if (i < 0)
3459 return i;
3426 nfs_inode_return_delegation(inode); 3460 nfs_inode_return_delegation(inode);
3427 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
3428 ret = nfs4_call_sync(server, &msg, &arg, &res, 1); 3461 ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
3462
3463 /*
3464 * Free each page after tx, so the only ref left is
3465 * held by the network stack
3466 */
3467 for (; i > 0; i--)
3468 put_page(pages[i-1]);
3469
3429 /* 3470 /*
3430 * Acl update can result in inode attribute update. 3471 * Acl update can result in inode attribute update.
3431 * so mark the attribute cache invalid. 3472 * so mark the attribute cache invalid.
@@ -4572,27 +4613,16 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4572 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4613 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
4573 args.verifier = &verifier; 4614 args.verifier = &verifier;
4574 4615
4575 while (1) { 4616 args.id_len = scnprintf(args.id, sizeof(args.id),
4576 args.id_len = scnprintf(args.id, sizeof(args.id), 4617 "%s/%s.%s/%u",
4577 "%s/%s %u", 4618 clp->cl_ipaddr,
4578 clp->cl_ipaddr, 4619 init_utsname()->nodename,
4579 rpc_peeraddr2str(clp->cl_rpcclient, 4620 init_utsname()->domainname,
4580 RPC_DISPLAY_ADDR), 4621 clp->cl_rpcclient->cl_auth->au_flavor);
4581 clp->cl_id_uniquifier);
4582
4583 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4584
4585 if (status != -NFS4ERR_CLID_INUSE)
4586 break;
4587
4588 if (signalled())
4589 break;
4590
4591 if (++clp->cl_id_uniquifier == 0)
4592 break;
4593 }
4594 4622
4595 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 4623 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4624 if (!status)
4625 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
4596 dprintk("<-- %s status= %d\n", __func__, status); 4626 dprintk("<-- %s status= %d\n", __func__, status);
4597 return status; 4627 return status;
4598} 4628}