|
@@ -292,7 +292,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
|
|
{
|
|
{
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
struct nfs_fattr fattr;
|
|
struct nfs_fattr fattr;
|
|
- struct page *pages[NFSACL_MAXPAGES] = { };
|
|
|
|
|
|
+ struct page *pages[NFSACL_MAXPAGES];
|
|
struct nfs3_setaclargs args = {
|
|
struct nfs3_setaclargs args = {
|
|
.inode = inode,
|
|
.inode = inode,
|
|
.mask = NFS_ACL,
|
|
.mask = NFS_ACL,
|
|
@@ -303,7 +303,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
|
|
.rpc_argp = &args,
|
|
.rpc_argp = &args,
|
|
.rpc_resp = &fattr,
|
|
.rpc_resp = &fattr,
|
|
};
|
|
};
|
|
- int status, count;
|
|
|
|
|
|
+ int status;
|
|
|
|
|
|
status = -EOPNOTSUPP;
|
|
status = -EOPNOTSUPP;
|
|
if (!nfs_server_capable(inode, NFS_CAP_ACLS))
|
|
if (!nfs_server_capable(inode, NFS_CAP_ACLS))
|
|
@@ -319,6 +319,20 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
args.mask |= NFS_DFACL;
|
|
args.mask |= NFS_DFACL;
|
|
args.acl_default = dfacl;
|
|
args.acl_default = dfacl;
|
|
|
|
+ args.len = nfsacl_size(acl, dfacl);
|
|
|
|
+ } else
|
|
|
|
+ args.len = nfsacl_size(acl, NULL);
|
|
|
|
+
|
|
|
|
+ if (args.len > NFS_ACL_INLINE_BUFSIZE) {
|
|
|
|
+ unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT);
|
|
|
|
+
|
|
|
|
+ status = -ENOMEM;
|
|
|
|
+ do {
|
|
|
|
+ args.pages[args.npages] = alloc_page(GFP_KERNEL);
|
|
|
|
+ if (args.pages[args.npages] == NULL)
|
|
|
|
+ goto out_freepages;
|
|
|
|
+ args.npages++;
|
|
|
|
+ } while (args.npages < npages);
|
|
}
|
|
}
|
|
|
|
|
|
dprintk("NFS call setacl\n");
|
|
dprintk("NFS call setacl\n");
|
|
@@ -329,10 +343,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
|
|
nfs_zap_acl_cache(inode);
|
|
nfs_zap_acl_cache(inode);
|
|
dprintk("NFS reply setacl: %d\n", status);
|
|
dprintk("NFS reply setacl: %d\n", status);
|
|
|
|
|
|
- /* pages may have been allocated at the xdr layer. */
|
|
|
|
- for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
|
|
|
|
- __free_page(args.pages[count]);
|
|
|
|
-
|
|
|
|
switch (status) {
|
|
switch (status) {
|
|
case 0:
|
|
case 0:
|
|
status = nfs_refresh_inode(inode, &fattr);
|
|
status = nfs_refresh_inode(inode, &fattr);
|
|
@@ -346,6 +356,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
|
|
case -ENOTSUPP:
|
|
case -ENOTSUPP:
|
|
status = -EOPNOTSUPP;
|
|
status = -EOPNOTSUPP;
|
|
}
|
|
}
|
|
|
|
+out_freepages:
|
|
|
|
+ while (args.npages != 0) {
|
|
|
|
+ args.npages--;
|
|
|
|
+ __free_page(args.pages[args.npages]);
|
|
|
|
+ }
|
|
out:
|
|
out:
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|