aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r--fs/btrfs/xattr.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 6c68d6356197..145d2b89e62d 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -249,7 +249,7 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans,
249 goto out; 249 goto out;
250 250
251 inode_inc_iversion(inode); 251 inode_inc_iversion(inode);
252 inode->i_ctime = CURRENT_TIME; 252 inode->i_ctime = current_fs_time(inode->i_sb);
253 set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); 253 set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags);
254 ret = btrfs_update_inode(trans, root, inode); 254 ret = btrfs_update_inode(trans, root, inode);
255 BUG_ON(ret); 255 BUG_ON(ret);
@@ -260,16 +260,12 @@ out:
260 260
261ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) 261ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
262{ 262{
263 struct btrfs_key key, found_key; 263 struct btrfs_key key;
264 struct inode *inode = d_inode(dentry); 264 struct inode *inode = d_inode(dentry);
265 struct btrfs_root *root = BTRFS_I(inode)->root; 265 struct btrfs_root *root = BTRFS_I(inode)->root;
266 struct btrfs_path *path; 266 struct btrfs_path *path;
267 struct extent_buffer *leaf; 267 int ret = 0;
268 struct btrfs_dir_item *di;
269 int ret = 0, slot;
270 size_t total_size = 0, size_left = size; 268 size_t total_size = 0, size_left = size;
271 unsigned long name_ptr;
272 size_t name_len;
273 269
274 /* 270 /*
275 * ok we want all objects associated with this id. 271 * ok we want all objects associated with this id.
@@ -291,6 +287,13 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
291 goto err; 287 goto err;
292 288
293 while (1) { 289 while (1) {
290 struct extent_buffer *leaf;
291 int slot;
292 struct btrfs_dir_item *di;
293 struct btrfs_key found_key;
294 u32 item_size;
295 u32 cur;
296
294 leaf = path->nodes[0]; 297 leaf = path->nodes[0];
295 slot = path->slots[0]; 298 slot = path->slots[0];
296 299
@@ -316,31 +319,45 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
316 if (found_key.type > BTRFS_XATTR_ITEM_KEY) 319 if (found_key.type > BTRFS_XATTR_ITEM_KEY)
317 break; 320 break;
318 if (found_key.type < BTRFS_XATTR_ITEM_KEY) 321 if (found_key.type < BTRFS_XATTR_ITEM_KEY)
319 goto next; 322 goto next_item;
320 323
321 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 324 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
322 if (verify_dir_item(root, leaf, di)) 325 item_size = btrfs_item_size_nr(leaf, slot);
323 goto next; 326 cur = 0;
324 327 while (cur < item_size) {
325 name_len = btrfs_dir_name_len(leaf, di); 328 u16 name_len = btrfs_dir_name_len(leaf, di);
326 total_size += name_len + 1; 329 u16 data_len = btrfs_dir_data_len(leaf, di);
330 u32 this_len = sizeof(*di) + name_len + data_len;
331 unsigned long name_ptr = (unsigned long)(di + 1);
332
333 if (verify_dir_item(root, leaf, di)) {
334 ret = -EIO;
335 goto err;
336 }
327 337
328 /* we are just looking for how big our buffer needs to be */ 338 total_size += name_len + 1;
329 if (!size) 339 /*
330 goto next; 340 * We are just looking for how big our buffer needs to
341 * be.
342 */
343 if (!size)
344 goto next;
331 345
332 if (!buffer || (name_len + 1) > size_left) { 346 if (!buffer || (name_len + 1) > size_left) {
333 ret = -ERANGE; 347 ret = -ERANGE;
334 goto err; 348 goto err;
335 } 349 }
336 350
337 name_ptr = (unsigned long)(di + 1); 351 read_extent_buffer(leaf, buffer, name_ptr, name_len);
338 read_extent_buffer(leaf, buffer, name_ptr, name_len); 352 buffer[name_len] = '\0';
339 buffer[name_len] = '\0';
340 353
341 size_left -= name_len + 1; 354 size_left -= name_len + 1;
342 buffer += name_len + 1; 355 buffer += name_len + 1;
343next: 356next:
357 cur += this_len;
358 di = (struct btrfs_dir_item *)((char *)di + this_len);
359 }
360next_item:
344 path->slots[0]++; 361 path->slots[0]++;
345 } 362 }
346 ret = total_size; 363 ret = total_size;