diff options
| author | David Brown <davidb@codeaurora.org> | 2011-03-17 01:13:16 -0400 |
|---|---|---|
| committer | David Brown <davidb@codeaurora.org> | 2011-03-17 01:13:16 -0400 |
| commit | 92c260f755c42337c550d8ac1f8ccd1b32bffb20 (patch) | |
| tree | 6d04fefc1adeecabfb2b00c201e0db78fa2b5529 /fs/nfs/nfs4proc.c | |
| parent | 8e76a80960bf06c245160a484d5a363ca6b520bb (diff) | |
| parent | 05e34754518b6a90d5c392790c032575fab12d66 (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.c | 74 |
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 | ||
| 3256 | static 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 | |||
| 3279 | unwind: | ||
| 3280 | for(; rc > 0; rc--) | ||
| 3281 | __free_page(spages[rc-1]); | ||
| 3282 | return -ENOMEM; | ||
| 3283 | } | ||
| 3284 | |||
| 3254 | struct nfs4_cached_acl { | 3285 | struct 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 | } |
