int jfs_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int rc; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = jfs_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; rc = posix_acl_chmod_masq(clone, inode->i_mode); if (!rc) { tid_t tid = txBegin(inode->i_sb, 0); mutex_lock(&JFS_IP(inode)->commit_mutex); rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); if (!rc) rc = txCommit(tid, 1, &inode, 0); txEnd(tid); mutex_unlock(&JFS_IP(inode)->commit_mutex); } posix_acl_release(clone); return rc; }
int ocfs2_acl_chmod(struct inode *inode) { struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct posix_acl *acl, *clone; int ret; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) return 0; acl = ocfs2_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; ret = posix_acl_chmod_masq(clone, inode->i_mode); if (!ret) ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS, clone, NULL, NULL); posix_acl_release(clone); return ret; }
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 btrfs_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int ret = 0; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!IS_POSIXACL(inode)) return 0; acl = btrfs_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; ret = posix_acl_chmod_masq(clone, inode->i_mode); if (!ret) ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); posix_acl_release(clone); return ret; }
int f2fs_acl_chmod(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct posix_acl *acl, *clone; int error; mode_t mode = get_inode_mode(inode); if (!test_opt(sbi, POSIX_ACL)) return 0; if (S_ISLNK(mode)) return -EOPNOTSUPP; acl = f2fs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); //error = posix_acl_chmod(&acl, GFP_KERNEL, mode); 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) return error; error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); return error; }
/* * Handles the case when a chmod is done for an inode that may have an * access control list. * The inode->i_mode field is updated to the desired value by the caller * before calling this function which returns 0 on success and a -ve * number on failure. */ int pvfs2_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int error; if (get_acl_flag(inode) == 0) { gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_acl_chmod: ACL options " "disabled on this FS!\n"); return 0; } if (S_ISLNK(inode->i_mode)) { gossip_err("pvfs2_acl_chmod: operation not permitted on symlink!\n"); error = -EACCES; goto out; } acl = pvfs2_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) { error = PTR_ERR(acl); gossip_err("pvfs2_acl_chmod: get acl (access) failed with %d\n", error); goto out; } if(!acl) { error = 0; goto out; } clone = posix_acl_clone(acl, GFP_KERNEL); posix_acl_release(acl); if (!clone) { gossip_err("pvfs2_acl_chmod failed with ENOMEM\n"); error = -ENOMEM; goto out; } error = posix_acl_chmod_masq(clone, inode->i_mode); if (!error) { error = pvfs2_set_acl(inode, ACL_TYPE_ACCESS, clone); gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_acl_chmod: pvfs2 set acl " "(access) returned %d\n", error); } posix_acl_release(clone); out: return error; }
int reiserfs_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (get_inode_sd_version(inode) == STAT_DATA_V1 || !reiserfs_posixacl(inode->i_sb)) { return 0; } reiserfs_write_unlock(inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); reiserfs_write_lock(inode->i_sb); if (!acl) return 0; if (IS_ERR(acl)) return PTR_ERR(acl); clone = posix_acl_clone(acl, GFP_NOFS); posix_acl_release(acl); if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); if (!error) { struct reiserfs_transaction_handle th; size_t size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(clone->a_count)); int depth; depth = reiserfs_write_lock_once(inode->i_sb); error = journal_begin(&th, inode->i_sb, size * 2); if (!error) { int error2; error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, clone); error2 = journal_end(&th, inode->i_sb, size * 2); if (error2) error = error2; } reiserfs_write_unlock_once(inode->i_sb, depth); } posix_acl_release(clone); return error; }
int reiserfs_acl_chmod (struct inode *inode) { struct posix_acl *acl, *clone; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (get_inode_sd_version (inode) == STAT_DATA_V1 || !reiserfs_posixacl(inode->i_sb)) { return 0; } reiserfs_read_lock_xattrs (inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); reiserfs_read_unlock_xattrs (inode->i_sb); if (!acl) return 0; if (IS_ERR(acl)) return PTR_ERR(acl); clone = posix_acl_clone(acl, GFP_NOFS); posix_acl_release(acl); if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); if (!error) { int lock = !has_xattr_dir (inode); reiserfs_write_lock_xattr_i (inode); if (lock) reiserfs_write_lock_xattrs (inode->i_sb); else reiserfs_read_lock_xattrs (inode->i_sb); error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); if (lock) reiserfs_write_unlock_xattrs (inode->i_sb); else reiserfs_read_unlock_xattrs (inode->i_sb); reiserfs_write_unlock_xattr_i (inode); } posix_acl_release(clone); return error; }
int jffs2_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int rc; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = jffs2_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; rc = posix_acl_chmod_masq(clone, inode->i_mode); if (!rc) rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone); posix_acl_release(clone); return rc; }
/** * generic_acl_chmod - change the access acl of @inode upon chmod() * @ops: FIlesystem specific getacl and setacl callbacks * * A chmod also changes the permissions of the owner, group/mask, and * other ACL entries. */ int generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops) { struct posix_acl *acl, *clone; int error = 0; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = ops->getacl(inode, ACL_TYPE_ACCESS); if (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) ops->setacl(inode, ACL_TYPE_ACCESS, clone); posix_acl_release(clone); } return error; }
/* * Does chmod for an inode that may have an Access Control List. The * inode->i_mode field must be updated to the desired value by the caller * before calling this function. * Returns 0 on success, or a negative error number. * * We change the ACL rather than storing some ACL entries in the file * mode permission bits (which would be more efficient), because that * would break once additional permissions (like ACL_APPEND, ACL_DELETE * for directories) are added. There are no more bits available in the * file mode. * * inode->i_mutex: down */ int ext3_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!test_opt(inode->i_sb, POSIX_ACL)) return 0; acl = ext3_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) { handle_t *handle; int retries = 0; retry: handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); if (IS_ERR(handle)) { error = PTR_ERR(handle); ext3_std_error(inode->i_sb, error); goto out; } error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone); ext3_journal_stop(handle); if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) goto retry; } out: posix_acl_release(clone); return error; }
/* * Does chmod for an inode that may have an Access Control List. The * inode->i_mode field must be updated to the desired value by the caller * before calling this function. * Returns 0 on success, or a negative error number. * * We change the ACL rather than storing some ACL entries in the file * mode permission bits (which would be more efficient), because that * would break once additional permissions (like ACL_APPEND, ACL_DELETE * for directories) are added. There are no more bits available in the * file mode. * * inode->i_mutex: down */ int ext2_acl_chmod(struct _inode *inode) { struct posix_acl *acl, *clone; int error; if (!test_opt(i_get_sb_ro(inode), POSIX_ACL)) return 0; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = ext2_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 = ext2_set_acl(inode, ACL_TYPE_ACCESS, clone); posix_acl_release(clone); return error; }
int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) { struct posix_acl *acl, *clone; char *data; unsigned int len; int error; acl = gfs2_acl_get(ip, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (!acl) return gfs2_setattr_simple(ip, attr); clone = posix_acl_clone(acl, GFP_NOFS); error = -ENOMEM; if (!clone) goto out; posix_acl_release(acl); acl = clone; error = posix_acl_chmod_masq(acl, attr->ia_mode); if (!error) { len = posix_acl_to_xattr(acl, NULL, 0); data = kmalloc(len, GFP_NOFS); error = -ENOMEM; if (data == NULL) goto out; posix_acl_to_xattr(acl, data, len); error = gfs2_xattr_acl_chmod(ip, attr, data); kfree(data); set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); } out: posix_acl_release(acl); return error; }