diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/reiserfs/xattr.c | 92 |
1 files changed, 24 insertions, 68 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f01389fd162e..c8178b7b9212 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -54,82 +54,48 @@ | |||
| 54 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char | 54 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char |
| 55 | *prefix); | 55 | *prefix); |
| 56 | 56 | ||
| 57 | static struct dentry *create_xa_root(struct super_block *sb) | 57 | /* Returns the dentry referring to the root of the extended attribute |
| 58 | * directory tree. If it has already been retrieved, it is used. If it | ||
| 59 | * hasn't been created and the flags indicate creation is allowed, we | ||
| 60 | * attempt to create it. On error, we return a pointer-encoded error. | ||
| 61 | */ | ||
| 62 | static struct dentry *get_xa_root(struct super_block *sb, int flags) | ||
| 58 | { | 63 | { |
| 59 | struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root); | 64 | struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root); |
| 60 | struct dentry *xaroot; | 65 | struct dentry *xaroot; |
| 61 | 66 | ||
| 62 | /* This needs to be created at mount-time */ | 67 | /* This needs to be created at mount-time */ |
| 63 | if (!privroot) | 68 | if (!privroot) |
| 64 | return ERR_PTR(-EOPNOTSUPP); | 69 | return ERR_PTR(-ENODATA); |
| 65 | 70 | ||
| 66 | xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); | 71 | mutex_lock(&privroot->d_inode->i_mutex); |
| 67 | if (IS_ERR(xaroot)) { | 72 | if (REISERFS_SB(sb)->xattr_root) { |
| 73 | xaroot = dget(REISERFS_SB(sb)->xattr_root); | ||
| 68 | goto out; | 74 | goto out; |
| 69 | } else if (!xaroot->d_inode) { | ||
| 70 | int err; | ||
| 71 | mutex_lock(&privroot->d_inode->i_mutex); | ||
| 72 | err = | ||
| 73 | privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot, | ||
| 74 | 0700); | ||
| 75 | mutex_unlock(&privroot->d_inode->i_mutex); | ||
| 76 | |||
| 77 | if (err) { | ||
| 78 | dput(xaroot); | ||
| 79 | dput(privroot); | ||
| 80 | return ERR_PTR(err); | ||
| 81 | } | ||
| 82 | REISERFS_SB(sb)->xattr_root = dget(xaroot); | ||
| 83 | } | 75 | } |
| 84 | 76 | ||
| 85 | out: | ||
| 86 | dput(privroot); | ||
| 87 | return xaroot; | ||
| 88 | } | ||
| 89 | |||
| 90 | /* This will return a dentry, or error, refering to the xa root directory. | ||
| 91 | * If the xa root doesn't exist yet, the dentry will be returned without | ||
| 92 | * an associated inode. This dentry can be used with ->mkdir to create | ||
| 93 | * the xa directory. */ | ||
| 94 | static struct dentry *__get_xa_root(struct super_block *s) | ||
| 95 | { | ||
| 96 | struct dentry *privroot = dget(REISERFS_SB(s)->priv_root); | ||
| 97 | struct dentry *xaroot = NULL; | ||
| 98 | |||
| 99 | if (IS_ERR(privroot) || !privroot) | ||
| 100 | return privroot; | ||
| 101 | |||
| 102 | xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); | 77 | xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); |
| 103 | if (IS_ERR(xaroot)) { | 78 | if (IS_ERR(xaroot)) { |
| 104 | goto out; | 79 | goto out; |
| 105 | } else if (!xaroot->d_inode) { | 80 | } else if (!xaroot->d_inode) { |
| 106 | dput(xaroot); | 81 | int err = -ENODATA; |
| 107 | xaroot = NULL; | 82 | if (flags == 0 || flags & XATTR_CREATE) |
| 108 | goto out; | 83 | err = privroot->d_inode->i_op->mkdir(privroot->d_inode, |
| 84 | xaroot, 0700); | ||
| 85 | if (err) { | ||
| 86 | dput(xaroot); | ||
| 87 | xaroot = ERR_PTR(err); | ||
| 88 | goto out; | ||
| 89 | } | ||
| 109 | } | 90 | } |
| 110 | 91 | REISERFS_SB(sb)->xattr_root = dget(xaroot); | |
| 111 | REISERFS_SB(s)->xattr_root = dget(xaroot); | ||
| 112 | 92 | ||
| 113 | out: | 93 | out: |
| 94 | mutex_unlock(&privroot->d_inode->i_mutex); | ||
| 114 | dput(privroot); | 95 | dput(privroot); |
| 115 | return xaroot; | 96 | return xaroot; |
| 116 | } | 97 | } |
| 117 | 98 | ||
| 118 | /* Returns the dentry (or NULL) referring to the root of the extended | ||
| 119 | * attribute directory tree. If it has already been retrieved, it is used. | ||
| 120 | * Otherwise, we attempt to retrieve it from disk. It may also return | ||
| 121 | * a pointer-encoded error. | ||
| 122 | */ | ||
| 123 | static inline struct dentry *get_xa_root(struct super_block *s) | ||
| 124 | { | ||
| 125 | struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root); | ||
| 126 | |||
| 127 | if (!dentry) | ||
| 128 | dentry = __get_xa_root(s); | ||
| 129 | |||
| 130 | return dentry; | ||
| 131 | } | ||
| 132 | |||
| 133 | /* Opens the directory corresponding to the inode's extended attribute store. | 99 | /* Opens the directory corresponding to the inode's extended attribute store. |
| 134 | * If flags allow, the tree to the directory may be created. If creation is | 100 | * If flags allow, the tree to the directory may be created. If creation is |
| 135 | * prohibited, -ENODATA is returned. */ | 101 | * prohibited, -ENODATA is returned. */ |
| @@ -138,21 +104,11 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) | |||
| 138 | struct dentry *xaroot, *xadir; | 104 | struct dentry *xaroot, *xadir; |
| 139 | char namebuf[17]; | 105 | char namebuf[17]; |
| 140 | 106 | ||
| 141 | xaroot = get_xa_root(inode->i_sb); | 107 | xaroot = get_xa_root(inode->i_sb, flags); |
| 142 | if (IS_ERR(xaroot)) { | 108 | if (IS_ERR(xaroot)) |
| 143 | return xaroot; | 109 | return xaroot; |
| 144 | } else if (!xaroot) { | ||
| 145 | if (flags == 0 || flags & XATTR_CREATE) { | ||
| 146 | xaroot = create_xa_root(inode->i_sb); | ||
| 147 | if (IS_ERR(xaroot)) | ||
| 148 | return xaroot; | ||
| 149 | } | ||
| 150 | if (!xaroot) | ||
| 151 | return ERR_PTR(-ENODATA); | ||
| 152 | } | ||
| 153 | 110 | ||
| 154 | /* ok, we have xaroot open */ | 111 | /* ok, we have xaroot open */ |
| 155 | |||
| 156 | snprintf(namebuf, sizeof(namebuf), "%X.%X", | 112 | snprintf(namebuf, sizeof(namebuf), "%X.%X", |
| 157 | le32_to_cpu(INODE_PKEY(inode)->k_objectid), | 113 | le32_to_cpu(INODE_PKEY(inode)->k_objectid), |
| 158 | inode->i_generation); | 114 | inode->i_generation); |
| @@ -821,7 +777,7 @@ int reiserfs_delete_xattrs(struct inode *inode) | |||
| 821 | 777 | ||
| 822 | /* Leftovers besides . and .. -- that's not good. */ | 778 | /* Leftovers besides . and .. -- that's not good. */ |
| 823 | if (dir->d_inode->i_nlink <= 2) { | 779 | if (dir->d_inode->i_nlink <= 2) { |
| 824 | root = get_xa_root(inode->i_sb); | 780 | root = get_xa_root(inode->i_sb, XATTR_REPLACE); |
| 825 | reiserfs_write_lock_xattrs(inode->i_sb); | 781 | reiserfs_write_lock_xattrs(inode->i_sb); |
| 826 | err = vfs_rmdir(root->d_inode, dir); | 782 | err = vfs_rmdir(root->d_inode, dir); |
| 827 | reiserfs_write_unlock_xattrs(inode->i_sb); | 783 | reiserfs_write_unlock_xattrs(inode->i_sb); |
