int xfs_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); clone = posix_acl_clone(acl, GFP_KERNEL); posix_acl_release(acl); if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); if (!error) error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone); posix_acl_release(clone); return error; }
int xfs_check_acl(struct inode *inode, int mask) { struct xfs_inode *ip = XFS_I(inode); struct posix_acl *acl; int error = -EAGAIN; xfs_itrace_entry(ip); /* * If there is no attribute fork no ACL exists on this inode and * we can skip the whole exercise. */ if (!XFS_IFORK_Q(ip)) return -EAGAIN; acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { error = posix_acl_permission(inode, acl, mask); posix_acl_release(acl); } return error; }
int xfs_check_acl(struct inode *inode, int mask, unsigned int flags) { struct xfs_inode *ip; struct posix_acl *acl; int error = -EAGAIN; ip = XFS_I(inode); trace_xfs_check_acl(ip); /* * If there is no attribute fork no ACL exists on this inode and * we can skip the whole exercise. */ if (!XFS_IFORK_Q(ip)) return -EAGAIN; if (flags & IPERM_FLAG_RCU) { if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) return -ECHILD; return -EAGAIN; } acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { error = posix_acl_permission(inode, acl, mask); posix_acl_release(acl); } return error; }
STATIC int xfs_vn_mknod( struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { struct inode *inode; struct xfs_inode *ip = NULL; struct posix_acl *default_acl = NULL; struct xfs_name name; int error; if (S_ISCHR(mode) || S_ISBLK(mode)) { if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) return -EINVAL; rdev = sysv_encode_dev(rdev); } else { rdev = 0; } if (IS_POSIXACL(dir)) { default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT); if (IS_ERR(default_acl)) return PTR_ERR(default_acl); if (!default_acl) mode &= ~current_umask(); } xfs_dentry_to_name(&name, dentry); error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); if (unlikely(error)) goto out_free_acl; inode = VFS_I(ip); error = xfs_init_security(inode, dir, &dentry->d_name); if (unlikely(error)) goto out_cleanup_inode; if (default_acl) { error = -xfs_inherit_acl(inode, default_acl); default_acl = NULL; if (unlikely(error)) goto out_cleanup_inode; } d_instantiate(dentry, inode); return -error; out_cleanup_inode: xfs_cleanup_inode(dir, inode, dentry); out_free_acl: posix_acl_release(default_acl); return -error; }
static int xfs_xattr_acl_get(struct dentry *dentry, const char *name, void *value, size_t size, int type) { struct posix_acl *acl; int error; acl = xfs_get_acl(dentry->d_inode, type); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl == NULL) return -ENODATA; error = posix_acl_to_xattr(&init_user_ns, acl, value, size); posix_acl_release(acl); return error; }
int xfs_acl_chmod(struct inode *inode) { struct posix_acl *acl; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); if (error) return error; error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); return error; }
static int xfs_xattr_system_get(struct inode *inode, const char *name, void *value, size_t size) { struct posix_acl *acl; int type, error; type = xfs_decode_acl(name); if (type < 0) return type; acl = xfs_get_acl(inode, type); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl == NULL) return -ENODATA; error = posix_acl_to_xattr(acl, value, size); posix_acl_release(acl); return error; }