Commit ab17c4f02156c4f75d7fa43a5aa2a7f942d47201
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
fs/reiserfs/xattr.c
... | ... | @@ -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 |