aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r--fs/reiserfs/xattr.c181
1 files changed, 91 insertions, 90 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index f83f52bae39..2237e10c7c7 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -113,41 +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 dentry = lookup_one_len(name, parent, strlen(name)); 123 mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);
124 if (IS_ERR(dentry))
125 return dentry;
126 else if (!dentry->d_inode) {
127 int err = -ENODATA;
128
129 if (xattr_may_create(flags)) {
130 mutex_lock_nested(&parent->d_inode->i_mutex,
131 I_MUTEX_XATTR);
132 err = xattr_mkdir(parent->d_inode, dentry, 0700);
133 mutex_unlock(&parent->d_inode->i_mutex);
134 }
135 124
125 xaroot = dget(REISERFS_SB(sb)->xattr_root);
126 if (!xaroot->d_inode) {
127 int err = -ENODATA;
128 if (xattr_may_create(flags))
129 err = xattr_mkdir(privroot->d_inode, xaroot, 0700);
136 if (err) { 130 if (err) {
137 dput(dentry); 131 dput(xaroot);
138 dentry = ERR_PTR(err); 132 xaroot = ERR_PTR(err);
139 } 133 }
140 } 134 }
141 135
142 return dentry; 136 mutex_unlock(&privroot->d_inode->i_mutex);
143} 137 return xaroot;
144
145static struct dentry *open_xa_root(struct super_block *sb, int flags)
146{
147 struct dentry *privroot = REISERFS_SB(sb)->priv_root;
148 if (!privroot)
149 return ERR_PTR(-ENODATA);
150 return lookup_or_create_dir(privroot, XAROOT_NAME, flags);
151} 138}
152 139
153static struct dentry *open_xa_dir(const struct inode *inode, int flags) 140static struct dentry *open_xa_dir(const struct inode *inode, int flags)
@@ -163,10 +150,22 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
163 le32_to_cpu(INODE_PKEY(inode)->k_objectid), 150 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
164 inode->i_generation); 151 inode->i_generation);
165 152
166 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);
167 dput(xaroot); 167 dput(xaroot);
168 return xadir; 168 return xadir;
169
170} 169}
171 170
172/* 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
@@ -184,6 +183,7 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset,
184{ 183{
185 struct reiserfs_dentry_buf *dbuf = buf; 184 struct reiserfs_dentry_buf *dbuf = buf;
186 struct dentry *dentry; 185 struct dentry *dentry;
186 WARN_ON_ONCE(!mutex_is_locked(&dbuf->xadir->d_inode->i_mutex));
187 187
188 if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) 188 if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
189 return -ENOSPC; 189 return -ENOSPC;
@@ -349,6 +349,7 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
349 if (IS_ERR(xadir)) 349 if (IS_ERR(xadir))
350 return ERR_CAST(xadir); 350 return ERR_CAST(xadir);
351 351
352 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
352 xafile = lookup_one_len(name, xadir, strlen(name)); 353 xafile = lookup_one_len(name, xadir, strlen(name));
353 if (IS_ERR(xafile)) { 354 if (IS_ERR(xafile)) {
354 err = PTR_ERR(xafile); 355 err = PTR_ERR(xafile);
@@ -360,18 +361,15 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
360 361
361 if (!xafile->d_inode) { 362 if (!xafile->d_inode) {
362 err = -ENODATA; 363 err = -ENODATA;
363 if (xattr_may_create(flags)) { 364 if (xattr_may_create(flags))
364 mutex_lock_nested(&xadir->d_inode->i_mutex,
365 I_MUTEX_XATTR);
366 err = xattr_create(xadir->d_inode, xafile, 365 err = xattr_create(xadir->d_inode, xafile,
367 0700|S_IFREG); 366 0700|S_IFREG);
368 mutex_unlock(&xadir->d_inode->i_mutex);
369 }
370 } 367 }
371 368
372 if (err) 369 if (err)
373 dput(xafile); 370 dput(xafile);
374out: 371out:
372 mutex_unlock(&xadir->d_inode->i_mutex);
375 dput(xadir); 373 dput(xadir);
376 if (err) 374 if (err)
377 return ERR_PTR(err); 375 return ERR_PTR(err);
@@ -435,6 +433,7 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
435 if (IS_ERR(xadir)) 433 if (IS_ERR(xadir))
436 return PTR_ERR(xadir); 434 return PTR_ERR(xadir);
437 435
436 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
438 dentry = lookup_one_len(name, xadir, strlen(name)); 437 dentry = lookup_one_len(name, xadir, strlen(name));
439 if (IS_ERR(dentry)) { 438 if (IS_ERR(dentry)) {
440 err = PTR_ERR(dentry); 439 err = PTR_ERR(dentry);
@@ -442,14 +441,13 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
442 } 441 }
443 442
444 if (dentry->d_inode) { 443 if (dentry->d_inode) {
445 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
446 err = xattr_unlink(xadir->d_inode, dentry); 444 err = xattr_unlink(xadir->d_inode, dentry);
447 mutex_unlock(&xadir->d_inode->i_mutex);
448 update_ctime(inode); 445 update_ctime(inode);
449 } 446 }
450 447
451 dput(dentry); 448 dput(dentry);
452out_dput: 449out_dput:
450 mutex_unlock(&xadir->d_inode->i_mutex);
453 dput(xadir); 451 dput(xadir);
454 return err; 452 return err;
455} 453}
@@ -843,7 +841,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
843 if (!dentry->d_inode) 841 if (!dentry->d_inode)
844 return -EINVAL; 842 return -EINVAL;
845 843
846 if (!reiserfs_xattrs(dentry->d_sb) || 844 if (!dentry->d_sb->s_xattr ||
847 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) 845 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
848 return -EOPNOTSUPP; 846 return -EOPNOTSUPP;
849 847
@@ -906,19 +904,22 @@ static int create_privroot(struct dentry *dentry)
906{ 904{
907 int err; 905 int err;
908 struct inode *inode = dentry->d_parent->d_inode; 906 struct inode *inode = dentry->d_parent->d_inode;
909 mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); 907 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
908
910 err = xattr_mkdir(inode, dentry, 0700); 909 err = xattr_mkdir(inode, dentry, 0700);
911 mutex_unlock(&inode->i_mutex); 910 if (err || !dentry->d_inode) {
912 if (err) { 911 reiserfs_warning(dentry->d_sb, "jdm-20006",
913 dput(dentry); 912 "xattrs/ACLs enabled and couldn't "
914 dentry = NULL; 913 "find/create .reiserfs_priv. "
914 "Failing mount.");
915 return -EOPNOTSUPP;
915 } 916 }
916 917
917 if (dentry && dentry->d_inode) 918 dentry->d_inode->i_flags |= S_PRIVATE;
918 reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " 919 reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
919 "storage.\n", PRIVROOT_NAME); 920 "storage.\n", PRIVROOT_NAME);
920 921
921 return err; 922 return 0;
922} 923}
923 924
924static int xattr_mount_check(struct super_block *s) 925static int xattr_mount_check(struct super_block *s)
@@ -950,11 +951,9 @@ static int
950xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) 951xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
951{ 952{
952 struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; 953 struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
953 if (name->len == priv_root->d_name.len && 954 if (container_of(q1, struct dentry, d_name) == priv_root)
954 name->hash == priv_root->d_name.hash &&
955 !memcmp(name->name, priv_root->d_name.name, name->len)) {
956 return -ENOENT; 955 return -ENOENT;
957 } else if (q1->len == name->len && 956 if (q1->len == name->len &&
958 !memcmp(q1->name, name->name, name->len)) 957 !memcmp(q1->name, name->name, name->len))
959 return 0; 958 return 0;
960 return 1; 959 return 1;
@@ -964,59 +963,60 @@ static const struct dentry_operations xattr_lookup_poison_ops = {
964 .d_compare = xattr_lookup_poison, 963 .d_compare = xattr_lookup_poison,
965}; 964};
966 965
966int reiserfs_lookup_privroot(struct super_block *s)
967{
968 struct dentry *dentry;
969 int err = 0;
970
971 /* If we don't have the privroot located yet - go find it */
972 mutex_lock(&s->s_root->d_inode->i_mutex);
973 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
974 strlen(PRIVROOT_NAME));
975 if (!IS_ERR(dentry)) {
976 REISERFS_SB(s)->priv_root = dentry;
977 s->s_root->d_op = &xattr_lookup_poison_ops;
978 if (dentry->d_inode)
979 dentry->d_inode->i_flags |= S_PRIVATE;
980 } else
981 err = PTR_ERR(dentry);
982 mutex_unlock(&s->s_root->d_inode->i_mutex);
983
984 return err;
985}
986
967/* We need to take a copy of the mount flags since things like 987/* We need to take a copy of the mount flags since things like
968 * MS_RDONLY don't get set until *after* we're called. 988 * MS_RDONLY don't get set until *after* we're called.
969 * mount_flags != mount_options */ 989 * mount_flags != mount_options */
970int reiserfs_xattr_init(struct super_block *s, int mount_flags) 990int reiserfs_xattr_init(struct super_block *s, int mount_flags)
971{ 991{
972 int err = 0; 992 int err = 0;
993 struct dentry *privroot = REISERFS_SB(s)->priv_root;
973 994
974#ifdef CONFIG_REISERFS_FS_XATTR 995#ifdef CONFIG_REISERFS_FS_XATTR
975 err = xattr_mount_check(s); 996 err = xattr_mount_check(s);
976 if (err) 997 if (err)
977 goto error; 998 goto error;
978#endif
979 999
980 /* If we don't have the privroot located yet - go find it */ 1000 if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
981 if (!REISERFS_SB(s)->priv_root) { 1001 mutex_lock(&s->s_root->d_inode->i_mutex);
982 struct dentry *dentry; 1002 err = create_privroot(REISERFS_SB(s)->priv_root);
983 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, 1003 mutex_unlock(&s->s_root->d_inode->i_mutex);
984 strlen(PRIVROOT_NAME));
985 if (!IS_ERR(dentry)) {
986#ifdef CONFIG_REISERFS_FS_XATTR
987 if (!(mount_flags & MS_RDONLY) && !dentry->d_inode)
988 err = create_privroot(dentry);
989#endif
990 if (!dentry->d_inode) {
991 dput(dentry);
992 dentry = NULL;
993 }
994 } else
995 err = PTR_ERR(dentry);
996
997 if (!err && dentry) {
998 s->s_root->d_op = &xattr_lookup_poison_ops;
999 dentry->d_inode->i_flags |= S_PRIVATE;
1000 REISERFS_SB(s)->priv_root = dentry;
1001#ifdef CONFIG_REISERFS_FS_XATTR
1002 /* xattrs are unavailable */
1003 } else if (!(mount_flags & MS_RDONLY)) {
1004 /* If we're read-only it just means that the dir
1005 * hasn't been created. Not an error -- just no
1006 * xattrs on the fs. We'll check again if we
1007 * go read-write */
1008 reiserfs_warning(s, "jdm-20006",
1009 "xattrs/ACLs enabled and couldn't "
1010 "find/create .reiserfs_priv. "
1011 "Failing mount.");
1012 err = -EOPNOTSUPP;
1013#endif
1014 }
1015 } 1004 }
1016 1005
1017#ifdef CONFIG_REISERFS_FS_XATTR 1006 if (privroot->d_inode) {
1018 if (!err)
1019 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 }
1020 1020
1021error: 1021error:
1022 if (err) { 1022 if (err) {
@@ -1026,11 +1026,12 @@ error:
1026#endif 1026#endif
1027 1027
1028 /* 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. */
1029 s->s_flags = s->s_flags & ~MS_POSIXACL;
1030#ifdef CONFIG_REISERFS_FS_POSIX_ACL 1029#ifdef CONFIG_REISERFS_FS_POSIX_ACL
1031 if (reiserfs_posixacl(s)) 1030 if (reiserfs_posixacl(s))
1032 s->s_flags |= MS_POSIXACL; 1031 s->s_flags |= MS_POSIXACL;
1032 else
1033#endif 1033#endif
1034 s->s_flags &= ~MS_POSIXACL;
1034 1035
1035 return err; 1036 return err;
1036} 1037}