Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/*
 * Called under i_mutex
 */
int reiserfs_acl_chmod(struct inode *inode)
{
	if (IS_PRIVATE(inode))
		return 0;
	if (get_inode_sd_version(inode) == STAT_DATA_V1 ||
	    !reiserfs_posixacl(inode->i_sb))
		return 0;

	return posix_acl_chmod(inode, inode->i_mode);
}
Ejemplo n.º 3
0
static int
posix_acl_default_list (struct inode *inode, const char *name, int namelen, char *out)
{
    int len = namelen;
    if (!reiserfs_posixacl (inode->i_sb))
        return 0;
    if (out)
        memcpy (out, name, len);

    return len;
}
Ejemplo n.º 4
0
static size_t posix_acl_default_list(struct dentry *dentry, char *list,
				     size_t list_size, const char *name,
				     size_t name_len, int type)
{
	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
	if (!reiserfs_posixacl(dentry->d_sb))
		return 0;
	if (list && size <= list_size)
		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
	return size;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
/* Looks up and caches the result of the default ACL.
 * We do this so that we don't need to carry the xattr_sem into
 * reiserfs_new_inode if we don't need to */
int reiserfs_cache_default_acl(struct inode *inode)
{
    int ret = 0;
    if (reiserfs_posixacl(inode->i_sb) && !is_reiserfs_priv_object(inode)) {
        struct posix_acl *acl;
        reiserfs_read_lock_xattr_i(inode);
        reiserfs_read_lock_xattrs(inode->i_sb);
        acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
        reiserfs_read_unlock_xattrs(inode->i_sb);
        reiserfs_read_unlock_xattr_i(inode);
        ret = (acl && !IS_ERR(acl));
        if (ret)
            posix_acl_release(acl);
    }

    return ret;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
/* We need to take a copy of the mount flags since things like
 * MS_RDONLY don't get set until *after* we're called.
 * mount_flags != mount_options */
int reiserfs_xattr_init(struct super_block *s, int mount_flags)
{
	int err = 0;
	struct dentry *privroot = REISERFS_SB(s)->priv_root;

	err = xattr_mount_check(s);
	if (err)
		goto error;

	if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
		reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s);
		err = create_privroot(REISERFS_SB(s)->priv_root);
		mutex_unlock(&s->s_root->d_inode->i_mutex);
	}

	if (privroot->d_inode) {
		s->s_xattr = reiserfs_xattr_handlers;
		reiserfs_mutex_lock_safe(&privroot->d_inode->i_mutex, s);
		if (!REISERFS_SB(s)->xattr_root) {
			struct dentry *dentry;
			dentry = lookup_one_len(XAROOT_NAME, privroot,
						strlen(XAROOT_NAME));
			if (!IS_ERR(dentry))
				REISERFS_SB(s)->xattr_root = dentry;
			else
				err = PTR_ERR(dentry);
		}
		mutex_unlock(&privroot->d_inode->i_mutex);
	}

error:
	if (err) {
		clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
		clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
	}

	/* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
	if (reiserfs_posixacl(s))
		s->s_flags |= MS_POSIXACL;
	else
		s->s_flags &= ~MS_POSIXACL;

	return err;
}
Ejemplo n.º 10
0
static int
xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
{
	struct posix_acl *acl;
	int error;

	if (!reiserfs_posixacl(inode->i_sb))
		return -EOPNOTSUPP;

	acl = reiserfs_get_acl (inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (acl == NULL)
		return -ENODATA;
	error = posix_acl_to_xattr(acl, buffer, size);
	posix_acl_release(acl);

	return error;
}
Ejemplo n.º 11
0
static int
posix_acl_get(struct dentry *dentry, const char *name, void *buffer,
		size_t size, int type)
{
	struct posix_acl *acl;
	int error;

	if (!reiserfs_posixacl(dentry->d_sb))
		return -EOPNOTSUPP;

	acl = reiserfs_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, buffer, size);
	posix_acl_release(acl);

	return error;
}