Example #1
0
File: xattr.c Project: 7799/linux
/*
 * 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;
	struct listxattr_buf buf = {
		.ctx.actor = listxattr_filler,
		.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_inode(dir->d_inode, &buf.ctx);
	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;
}
Example #2
0
File: xattr.c Project: 7799/linux
static int reiserfs_for_each_xattr(struct inode *inode,
				   int (*action)(struct dentry *, void *),
				   void *data)
{
	struct dentry *dir;
	int i, err = 0;
	struct reiserfs_dentry_buf buf = {
		.ctx.actor = fill_with_dentries,
	};

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

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

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

	buf.xadir = dir;
	while (1) {
		err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx);
		if (err)
			break;
		if (!buf.count)
			break;
		for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) {
			struct dentry *dentry = buf.dentries[i];

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

			dput(dentry);
			buf.dentries[i] = NULL;
		}
		if (err)
			break;
		buf.count = 0;
	}
	mutex_unlock(&dir->d_inode->i_mutex);

	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;
		reiserfs_write_lock(inode->i_sb);
		err = journal_begin(&th, inode->i_sb, blocks);
		reiserfs_write_unlock(inode->i_sb);
		if (!err) {
			int jerror;
			mutex_lock_nested(&dir->d_parent->d_inode->i_mutex,
					  I_MUTEX_XATTR);
			err = action(dir, data);
			reiserfs_write_lock(inode->i_sb);
			jerror = journal_end(&th, inode->i_sb, blocks);
			reiserfs_write_unlock(inode->i_sb);
			mutex_unlock(&dir->d_parent->d_inode->i_mutex);
			err = jerror ?: err;
		}
	}
Example #3
0
File: dir.c Project: 19Dan01/linux
static int reiserfs_readdir(struct file *file, struct dir_context *ctx)
{
	return reiserfs_readdir_inode(file_inode(file), ctx);
}