aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs')
-rw-r--r--fs/reiserfs/xattr.c73
1 files changed, 46 insertions, 27 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. */ 116static struct dentry *open_xa_root(struct super_block *sb, int flags)
117static 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
140static 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
148static struct dentry *open_xa_dir(const struct inode *inode, int flags) 140static 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)
986int reiserfs_xattr_init(struct super_block *s, int mount_flags) 990int 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
1003error: 1021error:
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}