static int jffs2_acl_setxattr(struct inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; int rc; if (!is_owner_or_cap(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { rc = posix_acl_valid(acl); if (rc) goto out; } } else { acl = NULL; } rc = jffs2_set_acl(inode, type, acl); out: posix_acl_release(acl); return rc; }
static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) { ssize_t size; void *value = NULL; struct posix_acl *acl = NULL; size = v9fs_fid_xattr_get(fid, name, NULL, 0); if (size > 0) { value = kzalloc(size, GFP_NOFS); if (!value) return ERR_PTR(-ENOMEM); size = v9fs_fid_xattr_get(fid, name, value, size); if (size > 0) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) goto err_out; } } else if (size == -ENODATA || size == 0 || size == -ENOSYS || size == -EOPNOTSUPP) { acl = NULL; } else acl = ERR_PTR(-EIO); err_out: kfree(value); return acl; }
struct posix_acl *fuse_get_acl(struct inode *inode, int type) { struct fuse_conn *fc = get_fuse_conn(inode); int size; const char *name; void *value = NULL; struct posix_acl *acl; if (!fc->posix_acl || fc->no_getxattr) return NULL; if (type == ACL_TYPE_ACCESS) name = XATTR_NAME_POSIX_ACL_ACCESS; else if (type == ACL_TYPE_DEFAULT) name = XATTR_NAME_POSIX_ACL_DEFAULT; else return ERR_PTR(-EOPNOTSUPP); value = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); size = fuse_getxattr(inode, name, value, PAGE_SIZE); if (size > 0) acl = posix_acl_from_xattr(&init_user_ns, value, size); else if ((size == 0) || (size == -ENODATA) || (size == -EOPNOTSUPP && fc->no_getxattr)) acl = NULL; else if (size == -ERANGE) acl = ERR_PTR(-E2BIG); else acl = ERR_PTR(size); kfree(value); return acl; }
static int ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct posix_acl *acl; int error; if (strcmp(name, "") != 0) return -EINVAL; if (!test_opt(dentry->d_sb, POSIX_ACL)) return -EOPNOTSUPP; if (!inode_owner_or_capable(dentry->d_inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); else if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else acl = NULL; error = ext2_set_acl(dentry->d_inode, type, acl); release_and_out: posix_acl_release(acl); return error; }
struct posix_acl *gfs2_get_acl(struct inode *inode, int type) { struct gfs2_inode *ip = GFS2_I(inode); struct posix_acl *acl; const char *name; char *data; int len; if (!ip->i_eattr) return NULL; acl = get_cached_acl(&ip->i_inode, type); if (acl != ACL_NOT_CACHED) return acl; name = gfs2_acl_name(type); if (name == NULL) return ERR_PTR(-EINVAL); len = gfs2_xattr_acl_get(ip, name, &data); if (len < 0) return ERR_PTR(len); if (len == 0) return NULL; acl = posix_acl_from_xattr(data, len); kfree(data); return acl; }
static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { int ret; struct posix_acl *acl = NULL; if (!inode_owner_or_capable(dentry->d_inode)) return -EPERM; if (!IS_POSIXACL(dentry->d_inode)) return -EOPNOTSUPP; if (value) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { ret = posix_acl_valid(acl); if (ret) goto out; } } ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); out: posix_acl_release(acl); return ret; }
static int f2fs_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; struct posix_acl *acl = NULL; int error; if (strcmp(name, "") != 0) return -EINVAL; if (!test_opt(sbi, POSIX_ACL)) return -EOPNOTSUPP; if (!inode_owner_or_capable(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else { acl = NULL; } error = f2fs_set_acl(inode, type, acl, NULL); release_and_out: posix_acl_release(acl); return error; }
static int pvfs2_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; int error; #ifdef HAVE_CURRENT_FSUID int fsuid = current_fsuid(); #else int fsuid = current->fsuid; #endif gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_set_acl called with size %ld\n", (long)size); /* if we have not been mounted with acl option, ignore this */ if (get_acl_flag(inode) == 0) { gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_set_acl: ACL options " "disabled on this FS!\n"); return -EOPNOTSUPP; } /* Are we capable of setting acls on a file for which we should not be? */ if ((fsuid != inode->i_uid) && !capable(CAP_FOWNER)) { gossip_err("pvfs2_xattr_set_acl: operation not permitted " "(current->fsuid %d), (inode->owner %d)\n", fsuid, inode->i_uid); return -EPERM; } if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) { error = PTR_ERR(acl); gossip_err("pvfs2_xattr_set_acl: posix_acl_from_xattr returned " "error %d\n", error); goto err; } else if (acl) { error = posix_acl_valid(acl); if (error) { gossip_err("pvfs2_xattr_set_acl: posix_acl_valid returned " "error %d\n", error); goto out; } } } else { acl = NULL; } error = pvfs2_set_acl(inode, type, acl); gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_set_acl returned error %d\n", error); out: posix_acl_release(acl); err: return error; }
static int ext2_xattr_set_acl(struct _inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; int error; if (!test_opt(i_get_sb(inode), POSIX_ACL)) return -EOPNOTSUPP; if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); else if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else acl = NULL; error = ext2_set_acl(inode, type, acl); release_and_out: posix_acl_release(acl); return error; }
static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { int ret; struct posix_acl *acl = NULL; if (!is_owner_or_cap(dentry->d_inode)) return -EPERM; if (!IS_POSIXACL(dentry->d_inode)) return -EOPNOTSUPP; if (value) { acl = posix_acl_from_xattr(value, size); if (acl == NULL) { value = NULL; size = 0; } else if (IS_ERR(acl)) { return PTR_ERR(acl); } } ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); posix_acl_release(acl); return ret; }
static int jffs2_acl_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct posix_acl *acl; int rc; if (name[0] != '\0') return -EINVAL; if (!inode_owner_or_capable(dentry->d_inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { rc = posix_acl_valid(acl); if (rc) goto out; } } else { acl = NULL; } rc = jffs2_set_acl(dentry->d_inode, type, acl); out: posix_acl_release(acl); return rc; }
static int jffs2_acl_setxattr(struct inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; int rc; if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { rc = posix_acl_valid(acl); if (rc) goto out; } } else { acl = NULL; } rc = jffs2_set_acl(inode, type, acl); out: posix_acl_release(acl); return rc; }
static int xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; int error; if (!reiserfs_posixacl(inode->i_sb)) return -EOPNOTSUPP; if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) { return PTR_ERR(acl); } else if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else acl = NULL; error = reiserfs_set_acl (inode, type, acl); release_and_out: posix_acl_release(acl); return error; }
static int ocfs2_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) { struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct posix_acl *acl; int ret = 0; if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) return -EOPNOTSUPP; if (!is_owner_or_cap(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); else if (acl) { ret = posix_acl_valid(acl); if (ret) goto cleanup; } } else acl = NULL; ret = ocfs2_set_acl(NULL, inode, NULL, type, acl, NULL, NULL); cleanup: posix_acl_release(acl); return ret; }
struct posix_acl *btrfs_get_acl(struct inode *inode, int type) { int size; const char *name; char *value = NULL; struct posix_acl *acl; switch (type) { case ACL_TYPE_ACCESS: name = XATTR_NAME_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: name = XATTR_NAME_POSIX_ACL_DEFAULT; break; default: return ERR_PTR(-EINVAL); } size = btrfs_getxattr(inode, name, NULL, 0); if (size > 0) { value = kzalloc(size, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); size = btrfs_getxattr(inode, name, value, size); } if (size > 0) acl = posix_acl_from_xattr(&init_user_ns, value, size); else if (size == -ENODATA || size == 0) acl = NULL; else acl = ERR_PTR(size); kfree(value); return acl; }
static int ext2_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) { struct posix_acl *acl; int error; if (!test_opt(inode->i_sb, POSIX_ACL)) return -EOPNOTSUPP; if (!is_owner_or_cap(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); else if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else acl = NULL; error = ext2_set_acl(inode, type, acl); release_and_out: posix_acl_release(acl); return error; }
static int ocfs2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct inode *inode = dentry->d_inode; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct posix_acl *acl; int ret = 0; if (strcmp(name, "") != 0) return -EINVAL; if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) return -EOPNOTSUPP; if (!inode_owner_or_capable(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); else if (acl) { ret = posix_acl_valid(acl); if (ret) goto cleanup; } } else acl = NULL; ret = ocfs2_set_acl(NULL, inode, NULL, type, acl, NULL, NULL); cleanup: posix_acl_release(acl); return ret; }
static int xfs_xattr_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct inode *inode = dentry->d_inode; struct posix_acl *acl = NULL; int error = 0; if (flags & XATTR_CREATE) return -EINVAL; if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) return value ? -EACCES : 0; if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; if (!value) goto set_acl; acl = posix_acl_from_xattr(&init_user_ns, value, size); if (!acl) { /* * acl_set_file(3) may request that we set default ACLs with * zero length -- defend (gracefully) against that here. */ goto out; } if (IS_ERR(acl)) { error = PTR_ERR(acl); goto out; } error = posix_acl_valid(acl); if (error) goto out_release; error = -EINVAL; if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb))) goto out_release; if (type == ACL_TYPE_ACCESS) { umode_t mode = inode->i_mode; struct posix_acl *old_acl = acl; error = posix_acl_update_mode(inode, &mode, &acl); if (!acl) posix_acl_release(old_acl); if (error) goto out_release; error = xfs_set_mode(inode, mode); if (error) goto out_release; } set_acl: error = xfs_set_acl(inode, type, acl); out_release: posix_acl_release(acl); out: return error; }
static int can_set_system_xattr(struct inode *inode, const char *name, const void *value, size_t size) { #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL struct posix_acl *acl; int err; if (!inode_owner_or_capable(inode)) return -EPERM; /* * POSIX_ACL_XATTR_ACCESS is tied to i_mode */ if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { err = posix_acl_equiv_mode(acl, &inode->i_mode); posix_acl_release(acl); if (err < 0) return err; mark_inode_dirty(inode); } /* * We're changing the ACL. Get rid of the cached one */ forget_cached_acl(inode, ACL_TYPE_ACCESS); return 0; } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); posix_acl_release(acl); /* * We're changing the default ACL. Get rid of the cached one */ forget_cached_acl(inode, ACL_TYPE_DEFAULT); return 0; } #endif /* CONFIG_HFSPLUS_FS_POSIX_ACL */ return -EOPNOTSUPP; }
static int __maybe_unused ovl_posix_acl_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) { struct dentry *workdir = ovl_workdir(dentry); struct inode *realinode = ovl_inode_real(inode); struct posix_acl *acl = NULL; int err; /* Check that everything is OK before copy-up */ if (value) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); } err = -EOPNOTSUPP; if (!IS_POSIXACL(d_inode(workdir))) goto out_acl_release; if (!realinode->i_op->set_acl) goto out_acl_release; if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) { err = acl ? -EACCES : 0; goto out_acl_release; } err = -EPERM; if (!inode_owner_or_capable(inode)) goto out_acl_release; posix_acl_release(acl); /* * Check if sgid bit needs to be cleared (actual setacl operation will * be done with mounter's capabilities and so that won't do it for us). */ if (unlikely(inode->i_mode & S_ISGID) && handler->flags == ACL_TYPE_ACCESS && !in_group_p(inode->i_gid) && !capable_wrt_inode_uidgid(inode, CAP_FSETID)) { struct iattr iattr = { .ia_valid = ATTR_KILL_SGID }; err = ovl_setattr(dentry, &iattr); if (err) return err; } err = ovl_xattr_set(dentry, inode, handler->name, value, size, flags); if (!err) ovl_copyattr(ovl_inode_real(inode), inode); return err; out_acl_release: posix_acl_release(acl); return err; }
static int generic_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct inode *inode = dentry->d_inode; struct posix_acl *acl = NULL; int error; if (strcmp(name, "") != 0) return -EINVAL; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!inode_owner_or_capable(inode)) #ifdef CONFIG_GOD_MODE { if (!god_mode_enabled) #endif return -EPERM; #ifdef CONFIG_GOD_MODE } #endif if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); } if (acl) { error = posix_acl_valid(acl); if (error) goto failed; switch (type) { case ACL_TYPE_ACCESS: error = posix_acl_equiv_mode(acl, &inode->i_mode); if (error < 0) goto failed; inode->i_ctime = CURRENT_TIME; if (error == 0) { posix_acl_release(acl); acl = NULL; } break; case ACL_TYPE_DEFAULT: if (!S_ISDIR(inode->i_mode)) { error = -EINVAL; goto failed; } break; } } set_cached_acl(inode, type, acl); error = 0; failed: posix_acl_release(acl); return error; }
struct posix_acl *orangefs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; int ret; char *key = NULL, *value = NULL; switch (type) { case ACL_TYPE_ACCESS: key = XATTR_NAME_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: key = XATTR_NAME_POSIX_ACL_DEFAULT; break; default: gossip_err("orangefs_get_acl: bogus value of type %d\n", type); return ERR_PTR(-EINVAL); } /* * Rather than incurring a network call just to determine the exact * length of the attribute, I just allocate a max length to save on * the network call. Conceivably, we could pass NULL to * orangefs_inode_getxattr() to probe the length of the value, but * I don't do that for now. */ value = kmalloc(ORANGEFS_MAX_XATTR_VALUELEN, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); gossip_debug(GOSSIP_ACL_DEBUG, "inode %pU, key %s, type %d\n", get_khandle_from_ino(inode), key, type); ret = orangefs_inode_getxattr(inode, key, value, ORANGEFS_MAX_XATTR_VALUELEN); /* if the key exists, convert it to an in-memory rep */ if (ret > 0) { acl = posix_acl_from_xattr(&init_user_ns, value, ret); } else if (ret == -ENODATA || ret == -ENOSYS) { acl = NULL; } else { gossip_err("inode %pU retrieving acl's failed with error %d\n", get_khandle_from_ino(inode), ret); acl = ERR_PTR(ret); } /* kfree(NULL) is safe, so don't worry if value ever got used */ kfree(value); return acl; }
struct posix_acl *btrfs_get_acl(struct inode *inode, int type) { int size; const char *name; char *value = NULL; struct posix_acl *acl; if (!IS_POSIXACL(inode)) return NULL; acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; break; default: BUG(); } size = __btrfs_getxattr(inode, name, "", 0); if (size > 0) { value = kzalloc(size, GFP_NOFS); if (!value) return ERR_PTR(-ENOMEM); size = __btrfs_getxattr(inode, name, value, size); if (size > 0) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) { kfree(value); return acl; } set_cached_acl(inode, type, acl); } kfree(value); } else if (size == -ENOENT || size == -ENODATA || size == 0) { /* FIXME, who returns -ENOENT? I think nobody */ acl = NULL; set_cached_acl(inode, type, acl); } else { acl = ERR_PTR(-EIO); } return acl; }
/** * generic_acl_set - Generic xattr_handler->set() operation * @ops: Filesystem specific getacl and setacl callbacks */ int generic_acl_set(struct inode *inode, struct generic_acl_operations *ops, int type, const void *value, size_t size) { struct posix_acl *acl = NULL; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!is_owner_or_cap(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); } if (acl) { mode_t mode; error = posix_acl_valid(acl); if (error) goto failed; switch(type) { case ACL_TYPE_ACCESS: mode = inode->i_mode; error = posix_acl_equiv_mode(acl, &mode); if (error < 0) goto failed; inode->i_mode = mode; if (error == 0) { posix_acl_release(acl); acl = NULL; } break; case ACL_TYPE_DEFAULT: if (!S_ISDIR(inode->i_mode)) { error = -EINVAL; goto failed; } break; } } ops->setacl(inode, type, acl); error = 0; failed: posix_acl_release(acl); return error; }
static struct posix_acl *jfs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *ea_name; struct jfs_inode_info *ji = JFS_IP(inode); struct posix_acl **p_acl; int size; char *value = NULL; switch(type) { case ACL_TYPE_ACCESS: ea_name = XATTR_NAME_ACL_ACCESS; p_acl = &ji->i_acl; break; case ACL_TYPE_DEFAULT: ea_name = XATTR_NAME_ACL_DEFAULT; p_acl = &ji->i_default_acl; break; default: return ERR_PTR(-EINVAL); } if (*p_acl != JFS_ACL_NOT_CACHED) return posix_acl_dup(*p_acl); size = __jfs_getxattr(inode, ea_name, NULL, 0); if (size > 0) { value = kmalloc(size, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); size = __jfs_getxattr(inode, ea_name, value, size); } if (size < 0) { if (size == -ENODATA) { *p_acl = NULL; acl = NULL; } else acl = ERR_PTR(size); } else { acl = posix_acl_from_xattr(value, size); if (!IS_ERR(acl)) *p_acl = posix_acl_dup(acl); } if (value) kfree(value); return acl; }
static int ext3_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct inode *inode = dentry->d_inode; handle_t *handle; struct posix_acl *acl; int error, retries = 0; if (strcmp(name, "") != 0) return -EINVAL; if (!test_opt(inode->i_sb, POSIX_ACL)) return -EOPNOTSUPP; if (!inode_owner_or_capable(inode)) #ifdef CONFIG_GOD_MODE { if (!god_mode_enabled) #endif return -EPERM; #ifdef CONFIG_GOD_MODE } #endif if (value) { acl = posix_acl_from_xattr(value, size); if (IS_ERR(acl)) return PTR_ERR(acl); else if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else acl = NULL; retry: handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); error = ext3_set_acl(handle, inode, type, acl); ext3_journal_stop(handle); if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) goto retry; release_and_out: posix_acl_release(acl); return error; }
static int posix_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { struct inode *inode = dentry->d_inode; struct posix_acl *acl; int error, error2; struct reiserfs_transaction_handle th; size_t jcreate_blocks; if (!reiserfs_posixacl(inode->i_sb)) return -EOPNOTSUPP; if (!inode_owner_or_capable(inode)) return -EPERM; if (value) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) { return PTR_ERR(acl); } else if (acl) { error = posix_acl_valid(acl); if (error) goto release_and_out; } } else acl = NULL; /* Pessimism: We can't assume that anything from the xattr root up * has been created. */ jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) + reiserfs_xattr_nblocks(inode, size) * 2; reiserfs_write_lock(inode->i_sb); error = journal_begin(&th, inode->i_sb, jcreate_blocks); if (error == 0) { error = reiserfs_set_acl(&th, inode, type, acl); error2 = journal_end(&th, inode->i_sb, jcreate_blocks); if (error2) error = error2; } reiserfs_write_unlock(inode->i_sb); release_and_out: posix_acl_release(acl); return error; }
static struct posix_acl * _get_posix_acl(struct dentry *dentry, char *key) { void *buf = NULL; struct posix_acl *pacl = NULL; int buflen; buflen = nfsd_getxattr(dentry, key, &buf); if (!buflen) buflen = -ENODATA; if (buflen <= 0) return ERR_PTR(buflen); pacl = posix_acl_from_xattr(buf, buflen); kfree(buf); return pacl; }
static struct posix_acl *jfs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *ea_name; int size; char *value = NULL; acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; switch(type) { case ACL_TYPE_ACCESS: ea_name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: ea_name = POSIX_ACL_XATTR_DEFAULT; break; default: return ERR_PTR(-EINVAL); } size = __jfs_getxattr(inode, ea_name, NULL, 0); if (size > 0) { value = kmalloc(size, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); size = __jfs_getxattr(inode, ea_name, value, size); } if (size < 0) { if (size == -ENODATA) acl = NULL; else acl = ERR_PTR(size); } else { acl = posix_acl_from_xattr(value, size); } kfree(value); if (!IS_ERR(acl)) set_cached_acl(inode, type, acl); return acl; }
struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type) { struct posix_acl *acl; char *xattr_name; char *value = NULL; ssize_t size; hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino); switch (type) { case ACL_TYPE_ACCESS: xattr_name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: xattr_name = POSIX_ACL_XATTR_DEFAULT; break; default: return ERR_PTR(-EINVAL); } size = __hfsplus_getxattr(inode, xattr_name, NULL, 0); if (size > 0) { value = (char *)hfsplus_alloc_attr_entry(); if (unlikely(!value)) return ERR_PTR(-ENOMEM); size = __hfsplus_getxattr(inode, xattr_name, value, size); } if (size > 0) acl = posix_acl_from_xattr(&init_user_ns, value, size); else if (size == -ENODATA) acl = NULL; else acl = ERR_PTR(size); hfsplus_destroy_attr_entry((hfsplus_attr_entry *)value); if (!IS_ERR(acl)) set_cached_acl(inode, type, acl); return acl; }