aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c80
-rw-r--r--fs/btrfs/ctree.h13
-rw-r--r--fs/btrfs/struct-funcs.c53
3 files changed, 116 insertions, 30 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 74c03fb0ca1..8af24da983b 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2333,6 +2333,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
2333{ 2333{
2334 struct extent_buffer *left = path->nodes[0]; 2334 struct extent_buffer *left = path->nodes[0];
2335 struct extent_buffer *upper = path->nodes[1]; 2335 struct extent_buffer *upper = path->nodes[1];
2336 struct btrfs_map_token token;
2336 struct btrfs_disk_key disk_key; 2337 struct btrfs_disk_key disk_key;
2337 int slot; 2338 int slot;
2338 u32 i; 2339 u32 i;
@@ -2344,6 +2345,8 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
2344 u32 data_end; 2345 u32 data_end;
2345 u32 this_item_size; 2346 u32 this_item_size;
2346 2347
2348 btrfs_init_map_token(&token);
2349
2347 if (empty) 2350 if (empty)
2348 nr = 0; 2351 nr = 0;
2349 else 2352 else
@@ -2421,8 +2424,8 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
2421 push_space = BTRFS_LEAF_DATA_SIZE(root); 2424 push_space = BTRFS_LEAF_DATA_SIZE(root);
2422 for (i = 0; i < right_nritems; i++) { 2425 for (i = 0; i < right_nritems; i++) {
2423 item = btrfs_item_nr(right, i); 2426 item = btrfs_item_nr(right, i);
2424 push_space -= btrfs_item_size(right, item); 2427 push_space -= btrfs_token_item_size(right, item, &token);
2425 btrfs_set_item_offset(right, item, push_space); 2428 btrfs_set_token_item_offset(right, item, push_space, &token);
2426 } 2429 }
2427 2430
2428 left_nritems -= push_items; 2431 left_nritems -= push_items;
@@ -2553,6 +2556,9 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
2553 int wret; 2556 int wret;
2554 u32 this_item_size; 2557 u32 this_item_size;
2555 u32 old_left_item_size; 2558 u32 old_left_item_size;
2559 struct btrfs_map_token token;
2560
2561 btrfs_init_map_token(&token);
2556 2562
2557 if (empty) 2563 if (empty)
2558 nr = min(right_nritems, max_slot); 2564 nr = min(right_nritems, max_slot);
@@ -2613,9 +2619,10 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
2613 2619
2614 item = btrfs_item_nr(left, i); 2620 item = btrfs_item_nr(left, i);
2615 2621
2616 ioff = btrfs_item_offset(left, item); 2622 ioff = btrfs_token_item_offset(left, item, &token);
2617 btrfs_set_item_offset(left, item, 2623 btrfs_set_token_item_offset(left, item,
2618 ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size)); 2624 ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size),
2625 &token);
2619 } 2626 }
2620 btrfs_set_header_nritems(left, old_left_nritems + push_items); 2627 btrfs_set_header_nritems(left, old_left_nritems + push_items);
2621 2628
@@ -2645,8 +2652,9 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
2645 for (i = 0; i < right_nritems; i++) { 2652 for (i = 0; i < right_nritems; i++) {
2646 item = btrfs_item_nr(right, i); 2653 item = btrfs_item_nr(right, i);
2647 2654
2648 push_space = push_space - btrfs_item_size(right, item); 2655 push_space = push_space - btrfs_token_item_size(right,
2649 btrfs_set_item_offset(right, item, push_space); 2656 item, &token);
2657 btrfs_set_token_item_offset(right, item, push_space, &token);
2650 } 2658 }
2651 2659
2652 btrfs_mark_buffer_dirty(left); 2660 btrfs_mark_buffer_dirty(left);
@@ -2767,6 +2775,9 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
2767 int ret = 0; 2775 int ret = 0;
2768 int wret; 2776 int wret;
2769 struct btrfs_disk_key disk_key; 2777 struct btrfs_disk_key disk_key;
2778 struct btrfs_map_token token;
2779
2780 btrfs_init_map_token(&token);
2770 2781
2771 nritems = nritems - mid; 2782 nritems = nritems - mid;
2772 btrfs_set_header_nritems(right, nritems); 2783 btrfs_set_header_nritems(right, nritems);
@@ -2788,8 +2799,9 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
2788 struct btrfs_item *item = btrfs_item_nr(right, i); 2799 struct btrfs_item *item = btrfs_item_nr(right, i);
2789 u32 ioff; 2800 u32 ioff;
2790 2801
2791 ioff = btrfs_item_offset(right, item); 2802 ioff = btrfs_token_item_offset(right, item, &token);
2792 btrfs_set_item_offset(right, item, ioff + rt_data_off); 2803 btrfs_set_token_item_offset(right, item,
2804 ioff + rt_data_off, &token);
2793 } 2805 }
2794 2806
2795 btrfs_set_header_nritems(l, mid); 2807 btrfs_set_header_nritems(l, mid);
@@ -3284,6 +3296,9 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
3284 unsigned int old_size; 3296 unsigned int old_size;
3285 unsigned int size_diff; 3297 unsigned int size_diff;
3286 int i; 3298 int i;
3299 struct btrfs_map_token token;
3300
3301 btrfs_init_map_token(&token);
3287 3302
3288 leaf = path->nodes[0]; 3303 leaf = path->nodes[0];
3289 slot = path->slots[0]; 3304 slot = path->slots[0];
@@ -3310,8 +3325,9 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
3310 u32 ioff; 3325 u32 ioff;
3311 item = btrfs_item_nr(leaf, i); 3326 item = btrfs_item_nr(leaf, i);
3312 3327
3313 ioff = btrfs_item_offset(leaf, item); 3328 ioff = btrfs_token_item_offset(leaf, item, &token);
3314 btrfs_set_item_offset(leaf, item, ioff + size_diff); 3329 btrfs_set_token_item_offset(leaf, item,
3330 ioff + size_diff, &token);
3315 } 3331 }
3316 3332
3317 /* shift the data */ 3333 /* shift the data */
@@ -3381,6 +3397,9 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
3381 unsigned int old_data; 3397 unsigned int old_data;
3382 unsigned int old_size; 3398 unsigned int old_size;
3383 int i; 3399 int i;
3400 struct btrfs_map_token token;
3401
3402 btrfs_init_map_token(&token);
3384 3403
3385 leaf = path->nodes[0]; 3404 leaf = path->nodes[0];
3386 3405
@@ -3410,8 +3429,9 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
3410 u32 ioff; 3429 u32 ioff;
3411 item = btrfs_item_nr(leaf, i); 3430 item = btrfs_item_nr(leaf, i);
3412 3431
3413 ioff = btrfs_item_offset(leaf, item); 3432 ioff = btrfs_token_item_offset(leaf, item, &token);
3414 btrfs_set_item_offset(leaf, item, ioff - data_size); 3433 btrfs_set_token_item_offset(leaf, item,
3434 ioff - data_size, &token);
3415 } 3435 }
3416 3436
3417 /* shift the data */ 3437 /* shift the data */
@@ -3454,6 +3474,9 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
3454 unsigned int data_end; 3474 unsigned int data_end;
3455 struct btrfs_disk_key disk_key; 3475 struct btrfs_disk_key disk_key;
3456 struct btrfs_key found_key; 3476 struct btrfs_key found_key;
3477 struct btrfs_map_token token;
3478
3479 btrfs_init_map_token(&token);
3457 3480
3458 for (i = 0; i < nr; i++) { 3481 for (i = 0; i < nr; i++) {
3459 if (total_size + data_size[i] + sizeof(struct btrfs_item) > 3482 if (total_size + data_size[i] + sizeof(struct btrfs_item) >
@@ -3519,8 +3542,9 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
3519 u32 ioff; 3542 u32 ioff;
3520 3543
3521 item = btrfs_item_nr(leaf, i); 3544 item = btrfs_item_nr(leaf, i);
3522 ioff = btrfs_item_offset(leaf, item); 3545 ioff = btrfs_token_item_offset(leaf, item, &token);
3523 btrfs_set_item_offset(leaf, item, ioff - total_data); 3546 btrfs_set_token_item_offset(leaf, item,
3547 ioff - total_data, &token);
3524 } 3548 }
3525 /* shift the items */ 3549 /* shift the items */
3526 memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr), 3550 memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr),
@@ -3547,9 +3571,10 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
3547 btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); 3571 btrfs_cpu_key_to_disk(&disk_key, cpu_key + i);
3548 btrfs_set_item_key(leaf, &disk_key, slot + i); 3572 btrfs_set_item_key(leaf, &disk_key, slot + i);
3549 item = btrfs_item_nr(leaf, slot + i); 3573 item = btrfs_item_nr(leaf, slot + i);
3550 btrfs_set_item_offset(leaf, item, data_end - data_size[i]); 3574 btrfs_set_token_item_offset(leaf, item,
3575 data_end - data_size[i], &token);
3551 data_end -= data_size[i]; 3576 data_end -= data_size[i];
3552 btrfs_set_item_size(leaf, item, data_size[i]); 3577 btrfs_set_token_item_size(leaf, item, data_size[i], &token);
3553 } 3578 }
3554 btrfs_set_header_nritems(leaf, nritems + nr); 3579 btrfs_set_header_nritems(leaf, nritems + nr);
3555 btrfs_mark_buffer_dirty(leaf); 3580 btrfs_mark_buffer_dirty(leaf);
@@ -3588,6 +3613,9 @@ int setup_items_for_insert(struct btrfs_trans_handle *trans,
3588 int ret; 3613 int ret;
3589 struct extent_buffer *leaf; 3614 struct extent_buffer *leaf;
3590 int slot; 3615 int slot;
3616 struct btrfs_map_token token;
3617
3618 btrfs_init_map_token(&token);
3591 3619
3592 leaf = path->nodes[0]; 3620 leaf = path->nodes[0];
3593 slot = path->slots[0]; 3621 slot = path->slots[0];
@@ -3619,8 +3647,9 @@ int setup_items_for_insert(struct btrfs_trans_handle *trans,
3619 u32 ioff; 3647 u32 ioff;
3620 3648
3621 item = btrfs_item_nr(leaf, i); 3649 item = btrfs_item_nr(leaf, i);
3622 ioff = btrfs_item_offset(leaf, item); 3650 ioff = btrfs_token_item_offset(leaf, item, &token);
3623 btrfs_set_item_offset(leaf, item, ioff - total_data); 3651 btrfs_set_token_item_offset(leaf, item,
3652 ioff - total_data, &token);
3624 } 3653 }
3625 /* shift the items */ 3654 /* shift the items */
3626 memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr), 3655 memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr),
@@ -3639,9 +3668,10 @@ int setup_items_for_insert(struct btrfs_trans_handle *trans,
3639 btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); 3668 btrfs_cpu_key_to_disk(&disk_key, cpu_key + i);
3640 btrfs_set_item_key(leaf, &disk_key, slot + i); 3669 btrfs_set_item_key(leaf, &disk_key, slot + i);
3641 item = btrfs_item_nr(leaf, slot + i); 3670 item = btrfs_item_nr(leaf, slot + i);
3642 btrfs_set_item_offset(leaf, item, data_end - data_size[i]); 3671 btrfs_set_token_item_offset(leaf, item,
3672 data_end - data_size[i], &token);
3643 data_end -= data_size[i]; 3673 data_end -= data_size[i];
3644 btrfs_set_item_size(leaf, item, data_size[i]); 3674 btrfs_set_token_item_size(leaf, item, data_size[i], &token);
3645 } 3675 }
3646 3676
3647 btrfs_set_header_nritems(leaf, nritems + nr); 3677 btrfs_set_header_nritems(leaf, nritems + nr);
@@ -3814,6 +3844,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
3814 int wret; 3844 int wret;
3815 int i; 3845 int i;
3816 u32 nritems; 3846 u32 nritems;
3847 struct btrfs_map_token token;
3848
3849 btrfs_init_map_token(&token);
3817 3850
3818 leaf = path->nodes[0]; 3851 leaf = path->nodes[0];
3819 last_off = btrfs_item_offset_nr(leaf, slot + nr - 1); 3852 last_off = btrfs_item_offset_nr(leaf, slot + nr - 1);
@@ -3835,8 +3868,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
3835 u32 ioff; 3868 u32 ioff;
3836 3869
3837 item = btrfs_item_nr(leaf, i); 3870 item = btrfs_item_nr(leaf, i);
3838 ioff = btrfs_item_offset(leaf, item); 3871 ioff = btrfs_token_item_offset(leaf, item, &token);
3839 btrfs_set_item_offset(leaf, item, ioff + dsize); 3872 btrfs_set_token_item_offset(leaf, item,
3873 ioff + dsize, &token);
3840 } 3874 }
3841 3875
3842 memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), 3876 memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot),
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 85ab1c5844a..c2e17cd299b 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1546,6 +1546,17 @@ struct btrfs_ioctl_defrag_range_args {
1546 1546
1547#define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) 1547#define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31)
1548 1548
1549struct btrfs_map_token {
1550 struct extent_buffer *eb;
1551 char *kaddr;
1552 unsigned long offset;
1553};
1554
1555static inline void btrfs_init_map_token (struct btrfs_map_token *token)
1556{
1557 memset(token, 0, sizeof(*token));
1558}
1559
1549/* some macros to generate set/get funcs for the struct fields. This 1560/* some macros to generate set/get funcs for the struct fields. This
1550 * assumes there is a lefoo_to_cpu for every type, so lets make a simple 1561 * assumes there is a lefoo_to_cpu for every type, so lets make a simple
1551 * one for u8: 1562 * one for u8:
@@ -1569,6 +1580,8 @@ struct btrfs_ioctl_defrag_range_args {
1569#ifndef BTRFS_SETGET_FUNCS 1580#ifndef BTRFS_SETGET_FUNCS
1570#define BTRFS_SETGET_FUNCS(name, type, member, bits) \ 1581#define BTRFS_SETGET_FUNCS(name, type, member, bits) \
1571u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ 1582u##bits btrfs_##name(struct extent_buffer *eb, type *s); \
1583u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, struct btrfs_map_token *token); \
1584void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token);\
1572void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); 1585void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val);
1573#endif 1586#endif
1574 1587
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index bc1f6ad1844..c6ffa581241 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -44,8 +44,9 @@
44#define BTRFS_SETGET_FUNCS(name, type, member, bits) \ 44#define BTRFS_SETGET_FUNCS(name, type, member, bits) \
45u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ 45u##bits btrfs_##name(struct extent_buffer *eb, type *s); \
46void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); \ 46void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); \
47u##bits btrfs_##name(struct extent_buffer *eb, \ 47void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token); \
48 type *s) \ 48u##bits btrfs_token_##name(struct extent_buffer *eb, \
49 type *s, struct btrfs_map_token *token) \
49{ \ 50{ \
50 unsigned long part_offset = (unsigned long)s; \ 51 unsigned long part_offset = (unsigned long)s; \
51 unsigned long offset = part_offset + offsetof(type, member); \ 52 unsigned long offset = part_offset + offsetof(type, member); \
@@ -54,9 +55,18 @@ u##bits btrfs_##name(struct extent_buffer *eb, \
54 char *kaddr; \ 55 char *kaddr; \
55 unsigned long map_start; \ 56 unsigned long map_start; \
56 unsigned long map_len; \ 57 unsigned long map_len; \
58 unsigned long mem_len = sizeof(((type *)0)->member); \
57 u##bits res; \ 59 u##bits res; \
60 if (token && token->kaddr && token->offset <= offset && \
61 token->eb == eb && \
62 (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \
63 kaddr = token->kaddr; \
64 p = (type *)(kaddr + part_offset - token->offset); \
65 res = le##bits##_to_cpu(p->member); \
66 return res; \
67 } \
58 err = map_private_extent_buffer(eb, offset, \ 68 err = map_private_extent_buffer(eb, offset, \
59 sizeof(((type *)0)->member), \ 69 mem_len, \
60 &kaddr, &map_start, &map_len); \ 70 &kaddr, &map_start, &map_len); \
61 if (err) { \ 71 if (err) { \
62 __le##bits leres; \ 72 __le##bits leres; \
@@ -65,10 +75,15 @@ u##bits btrfs_##name(struct extent_buffer *eb, \
65 } \ 75 } \
66 p = (type *)(kaddr + part_offset - map_start); \ 76 p = (type *)(kaddr + part_offset - map_start); \
67 res = le##bits##_to_cpu(p->member); \ 77 res = le##bits##_to_cpu(p->member); \
78 if (token) { \
79 token->kaddr = kaddr; \
80 token->offset = map_start; \
81 token->eb = eb; \
82 } \
68 return res; \ 83 return res; \
69} \ 84} \
70void btrfs_set_##name(struct extent_buffer *eb, \ 85void btrfs_set_token_##name(struct extent_buffer *eb, \
71 type *s, u##bits val) \ 86 type *s, u##bits val, struct btrfs_map_token *token) \
72{ \ 87{ \
73 unsigned long part_offset = (unsigned long)s; \ 88 unsigned long part_offset = (unsigned long)s; \
74 unsigned long offset = part_offset + offsetof(type, member); \ 89 unsigned long offset = part_offset + offsetof(type, member); \
@@ -77,8 +92,17 @@ void btrfs_set_##name(struct extent_buffer *eb, \
77 char *kaddr; \ 92 char *kaddr; \
78 unsigned long map_start; \ 93 unsigned long map_start; \
79 unsigned long map_len; \ 94 unsigned long map_len; \
95 unsigned long mem_len = sizeof(((type *)0)->member); \
96 if (token && token->kaddr && token->offset <= offset && \
97 token->eb == eb && \
98 (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \
99 kaddr = token->kaddr; \
100 p = (type *)(kaddr + part_offset - token->offset); \
101 p->member = cpu_to_le##bits(val); \
102 return; \
103 } \
80 err = map_private_extent_buffer(eb, offset, \ 104 err = map_private_extent_buffer(eb, offset, \
81 sizeof(((type *)0)->member), \ 105 mem_len, \
82 &kaddr, &map_start, &map_len); \ 106 &kaddr, &map_start, &map_len); \
83 if (err) { \ 107 if (err) { \
84 __le##bits val2; \ 108 __le##bits val2; \
@@ -88,7 +112,22 @@ void btrfs_set_##name(struct extent_buffer *eb, \
88 } \ 112 } \
89 p = (type *)(kaddr + part_offset - map_start); \ 113 p = (type *)(kaddr + part_offset - map_start); \
90 p->member = cpu_to_le##bits(val); \ 114 p->member = cpu_to_le##bits(val); \
91} 115 if (token) { \
116 token->kaddr = kaddr; \
117 token->offset = map_start; \
118 token->eb = eb; \
119 } \
120} \
121void btrfs_set_##name(struct extent_buffer *eb, \
122 type *s, u##bits val) \
123{ \
124 btrfs_set_token_##name(eb, s, val, NULL); \
125} \
126u##bits btrfs_##name(struct extent_buffer *eb, \
127 type *s) \
128{ \
129 return btrfs_token_##name(eb, s, NULL); \
130} \
92 131
93#include "ctree.h" 132#include "ctree.h"
94 133