diff options
Diffstat (limited to 'fs/reiserfs/xattr.c')
| -rw-r--r-- | fs/reiserfs/xattr.c | 181 |
1 files changed, 91 insertions, 90 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f83f52bae390..2237e10c7c7c 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. */ | 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 | 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 | |||
| 145 | static 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 | ||
| 153 | 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) |
| @@ -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); |
| 374 | out: | 371 | out: |
| 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); |
| 452 | out_dput: | 449 | out_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 | ||
| 924 | static int xattr_mount_check(struct super_block *s) | 925 | static int xattr_mount_check(struct super_block *s) |
| @@ -950,11 +951,9 @@ static int | |||
| 950 | xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) | 951 | xattr_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 | ||
| 966 | int 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 */ |
| 970 | int reiserfs_xattr_init(struct super_block *s, int mount_flags) | 990 | int 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 | ||
| 1021 | error: | 1021 | error: |
| 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 | } |
