diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/nfs/nfs3acl.c | 27 | ||||
| -rw-r--r-- | fs/nfs/nfs3xdr.c | 34 |
2 files changed, 34 insertions, 27 deletions
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index cef62557c87d..6bbf0e6daad2 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
| @@ -292,7 +292,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 292 | { | 292 | { |
| 293 | struct nfs_server *server = NFS_SERVER(inode); | 293 | struct nfs_server *server = NFS_SERVER(inode); |
| 294 | struct nfs_fattr fattr; | 294 | struct nfs_fattr fattr; |
| 295 | struct page *pages[NFSACL_MAXPAGES] = { }; | 295 | struct page *pages[NFSACL_MAXPAGES]; |
| 296 | struct nfs3_setaclargs args = { | 296 | struct nfs3_setaclargs args = { |
| 297 | .inode = inode, | 297 | .inode = inode, |
| 298 | .mask = NFS_ACL, | 298 | .mask = NFS_ACL, |
| @@ -303,7 +303,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 303 | .rpc_argp = &args, | 303 | .rpc_argp = &args, |
| 304 | .rpc_resp = &fattr, | 304 | .rpc_resp = &fattr, |
| 305 | }; | 305 | }; |
| 306 | int status, count; | 306 | int status; |
| 307 | 307 | ||
| 308 | status = -EOPNOTSUPP; | 308 | status = -EOPNOTSUPP; |
| 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) | 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) |
| @@ -319,6 +319,20 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 319 | if (S_ISDIR(inode->i_mode)) { | 319 | if (S_ISDIR(inode->i_mode)) { |
| 320 | args.mask |= NFS_DFACL; | 320 | args.mask |= NFS_DFACL; |
| 321 | args.acl_default = dfacl; | 321 | args.acl_default = dfacl; |
| 322 | args.len = nfsacl_size(acl, dfacl); | ||
| 323 | } else | ||
| 324 | args.len = nfsacl_size(acl, NULL); | ||
| 325 | |||
| 326 | if (args.len > NFS_ACL_INLINE_BUFSIZE) { | ||
| 327 | unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); | ||
| 328 | |||
| 329 | status = -ENOMEM; | ||
| 330 | do { | ||
| 331 | args.pages[args.npages] = alloc_page(GFP_KERNEL); | ||
| 332 | if (args.pages[args.npages] == NULL) | ||
| 333 | goto out_freepages; | ||
| 334 | args.npages++; | ||
| 335 | } while (args.npages < npages); | ||
| 322 | } | 336 | } |
| 323 | 337 | ||
| 324 | dprintk("NFS call setacl\n"); | 338 | dprintk("NFS call setacl\n"); |
| @@ -329,10 +343,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 329 | nfs_zap_acl_cache(inode); | 343 | nfs_zap_acl_cache(inode); |
| 330 | dprintk("NFS reply setacl: %d\n", status); | 344 | dprintk("NFS reply setacl: %d\n", status); |
| 331 | 345 | ||
| 332 | /* pages may have been allocated at the xdr layer. */ | ||
| 333 | for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) | ||
| 334 | __free_page(args.pages[count]); | ||
| 335 | |||
| 336 | switch (status) { | 346 | switch (status) { |
| 337 | case 0: | 347 | case 0: |
| 338 | status = nfs_refresh_inode(inode, &fattr); | 348 | status = nfs_refresh_inode(inode, &fattr); |
| @@ -346,6 +356,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 346 | case -ENOTSUPP: | 356 | case -ENOTSUPP: |
| 347 | status = -EOPNOTSUPP; | 357 | status = -EOPNOTSUPP; |
| 348 | } | 358 | } |
| 359 | out_freepages: | ||
| 360 | while (args.npages != 0) { | ||
| 361 | args.npages--; | ||
| 362 | __free_page(args.pages[args.npages]); | ||
| 363 | } | ||
| 349 | out: | 364 | out: |
| 350 | return status; | 365 | return status; |
| 351 | } | 366 | } |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 11cdddec1432..6cdeacffde46 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
| @@ -82,8 +82,10 @@ | |||
| 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) | 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) |
| 83 | 83 | ||
| 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) | 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) |
| 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3)) | 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ |
| 86 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3)) | 86 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) |
| 87 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ | ||
| 88 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) | ||
| 87 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) | 89 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) |
| 88 | 90 | ||
| 89 | /* | 91 | /* |
| @@ -703,28 +705,18 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, | |||
| 703 | struct nfs3_setaclargs *args) | 705 | struct nfs3_setaclargs *args) |
| 704 | { | 706 | { |
| 705 | struct xdr_buf *buf = &req->rq_snd_buf; | 707 | struct xdr_buf *buf = &req->rq_snd_buf; |
| 706 | unsigned int base, len_in_head, len = nfsacl_size( | 708 | unsigned int base; |
| 707 | (args->mask & NFS_ACL) ? args->acl_access : NULL, | 709 | int err; |
| 708 | (args->mask & NFS_DFACL) ? args->acl_default : NULL); | ||
| 709 | int count, err; | ||
| 710 | 710 | ||
| 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); | 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); |
| 712 | *p++ = htonl(args->mask); | 712 | *p++ = htonl(args->mask); |
| 713 | base = (char *)p - (char *)buf->head->iov_base; | 713 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
| 714 | /* put as much of the acls into head as possible. */ | 714 | base = req->rq_slen; |
| 715 | len_in_head = min_t(unsigned int, buf->head->iov_len - base, len); | 715 | |
| 716 | len -= len_in_head; | 716 | if (args->npages != 0) |
| 717 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2)); | 717 | xdr_encode_pages(buf, args->pages, 0, args->len); |
| 718 | 718 | else | |
| 719 | for (count = 0; (count << PAGE_SHIFT) < len; count++) { | 719 | req->rq_slen += args->len; |
| 720 | args->pages[count] = alloc_page(GFP_KERNEL); | ||
| 721 | if (!args->pages[count]) { | ||
| 722 | while (count) | ||
| 723 | __free_page(args->pages[--count]); | ||
| 724 | return -ENOMEM; | ||
| 725 | } | ||
| 726 | } | ||
| 727 | xdr_encode_pages(buf, args->pages, 0, len); | ||
| 728 | 720 | ||
| 729 | err = nfsacl_encode(buf, base, args->inode, | 721 | err = nfsacl_encode(buf, base, args->inode, |
| 730 | (args->mask & NFS_ACL) ? | 722 | (args->mask & NFS_ACL) ? |
