diff options
author | Jeff Mahoney <jeffm@suse.com> | 2009-05-05 15:30:15 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-05-09 10:49:39 -0400 |
commit | ab17c4f02156c4f75d7fa43a5aa2a7f942d47201 (patch) | |
tree | 20ff8ec91144d20966ac70adb24bd3372e3508c4 | |
parent | edcc37a0478836b4a51eafb1bcec6a52708f681d (diff) |
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>
-rw-r--r-- | fs/reiserfs/xattr.c | 73 | ||||
-rw-r--r-- | include/linux/reiserfs_fs_sb.h | 2 | ||||
-rw-r--r-- | include/linux/reiserfs_xattr.h | 2 |
3 files changed, 48 insertions, 29 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 2891f789f545..c77984473db9 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -113,36 +113,28 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
113 | 113 | ||
114 | #define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) | 114 | #define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) |
115 | 115 | ||
116 | /* Returns and possibly creates the xattr dir. */ | 116 | static struct dentry *open_xa_root(struct super_block *sb, int flags) |
117 | static struct dentry *lookup_or_create_dir(struct dentry *parent, | ||
118 | const char *name, int flags) | ||
119 | { | 117 | { |
120 | struct dentry *dentry; | 118 | struct dentry *privroot = REISERFS_SB(sb)->priv_root; |
121 | BUG_ON(!parent); | 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); | 123 | mutex_lock_nested(&privroot->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; | ||
127 | 124 | ||
125 | xaroot = dget(REISERFS_SB(sb)->xattr_root); | ||
126 | if (!xaroot->d_inode) { | ||
127 | int err = -ENODATA; | ||
128 | if (xattr_may_create(flags)) | 128 | if (xattr_may_create(flags)) |
129 | err = xattr_mkdir(parent->d_inode, dentry, 0700); | 129 | err = xattr_mkdir(privroot->d_inode, xaroot, 0700); |
130 | |||
131 | if (err) { | 130 | if (err) { |
132 | dput(dentry); | 131 | dput(xaroot); |
133 | dentry = ERR_PTR(err); | 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) | 136 | mutex_unlock(&privroot->d_inode->i_mutex); |
141 | { | 137 | return xaroot; |
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); | ||
146 | } | 138 | } |
147 | 139 | ||
148 | static struct dentry *open_xa_dir(const struct inode *inode, int flags) | 140 | 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) | |||
158 | le32_to_cpu(INODE_PKEY(inode)->k_objectid), | 150 | le32_to_cpu(INODE_PKEY(inode)->k_objectid), |
159 | inode->i_generation); | 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 | dput(xaroot); | 167 | dput(xaroot); |
163 | return xadir; | 168 | return xadir; |
164 | |||
165 | } | 169 | } |
166 | 170 | ||
167 | /* The following are side effects of other operations that aren't explicitly | 171 | /* The following are side effects of other operations that aren't explicitly |
@@ -986,19 +990,33 @@ int reiserfs_lookup_privroot(struct super_block *s) | |||
986 | int reiserfs_xattr_init(struct super_block *s, int mount_flags) | 990 | int reiserfs_xattr_init(struct super_block *s, int mount_flags) |
987 | { | 991 | { |
988 | int err = 0; | 992 | int err = 0; |
993 | struct dentry *privroot = REISERFS_SB(s)->priv_root; | ||
989 | 994 | ||
990 | #ifdef CONFIG_REISERFS_FS_XATTR | 995 | #ifdef CONFIG_REISERFS_FS_XATTR |
991 | err = xattr_mount_check(s); | 996 | err = xattr_mount_check(s); |
992 | if (err) | 997 | if (err) |
993 | goto error; | 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 | mutex_lock(&s->s_root->d_inode->i_mutex); | 1001 | mutex_lock(&s->s_root->d_inode->i_mutex); |
997 | err = create_privroot(REISERFS_SB(s)->priv_root); | 1002 | err = create_privroot(REISERFS_SB(s)->priv_root); |
998 | mutex_unlock(&s->s_root->d_inode->i_mutex); | 1003 | mutex_unlock(&s->s_root->d_inode->i_mutex); |
999 | } | 1004 | } |
1000 | if (!err) | 1005 | |
1006 | if (privroot->d_inode) { | ||
1001 | s->s_xattr = reiserfs_xattr_handlers; | 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 | error: | 1021 | error: |
1004 | if (err) { | 1022 | if (err) { |
@@ -1008,11 +1026,12 @@ error: | |||
1008 | #endif | 1026 | #endif |
1009 | 1027 | ||
1010 | /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ | 1028 | /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ |
1011 | s->s_flags = s->s_flags & ~MS_POSIXACL; | ||
1012 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | 1029 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL |
1013 | if (reiserfs_posixacl(s)) | 1030 | if (reiserfs_posixacl(s)) |
1014 | s->s_flags |= MS_POSIXACL; | 1031 | s->s_flags |= MS_POSIXACL; |
1032 | else | ||
1015 | #endif | 1033 | #endif |
1034 | s->s_flags &= ~MS_POSIXACL; | ||
1016 | 1035 | ||
1017 | return err; | 1036 | return err; |
1018 | } | 1037 | } |
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 6b361d23a499..8651640868a1 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h | |||
@@ -402,7 +402,7 @@ struct reiserfs_sb_info { | |||
402 | int reserved_blocks; /* amount of blocks reserved for further allocations */ | 402 | int reserved_blocks; /* amount of blocks reserved for further allocations */ |
403 | spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */ | 403 | spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */ |
404 | struct dentry *priv_root; /* root of /.reiserfs_priv */ | 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 | int j_errno; | 406 | int j_errno; |
407 | #ifdef CONFIG_QUOTA | 407 | #ifdef CONFIG_QUOTA |
408 | char *s_qf_names[MAXQUOTAS]; | 408 | char *s_qf_names[MAXQUOTAS]; |
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index fea1a8e65bef..cdedc01036e4 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h | |||
@@ -98,7 +98,7 @@ static inline size_t reiserfs_xattr_jcreate_nblocks(struct inode *inode) | |||
98 | 98 | ||
99 | if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) { | 99 | if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) { |
100 | nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); | 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 | nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); | 102 | nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb); |
103 | } | 103 | } |
104 | 104 | ||