Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab17c4f0 authored by Jeff Mahoney's avatar Jeff Mahoney Committed by Al Viro
Browse files

reiserfs: fixup xattr_root caching



 The xattr_root caching was broken from my previous patch set. It wouldn't
 cause corruption, but could cause decreased performance due to allocating
 a larger chunk of the journal (~ 27 blocks) than it would actually use.

 This patch loads the xattr root dentry at xattr initialization and creates
 it on-demand. Since we're using the cached dentry, there's no point
 in keeping lookup_or_create_dir around, so that's removed.

Signed-off-by: default avatarJeff Mahoney <jeffm@suse.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent edcc37a0
Loading
Loading
Loading
Loading
+46 −27
Original line number Diff line number Diff line
@@ -113,36 +113,28 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)

#define xattr_may_create(flags)	(!flags || flags & XATTR_CREATE)

/* Returns and possibly creates the xattr dir. */
static struct dentry *lookup_or_create_dir(struct dentry *parent,
					    const char *name, int flags)
static struct dentry *open_xa_root(struct super_block *sb, int flags)
{
	struct dentry *dentry;
	BUG_ON(!parent);
	struct dentry *privroot = REISERFS_SB(sb)->priv_root;
	struct dentry *xaroot;
	if (!privroot->d_inode)
		return ERR_PTR(-ENODATA);

	mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_XATTR);
	dentry = lookup_one_len(name, parent, strlen(name));
	if (!IS_ERR(dentry) && !dentry->d_inode) {
		int err = -ENODATA;
	mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);

	xaroot = dget(REISERFS_SB(sb)->xattr_root);
	if (!xaroot->d_inode) {
		int err = -ENODATA;
		if (xattr_may_create(flags))
			err = xattr_mkdir(parent->d_inode, dentry, 0700);

			err = xattr_mkdir(privroot->d_inode, xaroot, 0700);
		if (err) {
			dput(dentry);
			dentry = ERR_PTR(err);
		}
			dput(xaroot);
			xaroot = ERR_PTR(err);
		}
	mutex_unlock(&parent->d_inode->i_mutex);
	return dentry;
	}

static struct dentry *open_xa_root(struct super_block *sb, int flags)
{
	struct dentry *privroot = REISERFS_SB(sb)->priv_root;
	if (!privroot)
		return ERR_PTR(-ENODATA);
	return lookup_or_create_dir(privroot, XAROOT_NAME, flags);
	mutex_unlock(&privroot->d_inode->i_mutex);
	return xaroot;
}

static struct dentry *open_xa_dir(const struct inode *inode, int flags)
@@ -158,10 +150,22 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
		 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
		 inode->i_generation);

	xadir = lookup_or_create_dir(xaroot, namebuf, flags);
	mutex_lock_nested(&xaroot->d_inode->i_mutex, I_MUTEX_XATTR);

	xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
	if (!IS_ERR(xadir) && !xadir->d_inode) {
		int err = -ENODATA;
		if (xattr_may_create(flags))
			err = xattr_mkdir(xaroot->d_inode, xadir, 0700);
		if (err) {
			dput(xadir);
			xadir = ERR_PTR(err);
		}
	}

	mutex_unlock(&xaroot->d_inode->i_mutex);
	dput(xaroot);
	return xadir;

}

/* The following are side effects of other operations that aren't explicitly
@@ -986,19 +990,33 @@ int reiserfs_lookup_privroot(struct super_block *s)
int reiserfs_xattr_init(struct super_block *s, int mount_flags)
{
	int err = 0;
	struct dentry *privroot = REISERFS_SB(s)->priv_root;

#ifdef CONFIG_REISERFS_FS_XATTR
	err = xattr_mount_check(s);
	if (err)
		goto error;

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

	if (privroot->d_inode) {
		s->s_xattr = reiserfs_xattr_handlers;
		mutex_lock(&privroot->d_inode->i_mutex);
		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) {
@@ -1008,11 +1026,12 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
#endif

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

	return err;
}
+1 −1
Original line number Diff line number Diff line
@@ -402,7 +402,7 @@ struct reiserfs_sb_info {
	int reserved_blocks;	/* amount of blocks reserved for further allocations */
	spinlock_t bitmap_lock;	/* this lock on now only used to protect reserved_blocks variable */
	struct dentry *priv_root;	/* root of /.reiserfs_priv */
	struct dentry *xattr_root;	/* root of /.reiserfs_priv/.xa */
	struct dentry *xattr_root;	/* root of /.reiserfs_priv/xattrs */
	int j_errno;
#ifdef CONFIG_QUOTA
	char *s_qf_names[MAXQUOTAS];
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static inline size_t reiserfs_xattr_jcreate_nblocks(struct inode *inode)

	if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) {
		nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
		if (REISERFS_SB(inode->i_sb)->xattr_root == NULL)
		if (!REISERFS_SB(inode->i_sb)->xattr_root->d_inode)
			nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
	}