diff options
Diffstat (limited to 'fs/nfs/nfs3acl.c')
| -rw-r--r-- | fs/nfs/nfs3acl.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index cef62557c87..6bbf0e6daad 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 | } |
