Beispiel #1
0
/*
 * Inode operation listxattr()
 *
 * We totally ignore the generic listxattr here because it would be stupid
 * not to. Since the xattrs are organized in a directory, we can just
 * readdir to find them.
 */
ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
{
	struct dentry *dir;
	int err = 0;
	loff_t pos = 0;
	struct listxattr_buf buf = {
		.dentry = dentry,
		.buf = buffer,
		.size = buffer ? size : 0,
	};

	if (!dentry->d_inode)
		return -EINVAL;

	if (!dentry->d_sb->s_xattr ||
	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE);
	if (IS_ERR(dir)) {
		err = PTR_ERR(dir);
		if (err == -ENODATA)
			err = 0;  /* Not an error if there aren't any xattrs */
		goto out;
	}

	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR);
	err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos);
	mutex_unlock(&dir->d_inode->i_mutex);

	if (!err)
		err = buf.pos;

	dput(dir);
out:
	return err;
}

static int create_privroot(struct dentry *dentry)
{
	int err;
	struct inode *inode = dentry->d_parent->d_inode;
	WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));

	err = xattr_mkdir(inode, dentry, 0700);
	if (err || !dentry->d_inode) {
		reiserfs_warning(dentry->d_sb, "jdm-20006",
				 "xattrs/ACLs enabled and couldn't "
				 "find/create .reiserfs_priv. "
				 "Failing mount.");
		return -EOPNOTSUPP;
	}

	dentry->d_inode->i_flags |= S_PRIVATE;
	reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
		      "storage.\n", PRIVROOT_NAME);

	return 0;
}
Beispiel #2
0
static int reiserfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	struct dentry *dentry = file->f_path.dentry;
	return reiserfs_readdir_dentry(dentry, dirent, filldir, &file->f_pos);
}
Beispiel #3
0
/*
 * Inode operation listxattr()
 *
 * We totally ignore the generic listxattr here because it would be stupid
 * not to. Since the xattrs are organized in a directory, we can just
 * readdir to find them.
 */
ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
{
	struct dentry *dir;
	int err = 0;
	loff_t pos = 0;
	struct listxattr_buf buf = {
		.dentry = dentry,
		.buf = buffer,
		.size = buffer ? size : 0,
	};

	if (!dentry->d_inode)
		return -EINVAL;

	if (!dentry->d_sb->s_xattr ||
	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	dir = open_xa_dir(dentry->d_inode, XATTR_REPLACE);
	if (IS_ERR(dir)) {
		err = PTR_ERR(dir);
		if (err == -ENODATA)
			err = 0;  /* Not an error if there aren't any xattrs */
		goto out;
	}

	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR);
	err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos);
	mutex_unlock(&dir->d_inode->i_mutex);

	if (!err)
		err = buf.pos;

	dput(dir);
out:
	return err;
}

static int reiserfs_check_acl(struct inode *inode, int mask, unsigned int flags)
{
	struct posix_acl *acl;
	int error = -EAGAIN; /* do regular unix permission checks by default */

	if (flags & IPERM_FLAG_RCU)
		return -ECHILD;

	acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);

	if (acl) {
		if (!IS_ERR(acl)) {
			error = posix_acl_permission(inode, acl, mask);
			posix_acl_release(acl);
		} else if (PTR_ERR(acl) != -ENODATA)
			error = PTR_ERR(acl);
	}

	return error;
}

static int create_privroot(struct dentry *dentry)
{
	int err;
	struct inode *inode = dentry->d_parent->d_inode;
	WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));

	err = xattr_mkdir(inode, dentry, 0700);
	if (err || !dentry->d_inode) {
		reiserfs_warning(dentry->d_sb, "jdm-20006",
				 "xattrs/ACLs enabled and couldn't "
				 "find/create .reiserfs_priv. "
				 "Failing mount.");
		return -EOPNOTSUPP;
	}

	dentry->d_inode->i_flags |= S_PRIVATE;
	reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
		      "storage.\n", PRIVROOT_NAME);

	return 0;
}
Beispiel #4
0
static int reiserfs_for_each_xattr(struct inode *inode,
				   int (*action)(struct dentry *, void *),
				   void *data)
{
	struct dentry *dir;
	int i, err = 0;
	loff_t pos = 0;
	struct reiserfs_dentry_buf buf = {
		.count = 0,
	};

	/* Skip out, an xattr has no xattrs associated with it */
	if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
		return 0;

	reiserfs_write_unlock(inode->i_sb);
	dir = open_xa_dir(inode, XATTR_REPLACE);
	if (IS_ERR(dir)) {
		err = PTR_ERR(dir);
		reiserfs_write_lock(inode->i_sb);
		goto out;
	} else if (!dir->d_inode) {
		err = 0;
		reiserfs_write_lock(inode->i_sb);
		goto out_dir;
	}

	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR);

	reiserfs_write_lock(inode->i_sb);

	buf.xadir = dir;
	err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos);
	while ((err == 0 || err == -ENOSPC) && buf.count) {
		err = 0;

		for (i = 0; i < buf.count && buf.dentries[i]; i++) {
			int lerr = 0;
			struct dentry *dentry = buf.dentries[i];

			if (err == 0 && !S_ISDIR(dentry->d_inode->i_mode))
				lerr = action(dentry, data);

			dput(dentry);
			buf.dentries[i] = NULL;
			err = lerr ?: err;
		}
		buf.count = 0;
		if (!err)
			err = reiserfs_readdir_dentry(dir, &buf,
						      fill_with_dentries, &pos);
	}
	mutex_unlock(&dir->d_inode->i_mutex);

	/* Clean up after a failed readdir */
	cleanup_dentry_buf(&buf);

	if (!err) {
		/* We start a transaction here to avoid a ABBA situation
		 * between the xattr root's i_mutex and the journal lock.
		 * This doesn't incur much additional overhead since the
		 * new transaction will just nest inside the
		 * outer transaction. */
		int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 +
			     4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb);
		struct reiserfs_transaction_handle th;
		err = journal_begin(&th, inode->i_sb, blocks);
		if (!err) {
			int jerror;
			reiserfs_mutex_lock_nested_safe(
					  &dir->d_parent->d_inode->i_mutex,
					  I_MUTEX_XATTR, inode->i_sb);
			err = action(dir, data);
			jerror = journal_end(&th, inode->i_sb, blocks);
			mutex_unlock(&dir->d_parent->d_inode->i_mutex);
			err = jerror ?: err;
		}
	}