if (retval)
goto err_out;
- size = posix_acl_xattr_size(acl->a_count);
-
- value = kzalloc(size, GFP_NOFS);
+ value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
if (!value) {
retval = -ENOMEM;
goto err_out;
}
-
- retval = posix_acl_to_xattr(&init_user_ns, acl, value, size);
- if (retval < 0)
- goto err_out;
}
/*
return 0;
/* Set a setxattr request to server */
- size = posix_acl_xattr_size(acl->a_count);
- buffer = kmalloc(size, GFP_KERNEL);
+ buffer = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
- retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
- if (retval < 0)
- goto err_free_out;
+
switch (type) {
case ACL_TYPE_ACCESS:
name = XATTR_NAME_POSIX_ACL_ACCESS;
BUG();
}
retval = v9fs_fid_xattr_set(fid, name, buffer, size, 0);
-err_free_out:
kfree(buffer);
return retval;
}
int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode,
struct posix_acl *acl, int type)
{
- int ret, size = 0;
+ int ret;
+ size_t size = 0;
const char *name;
char AUTO_KFREE(value);
if (acl) {
unsigned int nofs_flag;
- size = posix_acl_xattr_size(acl->a_count);
/*
* We're holding a transaction handle, so use a NOFS memory
* allocation context to avoid deadlock if reclaim happens.
*/
nofs_flag = memalloc_nofs_save();
- value = kmalloc(size, GFP_KERNEL);
+ value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
memalloc_nofs_restore(nofs_flag);
if (!value)
return -ENOMEM;
-
- ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
- if (ret < 0)
- return ret;
}
if (trans)
int ceph_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
struct posix_acl *acl, int type)
{
- int ret = 0, size = 0;
+ int ret = 0;
+ size_t size = 0;
const char *name = NULL;
char *value = NULL;
struct iattr newattrs;
}
if (acl) {
- size = posix_acl_xattr_size(acl->a_count);
- value = kmalloc(size, GFP_NOFS);
+ value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
if (!value) {
ret = -ENOMEM;
goto out;
}
-
- ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
- if (ret < 0)
- goto out_free;
}
if (new_mode != old_mode) {
struct posix_acl *acl, *default_acl;
size_t val_size1 = 0, val_size2 = 0;
struct ceph_pagelist *pagelist = NULL;
- void *tmp_buf = NULL;
+ void *tmp_buf1 = NULL, *tmp_buf2 = NULL;
int err;
err = posix_acl_create(dir, mode, &default_acl, &acl);
if (!default_acl && !acl)
return 0;
- if (acl)
- val_size1 = posix_acl_xattr_size(acl->a_count);
- if (default_acl)
- val_size2 = posix_acl_xattr_size(default_acl->a_count);
-
err = -ENOMEM;
- tmp_buf = kmalloc(max(val_size1, val_size2), GFP_KERNEL);
- if (!tmp_buf)
- goto out_err;
pagelist = ceph_pagelist_alloc(GFP_KERNEL);
if (!pagelist)
goto out_err;
if (acl) {
size_t len = strlen(XATTR_NAME_POSIX_ACL_ACCESS);
+
+ err = -ENOMEM;
+ tmp_buf1 = posix_acl_to_xattr(&init_user_ns, acl,
+ &val_size1, GFP_KERNEL);
+ if (!tmp_buf1)
+ goto out_err;
err = ceph_pagelist_reserve(pagelist, len + val_size1 + 8);
if (err)
goto out_err;
ceph_pagelist_encode_string(pagelist, XATTR_NAME_POSIX_ACL_ACCESS,
len);
- err = posix_acl_to_xattr(&init_user_ns, acl,
- tmp_buf, val_size1);
- if (err < 0)
- goto out_err;
ceph_pagelist_encode_32(pagelist, val_size1);
- ceph_pagelist_append(pagelist, tmp_buf, val_size1);
+ ceph_pagelist_append(pagelist, tmp_buf1, val_size1);
}
if (default_acl) {
size_t len = strlen(XATTR_NAME_POSIX_ACL_DEFAULT);
+
+ err = -ENOMEM;
+ tmp_buf2 = posix_acl_to_xattr(&init_user_ns, default_acl,
+ &val_size2, GFP_KERNEL);
+ if (!tmp_buf2)
+ goto out_err;
err = ceph_pagelist_reserve(pagelist, len + val_size2 + 8);
if (err)
goto out_err;
ceph_pagelist_encode_string(pagelist,
XATTR_NAME_POSIX_ACL_DEFAULT, len);
- err = posix_acl_to_xattr(&init_user_ns, default_acl,
- tmp_buf, val_size2);
- if (err < 0)
- goto out_err;
ceph_pagelist_encode_32(pagelist, val_size2);
- ceph_pagelist_append(pagelist, tmp_buf, val_size2);
+ ceph_pagelist_append(pagelist, tmp_buf2, val_size2);
}
- kfree(tmp_buf);
+ kfree(tmp_buf1);
+ kfree(tmp_buf2);
as_ctx->acl = acl;
as_ctx->default_acl = default_acl;
out_err:
posix_acl_release(acl);
posix_acl_release(default_acl);
- kfree(tmp_buf);
+ kfree(tmp_buf1);
+ kfree(tmp_buf2);
if (pagelist)
ceph_pagelist_release(pagelist);
return err;
* them to be refreshed the next time they are used,
* and it also updates i_ctime.
*/
- size_t size = posix_acl_xattr_size(acl->a_count);
+ size_t size;
void *value;
- if (size > PAGE_SIZE)
- return -E2BIG;
-
- value = kmalloc(size, GFP_KERNEL);
+ value = posix_acl_to_xattr(fc->user_ns, acl, &size, GFP_KERNEL);
if (!value)
return -ENOMEM;
- ret = posix_acl_to_xattr(fc->user_ns, acl, value, size);
- if (ret < 0) {
+ if (size > PAGE_SIZE) {
kfree(value);
- return ret;
+ return -E2BIG;
}
/*
int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
int error;
- size_t len;
- char *data;
+ size_t len = 0;
+ char *data = NULL;
const char *name = gfs2_acl_name(type);
if (acl) {
- len = posix_acl_xattr_size(acl->a_count);
- data = kmalloc(len, GFP_NOFS);
+ data = posix_acl_to_xattr(&init_user_ns, acl, &len, GFP_NOFS);
if (data == NULL)
return -ENOMEM;
- error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
- if (error < 0)
- goto out;
- } else {
- data = NULL;
- len = 0;
}
error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
{
char *ea_name;
int rc;
- int size = 0;
+ size_t size = 0;
char *value = NULL;
switch (type) {
}
if (acl) {
- size = posix_acl_xattr_size(acl->a_count);
- value = kmalloc(size, GFP_KERNEL);
+ value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
if (!value)
return -ENOMEM;
- rc = posix_acl_to_xattr(&init_user_ns, acl, value, size);
- if (rc < 0)
- goto out;
}
rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0);
-out:
kfree(value);
if (!rc)
value = NULL;
flags = XATTR_REPLACE;
} else {
- size = posix_acl_xattr_size(acl->a_count);
- value = kmalloc(size, GFP_NOFS);
+ value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
if (!value)
return -ENOMEM;
- err = posix_acl_to_xattr(&init_user_ns, acl, value, size);
- if (err < 0)
- goto out;
flags = 0;
}
type);
if (acl) {
- size = posix_acl_xattr_size(acl->a_count);
- value = kmalloc(size, GFP_KERNEL);
+ value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
if (!value)
return -ENOMEM;
-
- error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
- if (error < 0)
- goto out;
}
gossip_debug(GOSSIP_ACL_DEBUG,
*/
error = orangefs_inode_setxattr(inode, name, value, size, 0);
-out:
kfree(value);
if (!error)
set_cached_acl(inode, type, acl);
/*
* Convert from in-memory to extended attribute representation.
*/
-int
+void *
posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
- void *buffer, size_t size)
+ size_t *sizep, gfp_t gfp)
{
- struct posix_acl_xattr_header *ext_acl = buffer;
+ struct posix_acl_xattr_header *ext_acl;
struct posix_acl_xattr_entry *ext_entry;
- int real_size, n;
+ size_t size;
+ int n;
- real_size = posix_acl_xattr_size(acl->a_count);
- if (!buffer)
- return real_size;
- if (real_size > size)
- return -ERANGE;
+ size = posix_acl_xattr_size(acl->a_count);
+ ext_acl = kmalloc(size, gfp);
+ if (!ext_acl)
+ return NULL;
ext_entry = (void *)(ext_acl + 1);
ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
break;
}
}
- return real_size;
+ *sizep = size;
+ return ext_acl;
}
EXPORT_SYMBOL (posix_acl_to_xattr);
}
#endif
-int posix_acl_to_xattr(struct user_namespace *user_ns,
- const struct posix_acl *acl, void *buffer, size_t size);
+extern void *posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
+ size_t *sizep, gfp_t gfp);
+
static inline const char *posix_acl_xattr_name(int type)
{
switch (type) {