Commit ab17c4f02156c4f75d7fa43a5aa2a7f942d47201

Authored by Jeff Mahoney
Committed by Al Viro
1 parent edcc37a047

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: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 3 changed files with 48 additions and 29 deletions Side-by-side Diff

... ... @@ -113,36 +113,28 @@
113 113  
114 114 #define xattr_may_create(flags) (!flags || flags & XATTR_CREATE)
115 115  
116   -/* Returns and possibly creates the xattr dir. */
117   -static struct dentry *lookup_or_create_dir(struct dentry *parent,
118   - const char *name, int flags)
  116 +static struct dentry *open_xa_root(struct super_block *sb, int flags)
119 117 {
120   - struct dentry *dentry;
121   - BUG_ON(!parent);
  118 + struct dentry *privroot = REISERFS_SB(sb)->priv_root;
  119 + struct dentry *xaroot;
  120 + if (!privroot->d_inode)
  121 + return ERR_PTR(-ENODATA);
122 122  
123   - mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_XATTR);
124   - dentry = lookup_one_len(name, parent, strlen(name));
125   - if (!IS_ERR(dentry) && !dentry->d_inode) {
126   - int err = -ENODATA;
  123 + mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);
127 124  
  125 + xaroot = dget(REISERFS_SB(sb)->xattr_root);
  126 + if (!xaroot->d_inode) {
  127 + int err = -ENODATA;
128 128 if (xattr_may_create(flags))
129   - err = xattr_mkdir(parent->d_inode, dentry, 0700);
130   -
  129 + err = xattr_mkdir(privroot->d_inode, xaroot, 0700);
131 130 if (err) {
132   - dput(dentry);
133   - dentry = ERR_PTR(err);
  131 + dput(xaroot);
  132 + xaroot = ERR_PTR(err);
134 133 }
135 134 }
136   - mutex_unlock(&parent->d_inode->i_mutex);
137   - return dentry;
138   -}
139 135  
140   -static struct dentry *open_xa_root(struct super_block *sb, int flags)
141   -{
142   - struct dentry *privroot = REISERFS_SB(sb)->priv_root;
143   - if (!privroot)
144   - return ERR_PTR(-ENODATA);
145   - return lookup_or_create_dir(privroot, XAROOT_NAME, flags);
  136 + mutex_unlock(&privroot->d_inode->i_mutex);
  137 + return xaroot;
146 138 }
147 139  
148 140 static struct dentry *open_xa_dir(const struct inode *inode, int flags)
149 141  
... ... @@ -158,10 +150,22 @@
158 150 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
159 151 inode->i_generation);
160 152  
161   - xadir = lookup_or_create_dir(xaroot, namebuf, flags);
  153 + mutex_lock_nested(&xaroot->d_inode->i_mutex, I_MUTEX_XATTR);
  154 +
  155 + xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
  156 + if (!IS_ERR(xadir) && !xadir->d_inode) {
  157 + int err = -ENODATA;
  158 + if (xattr_may_create(flags))
  159 + err = xattr_mkdir(xaroot->d_inode, xadir, 0700);
  160 + if (err) {
  161 + dput(xadir);
  162 + xadir = ERR_PTR(err);
  163 + }
  164 + }
  165 +
  166 + mutex_unlock(&xaroot->d_inode->i_mutex);
162 167 dput(xaroot);
163 168 return xadir;
164   -
165 169 }
166 170  
167 171 /* The following are side effects of other operations that aren't explicitly
168 172  
169 173  
170 174  
... ... @@ -986,19 +990,33 @@
986 990 int reiserfs_xattr_init(struct super_block *s, int mount_flags)
987 991 {
988 992 int err = 0;
  993 + struct dentry *privroot = REISERFS_SB(s)->priv_root;
989 994  
990 995 #ifdef CONFIG_REISERFS_FS_XATTR
991 996 err = xattr_mount_check(s);
992 997 if (err)
993 998 goto error;
994 999  
995   - if (!REISERFS_SB(s)->priv_root->d_inode && !(mount_flags & MS_RDONLY)) {
  1000 + if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
996 1001 mutex_lock(&s->s_root->d_inode->i_mutex);
997 1002 err = create_privroot(REISERFS_SB(s)->priv_root);
998 1003 mutex_unlock(&s->s_root->d_inode->i_mutex);
999 1004 }
1000   - if (!err)
  1005 +
  1006 + if (privroot->d_inode) {
1001 1007 s->s_xattr = reiserfs_xattr_handlers;
  1008 + mutex_lock(&privroot->d_inode->i_mutex);
  1009 + if (!REISERFS_SB(s)->xattr_root) {
  1010 + struct dentry *dentry;
  1011 + dentry = lookup_one_len(XAROOT_NAME, privroot,
  1012 + strlen(XAROOT_NAME));
  1013 + if (!IS_ERR(dentry))
  1014 + REISERFS_SB(s)->xattr_root = dentry;
  1015 + else
  1016 + err = PTR_ERR(dentry);
  1017 + }
  1018 + mutex_unlock(&privroot->d_inode->i_mutex);
  1019 + }
1002 1020  
1003 1021 error:
1004 1022 if (err) {
1005 1023  
1006 1024  
... ... @@ -1008,11 +1026,12 @@
1008 1026 #endif
1009 1027  
1010 1028 /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
1011   - s->s_flags = s->s_flags & ~MS_POSIXACL;
1012 1029 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
1013 1030 if (reiserfs_posixacl(s))
1014 1031 s->s_flags |= MS_POSIXACL;
  1032 + else
1015 1033 #endif
  1034 + s->s_flags &= ~MS_POSIXACL;
1016 1035  
1017 1036 return err;
1018 1037 }
include/linux/reiserfs_fs_sb.h
... ... @@ -402,7 +402,7 @@
402 402 int reserved_blocks; /* amount of blocks reserved for further allocations */
403 403 spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
404 404 struct dentry *priv_root; /* root of /.reiserfs_priv */
405   - struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
  405 + struct dentry *xattr_root; /* root of /.reiserfs_priv/xattrs */
406 406 int j_errno;
407 407 #ifdef CONFIG_QUOTA
408 408 char *s_qf_names[MAXQUOTAS];
include/linux/reiserfs_xattr.h
... ... @@ -98,7 +98,7 @@
98 98  
99 99 if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) {
100 100 nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
101   - if (REISERFS_SB(inode->i_sb)->xattr_root == NULL)
  101 + if (!REISERFS_SB(inode->i_sb)->xattr_root->d_inode)
102 102 nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
103 103 }
104 104