diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/btrfs/xattr.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r-- | fs/btrfs/xattr.c | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 88ecbb215878..5366fe452ab0 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -44,7 +44,7 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | |||
44 | return -ENOMEM; | 44 | return -ENOMEM; |
45 | 45 | ||
46 | /* lookup the xattr by name */ | 46 | /* lookup the xattr by name */ |
47 | di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, | 47 | di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), name, |
48 | strlen(name), 0); | 48 | strlen(name), 0); |
49 | if (!di) { | 49 | if (!di) { |
50 | ret = -ENODATA; | 50 | ret = -ENODATA; |
@@ -103,7 +103,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, | |||
103 | return -ENOMEM; | 103 | return -ENOMEM; |
104 | 104 | ||
105 | /* first lets see if we already have this xattr */ | 105 | /* first lets see if we already have this xattr */ |
106 | di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name, | 106 | di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, |
107 | strlen(name), -1); | 107 | strlen(name), -1); |
108 | if (IS_ERR(di)) { | 108 | if (IS_ERR(di)) { |
109 | ret = PTR_ERR(di); | 109 | ret = PTR_ERR(di); |
@@ -120,13 +120,13 @@ static int do_setxattr(struct btrfs_trans_handle *trans, | |||
120 | 120 | ||
121 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | 121 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
122 | BUG_ON(ret); | 122 | BUG_ON(ret); |
123 | btrfs_release_path(root, path); | 123 | btrfs_release_path(path); |
124 | 124 | ||
125 | /* if we don't have a value then we are removing the xattr */ | 125 | /* if we don't have a value then we are removing the xattr */ |
126 | if (!value) | 126 | if (!value) |
127 | goto out; | 127 | goto out; |
128 | } else { | 128 | } else { |
129 | btrfs_release_path(root, path); | 129 | btrfs_release_path(path); |
130 | 130 | ||
131 | if (flags & XATTR_REPLACE) { | 131 | if (flags & XATTR_REPLACE) { |
132 | /* we couldn't find the attr to replace */ | 132 | /* we couldn't find the attr to replace */ |
@@ -136,7 +136,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, | |||
136 | } | 136 | } |
137 | 137 | ||
138 | /* ok we have to create a completely new xattr */ | 138 | /* ok we have to create a completely new xattr */ |
139 | ret = btrfs_insert_xattr_item(trans, root, path, inode->i_ino, | 139 | ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), |
140 | name, name_len, value, size); | 140 | name, name_len, value, size); |
141 | BUG_ON(ret); | 141 | BUG_ON(ret); |
142 | out: | 142 | out: |
@@ -158,8 +158,6 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans, | |||
158 | if (IS_ERR(trans)) | 158 | if (IS_ERR(trans)) |
159 | return PTR_ERR(trans); | 159 | return PTR_ERR(trans); |
160 | 160 | ||
161 | btrfs_set_trans_block_group(trans, inode); | ||
162 | |||
163 | ret = do_setxattr(trans, inode, name, value, size, flags); | 161 | ret = do_setxattr(trans, inode, name, value, size, flags); |
164 | if (ret) | 162 | if (ret) |
165 | goto out; | 163 | goto out; |
@@ -178,21 +176,19 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
178 | struct inode *inode = dentry->d_inode; | 176 | struct inode *inode = dentry->d_inode; |
179 | struct btrfs_root *root = BTRFS_I(inode)->root; | 177 | struct btrfs_root *root = BTRFS_I(inode)->root; |
180 | struct btrfs_path *path; | 178 | struct btrfs_path *path; |
181 | struct btrfs_item *item; | ||
182 | struct extent_buffer *leaf; | 179 | struct extent_buffer *leaf; |
183 | struct btrfs_dir_item *di; | 180 | struct btrfs_dir_item *di; |
184 | int ret = 0, slot, advance; | 181 | int ret = 0, slot; |
185 | size_t total_size = 0, size_left = size; | 182 | size_t total_size = 0, size_left = size; |
186 | unsigned long name_ptr; | 183 | unsigned long name_ptr; |
187 | size_t name_len; | 184 | size_t name_len; |
188 | u32 nritems; | ||
189 | 185 | ||
190 | /* | 186 | /* |
191 | * ok we want all objects associated with this id. | 187 | * ok we want all objects associated with this id. |
192 | * NOTE: we set key.offset = 0; because we want to start with the | 188 | * NOTE: we set key.offset = 0; because we want to start with the |
193 | * first xattr that we find and walk forward | 189 | * first xattr that we find and walk forward |
194 | */ | 190 | */ |
195 | key.objectid = inode->i_ino; | 191 | key.objectid = btrfs_ino(inode); |
196 | btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); | 192 | btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); |
197 | key.offset = 0; | 193 | key.offset = 0; |
198 | 194 | ||
@@ -205,36 +201,25 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
205 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 201 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
206 | if (ret < 0) | 202 | if (ret < 0) |
207 | goto err; | 203 | goto err; |
208 | advance = 0; | 204 | |
209 | while (1) { | 205 | while (1) { |
210 | leaf = path->nodes[0]; | 206 | leaf = path->nodes[0]; |
211 | nritems = btrfs_header_nritems(leaf); | ||
212 | slot = path->slots[0]; | 207 | slot = path->slots[0]; |
213 | 208 | ||
214 | /* this is where we start walking through the path */ | 209 | /* this is where we start walking through the path */ |
215 | if (advance || slot >= nritems) { | 210 | if (slot >= btrfs_header_nritems(leaf)) { |
216 | /* | 211 | /* |
217 | * if we've reached the last slot in this leaf we need | 212 | * if we've reached the last slot in this leaf we need |
218 | * to go to the next leaf and reset everything | 213 | * to go to the next leaf and reset everything |
219 | */ | 214 | */ |
220 | if (slot >= nritems-1) { | 215 | ret = btrfs_next_leaf(root, path); |
221 | ret = btrfs_next_leaf(root, path); | 216 | if (ret < 0) |
222 | if (ret) | 217 | goto err; |
223 | break; | 218 | else if (ret > 0) |
224 | leaf = path->nodes[0]; | 219 | break; |
225 | nritems = btrfs_header_nritems(leaf); | 220 | continue; |
226 | slot = path->slots[0]; | ||
227 | } else { | ||
228 | /* | ||
229 | * just walking through the slots on this leaf | ||
230 | */ | ||
231 | slot++; | ||
232 | path->slots[0]++; | ||
233 | } | ||
234 | } | 221 | } |
235 | advance = 1; | ||
236 | 222 | ||
237 | item = btrfs_item_nr(leaf, slot); | ||
238 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 223 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
239 | 224 | ||
240 | /* check to make sure this item is what we want */ | 225 | /* check to make sure this item is what we want */ |
@@ -244,13 +229,15 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
244 | break; | 229 | break; |
245 | 230 | ||
246 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); | 231 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); |
232 | if (verify_dir_item(root, leaf, di)) | ||
233 | continue; | ||
247 | 234 | ||
248 | name_len = btrfs_dir_name_len(leaf, di); | 235 | name_len = btrfs_dir_name_len(leaf, di); |
249 | total_size += name_len + 1; | 236 | total_size += name_len + 1; |
250 | 237 | ||
251 | /* we are just looking for how big our buffer needs to be */ | 238 | /* we are just looking for how big our buffer needs to be */ |
252 | if (!size) | 239 | if (!size) |
253 | continue; | 240 | goto next; |
254 | 241 | ||
255 | if (!buffer || (name_len + 1) > size_left) { | 242 | if (!buffer || (name_len + 1) > size_left) { |
256 | ret = -ERANGE; | 243 | ret = -ERANGE; |
@@ -263,6 +250,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
263 | 250 | ||
264 | size_left -= name_len + 1; | 251 | size_left -= name_len + 1; |
265 | buffer += name_len + 1; | 252 | buffer += name_len + 1; |
253 | next: | ||
254 | path->slots[0]++; | ||
266 | } | 255 | } |
267 | ret = total_size; | 256 | ret = total_size; |
268 | 257 | ||
@@ -318,6 +307,15 @@ ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, | |||
318 | int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 307 | int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
319 | size_t size, int flags) | 308 | size_t size, int flags) |
320 | { | 309 | { |
310 | struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root; | ||
311 | |||
312 | /* | ||
313 | * The permission on security.* and system.* is not checked | ||
314 | * in permission(). | ||
315 | */ | ||
316 | if (btrfs_root_readonly(root)) | ||
317 | return -EROFS; | ||
318 | |||
321 | /* | 319 | /* |
322 | * If this is a request for a synthetic attribute in the system.* | 320 | * If this is a request for a synthetic attribute in the system.* |
323 | * namespace use the generic infrastructure to resolve a handler | 321 | * namespace use the generic infrastructure to resolve a handler |
@@ -338,6 +336,15 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
338 | 336 | ||
339 | int btrfs_removexattr(struct dentry *dentry, const char *name) | 337 | int btrfs_removexattr(struct dentry *dentry, const char *name) |
340 | { | 338 | { |
339 | struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root; | ||
340 | |||
341 | /* | ||
342 | * The permission on security.* and system.* is not checked | ||
343 | * in permission(). | ||
344 | */ | ||
345 | if (btrfs_root_readonly(root)) | ||
346 | return -EROFS; | ||
347 | |||
341 | /* | 348 | /* |
342 | * If this is a request for a synthetic attribute in the system.* | 349 | * If this is a request for a synthetic attribute in the system.* |
343 | * namespace use the generic infrastructure to resolve a handler | 350 | * namespace use the generic infrastructure to resolve a handler |
@@ -354,7 +361,8 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) | |||
354 | } | 361 | } |
355 | 362 | ||
356 | int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, | 363 | int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, |
357 | struct inode *inode, struct inode *dir) | 364 | struct inode *inode, struct inode *dir, |
365 | const struct qstr *qstr) | ||
358 | { | 366 | { |
359 | int err; | 367 | int err; |
360 | size_t len; | 368 | size_t len; |
@@ -362,7 +370,8 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, | |||
362 | char *suffix; | 370 | char *suffix; |
363 | char *name; | 371 | char *name; |
364 | 372 | ||
365 | err = security_inode_init_security(inode, dir, &suffix, &value, &len); | 373 | err = security_inode_init_security(inode, dir, qstr, &suffix, &value, |
374 | &len); | ||
366 | if (err) { | 375 | if (err) { |
367 | if (err == -EOPNOTSUPP) | 376 | if (err == -EOPNOTSUPP) |
368 | return 0; | 377 | return 0; |