diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-15 16:14:19 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:56 -0400 |
commit | 5f39d397dfbe140a14edecd4e73c34ce23c4f9ee (patch) | |
tree | 280561e4b68d573590557dd27df656869eed8023 /fs/btrfs | |
parent | 50b78c24d594e6985f36a9a8d8e2fb74e1664e90 (diff) |
Btrfs: Create extent_buffer interface for large blocksizes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/Makefile | 2 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 1484 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 849 | ||||
-rw-r--r-- | fs/btrfs/dir-item.c | 102 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 391 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 55 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 294 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 672 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 75 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 63 | ||||
-rw-r--r-- | fs/btrfs/file.c | 129 | ||||
-rw-r--r-- | fs/btrfs/inode-item.c | 22 | ||||
-rw-r--r-- | fs/btrfs/inode-map.c | 17 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 435 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 96 | ||||
-rw-r--r-- | fs/btrfs/print-tree.h | 4 | ||||
-rw-r--r-- | fs/btrfs/root-tree.c | 51 | ||||
-rw-r--r-- | fs/btrfs/super.c | 7 | ||||
-rw-r--r-- | fs/btrfs/sysfs.c | 10 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 61 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 5 | ||||
-rw-r--r-- | fs/btrfs/tree-defrag.c | 58 |
22 files changed, 2794 insertions, 2088 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 6341cf7a9f91..a3b51085d7f0 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -23,4 +23,6 @@ modules_install: | |||
23 | clean: | 23 | clean: |
24 | $(MAKE) -C $(KERNELDIR) M=`pwd` clean | 24 | $(MAKE) -C $(KERNELDIR) M=`pwd` clean |
25 | 25 | ||
26 | tester: | ||
27 | $(MAKE) -C $(KERNELDIR) M=`pwd` tree-defrag.o transaction.o sysfs.o super.o root-tree.o inode-map.o inode-item.o inode.o file-item.o file.o extent_map.o disk-io.o ctree.o dir-item.o extent-tree.o | ||
26 | endif | 28 | endif |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b41f48ade419..f60920e8a0e0 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -16,21 +16,24 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/highmem.h> | ||
19 | #include "ctree.h" | 20 | #include "ctree.h" |
20 | #include "disk-io.h" | 21 | #include "disk-io.h" |
21 | #include "transaction.h" | 22 | #include "transaction.h" |
23 | #include "print-tree.h" | ||
22 | 24 | ||
23 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | 25 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root |
24 | *root, struct btrfs_path *path, int level); | 26 | *root, struct btrfs_path *path, int level); |
25 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | 27 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root |
26 | *root, struct btrfs_key *ins_key, | 28 | *root, struct btrfs_key *ins_key, |
27 | struct btrfs_path *path, int data_size); | 29 | struct btrfs_path *path, int data_size); |
28 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | 30 | static int push_node_left(struct btrfs_trans_handle *trans, |
29 | *root, struct buffer_head *dst, struct buffer_head | 31 | struct btrfs_root *root, struct extent_buffer *dst, |
30 | *src); | 32 | struct extent_buffer *src); |
31 | static int balance_node_right(struct btrfs_trans_handle *trans, struct | 33 | static int balance_node_right(struct btrfs_trans_handle *trans, |
32 | btrfs_root *root, struct buffer_head *dst_buf, | 34 | struct btrfs_root *root, |
33 | struct buffer_head *src_buf); | 35 | struct extent_buffer *dst_buf, |
36 | struct extent_buffer *src_buf); | ||
34 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 37 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
35 | struct btrfs_path *path, int level, int slot); | 38 | struct btrfs_path *path, int level, int slot); |
36 | 39 | ||
@@ -62,40 +65,38 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | |||
62 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | 65 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { |
63 | if (!p->nodes[i]) | 66 | if (!p->nodes[i]) |
64 | break; | 67 | break; |
65 | btrfs_block_release(root, p->nodes[i]); | 68 | free_extent_buffer(p->nodes[i]); |
66 | } | 69 | } |
67 | memset(p, 0, sizeof(*p)); | 70 | memset(p, 0, sizeof(*p)); |
68 | } | 71 | } |
69 | 72 | ||
70 | static int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | 73 | static int __btrfs_cow_block(struct btrfs_trans_handle *trans, |
71 | *root, struct buffer_head *buf, struct buffer_head | 74 | struct btrfs_root *root, |
72 | *parent, int parent_slot, struct buffer_head | 75 | struct extent_buffer *buf, |
73 | **cow_ret, u64 search_start, u64 empty_size) | 76 | struct extent_buffer *parent, int parent_slot, |
77 | struct extent_buffer **cow_ret, | ||
78 | u64 search_start, u64 empty_size) | ||
74 | { | 79 | { |
75 | struct buffer_head *cow; | 80 | struct extent_buffer *cow; |
76 | struct btrfs_node *cow_node; | ||
77 | int ret = 0; | 81 | int ret = 0; |
78 | int different_trans = 0; | 82 | int different_trans = 0; |
79 | 83 | ||
80 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); | 84 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); |
81 | WARN_ON(!buffer_uptodate(buf)); | 85 | |
82 | cow = btrfs_alloc_free_block(trans, root, search_start, empty_size); | 86 | cow = btrfs_alloc_free_block(trans, root, search_start, empty_size); |
83 | if (IS_ERR(cow)) | 87 | if (IS_ERR(cow)) |
84 | return PTR_ERR(cow); | 88 | return PTR_ERR(cow); |
85 | 89 | ||
86 | cow_node = btrfs_buffer_node(cow); | 90 | if (buf->len != root->sectorsize || cow->len != root->sectorsize) |
87 | if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) | ||
88 | WARN_ON(1); | 91 | WARN_ON(1); |
89 | 92 | ||
90 | memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); | 93 | copy_extent_buffer(cow, buf, 0, 0, cow->len); |
91 | btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); | 94 | btrfs_set_header_blocknr(cow, extent_buffer_blocknr(cow)); |
92 | btrfs_set_header_generation(&cow_node->header, trans->transid); | 95 | btrfs_set_header_generation(cow, trans->transid); |
93 | btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); | 96 | btrfs_set_header_owner(cow, root->root_key.objectid); |
94 | 97 | ||
95 | WARN_ON(btrfs_header_generation(btrfs_buffer_header(buf)) > | 98 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
96 | trans->transid); | 99 | if (btrfs_header_generation(buf) != trans->transid) { |
97 | if (btrfs_header_generation(btrfs_buffer_header(buf)) != | ||
98 | trans->transid) { | ||
99 | different_trans = 1; | 100 | different_trans = 1; |
100 | ret = btrfs_inc_ref(trans, root, buf); | 101 | ret = btrfs_inc_ref(trans, root, buf); |
101 | if (ret) | 102 | if (ret) |
@@ -106,29 +107,29 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | |||
106 | 107 | ||
107 | if (buf == root->node) { | 108 | if (buf == root->node) { |
108 | root->node = cow; | 109 | root->node = cow; |
109 | get_bh(cow); | 110 | extent_buffer_get(cow); |
110 | if (buf != root->commit_root) { | 111 | if (buf != root->commit_root) { |
111 | btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); | 112 | btrfs_free_extent(trans, root, |
113 | extent_buffer_blocknr(buf), 1, 1); | ||
112 | } | 114 | } |
113 | btrfs_block_release(root, buf); | 115 | free_extent_buffer(buf); |
114 | } else { | 116 | } else { |
115 | btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, | 117 | btrfs_set_node_blockptr(parent, parent_slot, |
116 | bh_blocknr(cow)); | 118 | extent_buffer_blocknr(cow)); |
117 | btrfs_mark_buffer_dirty(parent); | 119 | btrfs_mark_buffer_dirty(parent); |
118 | WARN_ON(btrfs_header_generation(btrfs_buffer_header(parent)) != | 120 | WARN_ON(btrfs_header_generation(parent) != trans->transid); |
119 | trans->transid); | 121 | btrfs_free_extent(trans, root, extent_buffer_blocknr(buf),1,1); |
120 | btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1); | ||
121 | } | 122 | } |
122 | btrfs_block_release(root, buf); | 123 | free_extent_buffer(buf); |
123 | btrfs_mark_buffer_dirty(cow); | 124 | btrfs_mark_buffer_dirty(cow); |
124 | *cow_ret = cow; | 125 | *cow_ret = cow; |
125 | return 0; | 126 | return 0; |
126 | } | 127 | } |
127 | 128 | ||
128 | int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | 129 | int btrfs_cow_block(struct btrfs_trans_handle *trans, |
129 | *root, struct buffer_head *buf, struct buffer_head | 130 | struct btrfs_root *root, struct extent_buffer *buf, |
130 | *parent, int parent_slot, struct buffer_head | 131 | struct extent_buffer *parent, int parent_slot, |
131 | **cow_ret) | 132 | struct extent_buffer **cow_ret) |
132 | { | 133 | { |
133 | u64 search_start; | 134 | u64 search_start; |
134 | if (trans->transaction != root->fs_info->running_transaction) { | 135 | if (trans->transaction != root->fs_info->running_transaction) { |
@@ -141,13 +142,12 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | |||
141 | root->fs_info->generation); | 142 | root->fs_info->generation); |
142 | WARN_ON(1); | 143 | WARN_ON(1); |
143 | } | 144 | } |
144 | if (btrfs_header_generation(btrfs_buffer_header(buf)) == | 145 | if (btrfs_header_generation(buf) == trans->transid) { |
145 | trans->transid) { | ||
146 | *cow_ret = buf; | 146 | *cow_ret = buf; |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | search_start = bh_blocknr(buf) & ~((u64)65535); | 150 | search_start = extent_buffer_blocknr(buf) & ~((u64)65535); |
151 | return __btrfs_cow_block(trans, root, buf, parent, | 151 | return __btrfs_cow_block(trans, root, buf, parent, |
152 | parent_slot, cow_ret, search_start, 0); | 152 | parent_slot, cow_ret, search_start, 0); |
153 | } | 153 | } |
@@ -161,9 +161,11 @@ static int close_blocks(u64 blocknr, u64 other) | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | static int should_defrag_leaf(struct buffer_head *bh) | 164 | #if 0 |
165 | static int should_defrag_leaf(struct extent_buffer *eb) | ||
165 | { | 166 | { |
166 | struct btrfs_leaf *leaf = btrfs_buffer_leaf(bh); | 167 | return 0; |
168 | struct btrfs_leaf *leaf = btrfs_buffer_leaf(eb); | ||
167 | struct btrfs_disk_key *key; | 169 | struct btrfs_disk_key *key; |
168 | u32 nritems; | 170 | u32 nritems; |
169 | 171 | ||
@@ -188,14 +190,17 @@ static int should_defrag_leaf(struct buffer_head *bh) | |||
188 | } | 190 | } |
189 | return 0; | 191 | return 0; |
190 | } | 192 | } |
193 | #endif | ||
191 | 194 | ||
192 | int btrfs_realloc_node(struct btrfs_trans_handle *trans, | 195 | int btrfs_realloc_node(struct btrfs_trans_handle *trans, |
193 | struct btrfs_root *root, struct buffer_head *parent, | 196 | struct btrfs_root *root, struct extent_buffer *parent, |
194 | int cache_only, u64 *last_ret) | 197 | int cache_only, u64 *last_ret) |
195 | { | 198 | { |
199 | return 0; | ||
200 | #if 0 | ||
196 | struct btrfs_node *parent_node; | 201 | struct btrfs_node *parent_node; |
197 | struct buffer_head *cur_bh; | 202 | struct extent_buffer *cur_eb; |
198 | struct buffer_head *tmp_bh; | 203 | struct extent_buffer *tmp_eb; |
199 | u64 blocknr; | 204 | u64 blocknr; |
200 | u64 search_start = *last_ret; | 205 | u64 search_start = *last_ret; |
201 | u64 last_block = 0; | 206 | u64 last_block = 0; |
@@ -281,6 +286,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
281 | brelse(tmp_bh); | 286 | brelse(tmp_bh); |
282 | } | 287 | } |
283 | return err; | 288 | return err; |
289 | #endif | ||
284 | } | 290 | } |
285 | 291 | ||
286 | /* | 292 | /* |
@@ -289,12 +295,12 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
289 | * which is the stop of the leaf data stack | 295 | * which is the stop of the leaf data stack |
290 | */ | 296 | */ |
291 | static inline unsigned int leaf_data_end(struct btrfs_root *root, | 297 | static inline unsigned int leaf_data_end(struct btrfs_root *root, |
292 | struct btrfs_leaf *leaf) | 298 | struct extent_buffer *leaf) |
293 | { | 299 | { |
294 | u32 nr = btrfs_header_nritems(&leaf->header); | 300 | u32 nr = btrfs_header_nritems(leaf); |
295 | if (nr == 0) | 301 | if (nr == 0) |
296 | return BTRFS_LEAF_DATA_SIZE(root); | 302 | return BTRFS_LEAF_DATA_SIZE(root); |
297 | return btrfs_item_offset(leaf->items + nr - 1); | 303 | return btrfs_item_offset_nr(leaf, nr - 1); |
298 | } | 304 | } |
299 | 305 | ||
300 | /* | 306 | /* |
@@ -310,9 +316,9 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) | |||
310 | return 1; | 316 | return 1; |
311 | if (k1.objectid < k2->objectid) | 317 | if (k1.objectid < k2->objectid) |
312 | return -1; | 318 | return -1; |
313 | if (k1.flags > k2->flags) | 319 | if (k1.type > k2->type) |
314 | return 1; | 320 | return 1; |
315 | if (k1.flags < k2->flags) | 321 | if (k1.type < k2->type) |
316 | return -1; | 322 | return -1; |
317 | if (k1.offset > k2->offset) | 323 | if (k1.offset > k2->offset) |
318 | return 1; | 324 | return 1; |
@@ -324,37 +330,39 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2) | |||
324 | static int check_node(struct btrfs_root *root, struct btrfs_path *path, | 330 | static int check_node(struct btrfs_root *root, struct btrfs_path *path, |
325 | int level) | 331 | int level) |
326 | { | 332 | { |
327 | struct btrfs_node *parent = NULL; | 333 | struct extent_buffer *parent = NULL; |
328 | struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); | 334 | struct extent_buffer *node = path->nodes[level]; |
335 | struct btrfs_disk_key parent_key; | ||
336 | struct btrfs_disk_key node_key; | ||
329 | int parent_slot; | 337 | int parent_slot; |
330 | int slot; | 338 | int slot; |
331 | struct btrfs_key cpukey; | 339 | struct btrfs_key cpukey; |
332 | u32 nritems = btrfs_header_nritems(&node->header); | 340 | u32 nritems = btrfs_header_nritems(node); |
333 | 341 | ||
334 | if (path->nodes[level + 1]) | 342 | if (path->nodes[level + 1]) |
335 | parent = btrfs_buffer_node(path->nodes[level + 1]); | 343 | parent = path->nodes[level + 1]; |
336 | 344 | ||
337 | slot = path->slots[level]; | 345 | slot = path->slots[level]; |
338 | BUG_ON(!buffer_uptodate(path->nodes[level])); | ||
339 | BUG_ON(nritems == 0); | 346 | BUG_ON(nritems == 0); |
340 | if (parent) { | 347 | if (parent) { |
341 | struct btrfs_disk_key *parent_key; | ||
342 | |||
343 | parent_slot = path->slots[level + 1]; | 348 | parent_slot = path->slots[level + 1]; |
344 | parent_key = &parent->ptrs[parent_slot].key; | 349 | btrfs_node_key(parent, &parent_key, parent_slot); |
345 | BUG_ON(memcmp(parent_key, &node->ptrs[0].key, | 350 | btrfs_node_key(node, &node_key, 0); |
351 | BUG_ON(memcmp(&parent_key, &node_key, | ||
346 | sizeof(struct btrfs_disk_key))); | 352 | sizeof(struct btrfs_disk_key))); |
347 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != | 353 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != |
348 | btrfs_header_blocknr(&node->header)); | 354 | btrfs_header_blocknr(node)); |
349 | } | 355 | } |
350 | BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); | 356 | BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); |
351 | if (slot != 0) { | 357 | if (slot != 0) { |
352 | btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key); | 358 | btrfs_node_key_to_cpu(node, &cpukey, slot - 1); |
353 | BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0); | 359 | btrfs_node_key(node, &node_key, slot); |
360 | BUG_ON(comp_keys(&node_key, &cpukey) <= 0); | ||
354 | } | 361 | } |
355 | if (slot < nritems - 1) { | 362 | if (slot < nritems - 1) { |
356 | btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key); | 363 | btrfs_node_key_to_cpu(node, &cpukey, slot + 1); |
357 | BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0); | 364 | btrfs_node_key(node, &node_key, slot); |
365 | BUG_ON(comp_keys(&node_key, &cpukey) >= 0); | ||
358 | } | 366 | } |
359 | return 0; | 367 | return 0; |
360 | } | 368 | } |
@@ -362,83 +370,172 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path, | |||
362 | static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, | 370 | static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, |
363 | int level) | 371 | int level) |
364 | { | 372 | { |
365 | struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); | 373 | struct extent_buffer *leaf = path->nodes[level]; |
366 | struct btrfs_node *parent = NULL; | 374 | struct extent_buffer *parent = NULL; |
367 | int parent_slot; | 375 | int parent_slot; |
368 | int slot = path->slots[0]; | ||
369 | struct btrfs_key cpukey; | 376 | struct btrfs_key cpukey; |
377 | struct btrfs_disk_key parent_key; | ||
378 | struct btrfs_disk_key leaf_key; | ||
379 | int slot = path->slots[0]; | ||
370 | 380 | ||
371 | u32 nritems = btrfs_header_nritems(&leaf->header); | 381 | u32 nritems = btrfs_header_nritems(leaf); |
372 | 382 | ||
373 | if (path->nodes[level + 1]) | 383 | if (path->nodes[level + 1]) |
374 | parent = btrfs_buffer_node(path->nodes[level + 1]); | 384 | parent = path->nodes[level + 1]; |
375 | |||
376 | BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); | ||
377 | 385 | ||
378 | if (nritems == 0) | 386 | if (nritems == 0) |
379 | return 0; | 387 | return 0; |
380 | 388 | ||
381 | if (parent) { | 389 | if (parent) { |
382 | struct btrfs_disk_key *parent_key; | ||
383 | |||
384 | parent_slot = path->slots[level + 1]; | 390 | parent_slot = path->slots[level + 1]; |
385 | parent_key = &parent->ptrs[parent_slot].key; | 391 | btrfs_node_key(parent, &parent_key, parent_slot); |
392 | btrfs_item_key(leaf, &leaf_key, 0); | ||
386 | 393 | ||
387 | BUG_ON(memcmp(parent_key, &leaf->items[0].key, | 394 | BUG_ON(memcmp(&parent_key, &leaf_key, |
388 | sizeof(struct btrfs_disk_key))); | 395 | sizeof(struct btrfs_disk_key))); |
389 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != | 396 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != |
390 | btrfs_header_blocknr(&leaf->header)); | 397 | btrfs_header_blocknr(leaf)); |
398 | } | ||
399 | #if 0 | ||
400 | for (i = 0; nritems > 1 && i < nritems - 2; i++) { | ||
401 | btrfs_item_key_to_cpu(leaf, &cpukey, i + 1); | ||
402 | btrfs_item_key(leaf, &leaf_key, i); | ||
403 | if (comp_keys(&leaf_key, &cpukey) >= 0) { | ||
404 | btrfs_print_leaf(root, leaf); | ||
405 | printk("slot %d offset bad key\n", i); | ||
406 | BUG_ON(1); | ||
407 | } | ||
408 | if (btrfs_item_offset_nr(leaf, i) != | ||
409 | btrfs_item_end_nr(leaf, i + 1)) { | ||
410 | btrfs_print_leaf(root, leaf); | ||
411 | printk("slot %d offset bad\n", i); | ||
412 | BUG_ON(1); | ||
413 | } | ||
414 | if (i == 0) { | ||
415 | if (btrfs_item_offset_nr(leaf, i) + | ||
416 | btrfs_item_size_nr(leaf, i) != | ||
417 | BTRFS_LEAF_DATA_SIZE(root)) { | ||
418 | btrfs_print_leaf(root, leaf); | ||
419 | printk("slot %d first offset bad\n", i); | ||
420 | BUG_ON(1); | ||
421 | } | ||
422 | } | ||
391 | } | 423 | } |
392 | if (slot != 0) { | 424 | if (nritems > 0) { |
393 | btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key); | 425 | if (btrfs_item_size_nr(leaf, nritems - 1) > 4096) { |
394 | BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0); | 426 | btrfs_print_leaf(root, leaf); |
395 | BUG_ON(btrfs_item_offset(leaf->items + slot - 1) != | 427 | printk("slot %d bad size \n", nritems - 1); |
396 | btrfs_item_end(leaf->items + slot)); | 428 | BUG_ON(1); |
429 | } | ||
430 | } | ||
431 | #endif | ||
432 | if (slot != 0 && slot < nritems - 1) { | ||
433 | btrfs_item_key(leaf, &leaf_key, slot); | ||
434 | btrfs_item_key_to_cpu(leaf, &cpukey, slot - 1); | ||
435 | if (comp_keys(&leaf_key, &cpukey) <= 0) { | ||
436 | btrfs_print_leaf(root, leaf); | ||
437 | printk("slot %d offset bad key\n", slot); | ||
438 | BUG_ON(1); | ||
439 | } | ||
440 | if (btrfs_item_offset_nr(leaf, slot - 1) != | ||
441 | btrfs_item_end_nr(leaf, slot)) { | ||
442 | btrfs_print_leaf(root, leaf); | ||
443 | printk("slot %d offset bad\n", slot); | ||
444 | BUG_ON(1); | ||
445 | } | ||
397 | } | 446 | } |
398 | if (slot < nritems - 1) { | 447 | if (slot < nritems - 1) { |
399 | btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key); | 448 | btrfs_item_key(leaf, &leaf_key, slot); |
400 | BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0); | 449 | btrfs_item_key_to_cpu(leaf, &cpukey, slot + 1); |
401 | BUG_ON(btrfs_item_offset(leaf->items + slot) != | 450 | BUG_ON(comp_keys(&leaf_key, &cpukey) >= 0); |
402 | btrfs_item_end(leaf->items + slot + 1)); | 451 | if (btrfs_item_offset_nr(leaf, slot) != |
452 | btrfs_item_end_nr(leaf, slot + 1)) { | ||
453 | btrfs_print_leaf(root, leaf); | ||
454 | printk("slot %d offset bad\n", slot); | ||
455 | BUG_ON(1); | ||
456 | } | ||
403 | } | 457 | } |
404 | BUG_ON(btrfs_item_offset(leaf->items) + | 458 | BUG_ON(btrfs_item_offset_nr(leaf, 0) + |
405 | btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root)); | 459 | btrfs_item_size_nr(leaf, 0) != BTRFS_LEAF_DATA_SIZE(root)); |
406 | return 0; | 460 | return 0; |
407 | } | 461 | } |
408 | 462 | ||
409 | static int check_block(struct btrfs_root *root, struct btrfs_path *path, | 463 | static int check_block(struct btrfs_root *root, struct btrfs_path *path, |
410 | int level) | 464 | int level) |
411 | { | 465 | { |
412 | struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); | 466 | struct extent_buffer *buf = path->nodes[level]; |
413 | if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid, | 467 | char fsid[BTRFS_FSID_SIZE]; |
414 | sizeof(node->header.fsid))) | 468 | |
415 | BUG(); | 469 | read_extent_buffer(buf, fsid, (unsigned long)btrfs_header_fsid(buf), |
470 | BTRFS_FSID_SIZE); | ||
471 | |||
472 | if (memcmp(fsid, root->fs_info->fsid, BTRFS_FSID_SIZE)) { | ||
473 | int i = 0; | ||
474 | printk("warning bad block %Lu\n", buf->start); | ||
475 | if (!btrfs_buffer_uptodate(buf)) { | ||
476 | WARN_ON(1); | ||
477 | } | ||
478 | for (i = 0; i < BTRFS_FSID_SIZE; i++) { | ||
479 | printk("%x:%x ", root->fs_info->fsid[i], fsid[i]); | ||
480 | } | ||
481 | printk("\n"); | ||
482 | // BUG(); | ||
483 | } | ||
416 | if (level == 0) | 484 | if (level == 0) |
417 | return check_leaf(root, path, level); | 485 | return check_leaf(root, path, level); |
418 | return check_node(root, path, level); | 486 | return check_node(root, path, level); |
419 | } | 487 | } |
420 | 488 | ||
421 | /* | 489 | /* |
422 | * search for key in the array p. items p are item_size apart | 490 | * search for key in the extent_buffer. The items start at offset p, |
423 | * and there are 'max' items in p | 491 | * and they are item_size apart. There are 'max' items in p. |
492 | * | ||
424 | * the slot in the array is returned via slot, and it points to | 493 | * the slot in the array is returned via slot, and it points to |
425 | * the place where you would insert key if it is not found in | 494 | * the place where you would insert key if it is not found in |
426 | * the array. | 495 | * the array. |
427 | * | 496 | * |
428 | * slot may point to max if the key is bigger than all of the keys | 497 | * slot may point to max if the key is bigger than all of the keys |
429 | */ | 498 | */ |
430 | static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, | 499 | static int generic_bin_search(struct extent_buffer *eb, unsigned long p, |
431 | int max, int *slot) | 500 | int item_size, struct btrfs_key *key, |
501 | int max, int *slot) | ||
432 | { | 502 | { |
433 | int low = 0; | 503 | int low = 0; |
434 | int high = max; | 504 | int high = max; |
435 | int mid; | 505 | int mid; |
436 | int ret; | 506 | int ret; |
437 | struct btrfs_disk_key *tmp; | 507 | struct btrfs_disk_key *tmp; |
508 | struct btrfs_disk_key unaligned; | ||
509 | unsigned long offset; | ||
510 | char *map_token = NULL; | ||
511 | char *kaddr = NULL; | ||
512 | unsigned long map_start = 0; | ||
513 | unsigned long map_len = 0; | ||
438 | 514 | ||
439 | while(low < high) { | 515 | while(low < high) { |
440 | mid = (low + high) / 2; | 516 | mid = (low + high) / 2; |
441 | tmp = (struct btrfs_disk_key *)(p + mid * item_size); | 517 | offset = p + mid * item_size; |
518 | |||
519 | if (!map_token || offset < map_start || | ||
520 | (offset + sizeof(struct btrfs_disk_key)) > | ||
521 | map_start + map_len) { | ||
522 | if (map_token) | ||
523 | unmap_extent_buffer(eb, map_token, KM_USER0); | ||
524 | map_extent_buffer(eb, offset, &map_token, &kaddr, | ||
525 | &map_start, &map_len, KM_USER0); | ||
526 | |||
527 | } | ||
528 | if (offset + sizeof(struct btrfs_disk_key) > | ||
529 | map_start + map_len) { | ||
530 | unmap_extent_buffer(eb, map_token, KM_USER0); | ||
531 | read_extent_buffer(eb, &unaligned, | ||
532 | offset, sizeof(unaligned)); | ||
533 | map_token = NULL; | ||
534 | tmp = &unaligned; | ||
535 | } else { | ||
536 | tmp = (struct btrfs_disk_key *)(kaddr + offset - | ||
537 | map_start); | ||
538 | } | ||
442 | ret = comp_keys(tmp, key); | 539 | ret = comp_keys(tmp, key); |
443 | 540 | ||
444 | if (ret < 0) | 541 | if (ret < 0) |
@@ -447,10 +544,13 @@ static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, | |||
447 | high = mid; | 544 | high = mid; |
448 | else { | 545 | else { |
449 | *slot = mid; | 546 | *slot = mid; |
547 | unmap_extent_buffer(eb, map_token, KM_USER0); | ||
450 | return 0; | 548 | return 0; |
451 | } | 549 | } |
452 | } | 550 | } |
453 | *slot = low; | 551 | *slot = low; |
552 | if (map_token) | ||
553 | unmap_extent_buffer(eb, map_token, KM_USER0); | ||
454 | return 1; | 554 | return 1; |
455 | } | 555 | } |
456 | 556 | ||
@@ -458,46 +558,42 @@ static int generic_bin_search(char *p, int item_size, struct btrfs_key *key, | |||
458 | * simple bin_search frontend that does the right thing for | 558 | * simple bin_search frontend that does the right thing for |
459 | * leaves vs nodes | 559 | * leaves vs nodes |
460 | */ | 560 | */ |
461 | static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) | 561 | static int bin_search(struct extent_buffer *eb, struct btrfs_key *key, |
562 | int level, int *slot) | ||
462 | { | 563 | { |
463 | if (btrfs_is_leaf(c)) { | 564 | if (level == 0) { |
464 | struct btrfs_leaf *l = (struct btrfs_leaf *)c; | 565 | return generic_bin_search(eb, |
465 | return generic_bin_search((void *)l->items, | 566 | offsetof(struct btrfs_leaf, items), |
466 | sizeof(struct btrfs_item), | 567 | sizeof(struct btrfs_item), |
467 | key, btrfs_header_nritems(&c->header), | 568 | key, btrfs_header_nritems(eb), |
468 | slot); | 569 | slot); |
469 | } else { | 570 | } else { |
470 | return generic_bin_search((void *)c->ptrs, | 571 | return generic_bin_search(eb, |
572 | offsetof(struct btrfs_node, ptrs), | ||
471 | sizeof(struct btrfs_key_ptr), | 573 | sizeof(struct btrfs_key_ptr), |
472 | key, btrfs_header_nritems(&c->header), | 574 | key, btrfs_header_nritems(eb), |
473 | slot); | 575 | slot); |
474 | } | 576 | } |
475 | return -1; | 577 | return -1; |
476 | } | 578 | } |
477 | 579 | ||
478 | static struct buffer_head *read_node_slot(struct btrfs_root *root, | 580 | static struct extent_buffer *read_node_slot(struct btrfs_root *root, |
479 | struct buffer_head *parent_buf, | 581 | struct extent_buffer *parent, int slot) |
480 | int slot) | ||
481 | { | 582 | { |
482 | struct btrfs_node *node = btrfs_buffer_node(parent_buf); | ||
483 | if (slot < 0) | 583 | if (slot < 0) |
484 | return NULL; | 584 | return NULL; |
485 | if (slot >= btrfs_header_nritems(&node->header)) | 585 | if (slot >= btrfs_header_nritems(parent)) |
486 | return NULL; | 586 | return NULL; |
487 | return read_tree_block(root, btrfs_node_blockptr(node, slot)); | 587 | return read_tree_block(root, btrfs_node_blockptr(parent, slot)); |
488 | } | 588 | } |
489 | 589 | ||
490 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | 590 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root |
491 | *root, struct btrfs_path *path, int level) | 591 | *root, struct btrfs_path *path, int level) |
492 | { | 592 | { |
493 | struct buffer_head *right_buf; | 593 | struct extent_buffer *right = NULL; |
494 | struct buffer_head *mid_buf; | 594 | struct extent_buffer *mid; |
495 | struct buffer_head *left_buf; | 595 | struct extent_buffer *left = NULL; |
496 | struct buffer_head *parent_buf = NULL; | 596 | struct extent_buffer *parent = NULL; |
497 | struct btrfs_node *right = NULL; | ||
498 | struct btrfs_node *mid; | ||
499 | struct btrfs_node *left = NULL; | ||
500 | struct btrfs_node *parent = NULL; | ||
501 | int ret = 0; | 597 | int ret = 0; |
502 | int wret; | 598 | int wret; |
503 | int pslot; | 599 | int pslot; |
@@ -508,60 +604,57 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
508 | if (level == 0) | 604 | if (level == 0) |
509 | return 0; | 605 | return 0; |
510 | 606 | ||
511 | mid_buf = path->nodes[level]; | 607 | mid = path->nodes[level]; |
512 | mid = btrfs_buffer_node(mid_buf); | ||
513 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | 608 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); |
514 | 609 | ||
515 | if (level < BTRFS_MAX_LEVEL - 1) | 610 | if (level < BTRFS_MAX_LEVEL - 1) |
516 | parent_buf = path->nodes[level + 1]; | 611 | parent = path->nodes[level + 1]; |
517 | pslot = path->slots[level + 1]; | 612 | pslot = path->slots[level + 1]; |
518 | 613 | ||
519 | /* | 614 | /* |
520 | * deal with the case where there is only one pointer in the root | 615 | * deal with the case where there is only one pointer in the root |
521 | * by promoting the node below to a root | 616 | * by promoting the node below to a root |
522 | */ | 617 | */ |
523 | if (!parent_buf) { | 618 | if (!parent) { |
524 | struct buffer_head *child; | 619 | struct extent_buffer *child; |
525 | u64 blocknr = bh_blocknr(mid_buf); | 620 | u64 blocknr = extent_buffer_blocknr(mid); |
526 | 621 | ||
527 | if (btrfs_header_nritems(&mid->header) != 1) | 622 | if (btrfs_header_nritems(mid) != 1) |
528 | return 0; | 623 | return 0; |
529 | 624 | ||
530 | /* promote the child to a root */ | 625 | /* promote the child to a root */ |
531 | child = read_node_slot(root, mid_buf, 0); | 626 | child = read_node_slot(root, mid, 0); |
532 | BUG_ON(!child); | 627 | BUG_ON(!child); |
533 | root->node = child; | 628 | root->node = child; |
534 | path->nodes[level] = NULL; | 629 | path->nodes[level] = NULL; |
535 | clean_tree_block(trans, root, mid_buf); | 630 | clean_tree_block(trans, root, mid); |
536 | wait_on_buffer(mid_buf); | 631 | wait_on_tree_block_writeback(root, mid); |
537 | /* once for the path */ | 632 | /* once for the path */ |
538 | btrfs_block_release(root, mid_buf); | 633 | free_extent_buffer(mid); |
539 | /* once for the root ptr */ | 634 | /* once for the root ptr */ |
540 | btrfs_block_release(root, mid_buf); | 635 | free_extent_buffer(mid); |
541 | return btrfs_free_extent(trans, root, blocknr, 1, 1); | 636 | return btrfs_free_extent(trans, root, blocknr, 1, 1); |
542 | } | 637 | } |
543 | parent = btrfs_buffer_node(parent_buf); | 638 | if (btrfs_header_nritems(mid) > |
544 | |||
545 | if (btrfs_header_nritems(&mid->header) > | ||
546 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) | 639 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) |
547 | return 0; | 640 | return 0; |
548 | 641 | ||
549 | if (btrfs_header_nritems(&mid->header) < 2) | 642 | if (btrfs_header_nritems(mid) < 2) |
550 | err_on_enospc = 1; | 643 | err_on_enospc = 1; |
551 | 644 | ||
552 | left_buf = read_node_slot(root, parent_buf, pslot - 1); | 645 | left = read_node_slot(root, parent, pslot - 1); |
553 | if (left_buf) { | 646 | if (left) { |
554 | wret = btrfs_cow_block(trans, root, left_buf, | 647 | wret = btrfs_cow_block(trans, root, left, |
555 | parent_buf, pslot - 1, &left_buf); | 648 | parent, pslot - 1, &left); |
556 | if (wret) { | 649 | if (wret) { |
557 | ret = wret; | 650 | ret = wret; |
558 | goto enospc; | 651 | goto enospc; |
559 | } | 652 | } |
560 | } | 653 | } |
561 | right_buf = read_node_slot(root, parent_buf, pslot + 1); | 654 | right = read_node_slot(root, parent, pslot + 1); |
562 | if (right_buf) { | 655 | if (right) { |
563 | wret = btrfs_cow_block(trans, root, right_buf, | 656 | wret = btrfs_cow_block(trans, root, right, |
564 | parent_buf, pslot + 1, &right_buf); | 657 | parent, pslot + 1, &right); |
565 | if (wret) { | 658 | if (wret) { |
566 | ret = wret; | 659 | ret = wret; |
567 | goto enospc; | 660 | goto enospc; |
@@ -569,30 +662,27 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
569 | } | 662 | } |
570 | 663 | ||
571 | /* first, try to make some room in the middle buffer */ | 664 | /* first, try to make some room in the middle buffer */ |
572 | if (left_buf) { | 665 | if (left) { |
573 | left = btrfs_buffer_node(left_buf); | 666 | orig_slot += btrfs_header_nritems(left); |
574 | orig_slot += btrfs_header_nritems(&left->header); | 667 | wret = push_node_left(trans, root, left, mid); |
575 | wret = push_node_left(trans, root, left_buf, mid_buf); | ||
576 | if (wret < 0) | 668 | if (wret < 0) |
577 | ret = wret; | 669 | ret = wret; |
578 | if (btrfs_header_nritems(&mid->header) < 2) | 670 | if (btrfs_header_nritems(mid) < 2) |
579 | err_on_enospc = 1; | 671 | err_on_enospc = 1; |
580 | } | 672 | } |
581 | 673 | ||
582 | /* | 674 | /* |
583 | * then try to empty the right most buffer into the middle | 675 | * then try to empty the right most buffer into the middle |
584 | */ | 676 | */ |
585 | if (right_buf) { | 677 | if (right) { |
586 | right = btrfs_buffer_node(right_buf); | 678 | wret = push_node_left(trans, root, mid, right); |
587 | wret = push_node_left(trans, root, mid_buf, right_buf); | ||
588 | if (wret < 0 && wret != -ENOSPC) | 679 | if (wret < 0 && wret != -ENOSPC) |
589 | ret = wret; | 680 | ret = wret; |
590 | if (btrfs_header_nritems(&right->header) == 0) { | 681 | if (btrfs_header_nritems(right) == 0) { |
591 | u64 blocknr = bh_blocknr(right_buf); | 682 | u64 blocknr = extent_buffer_blocknr(right); |
592 | clean_tree_block(trans, root, right_buf); | 683 | clean_tree_block(trans, root, right); |
593 | wait_on_buffer(right_buf); | 684 | wait_on_tree_block_writeback(root, right); |
594 | btrfs_block_release(root, right_buf); | 685 | free_extent_buffer(right); |
595 | right_buf = NULL; | ||
596 | right = NULL; | 686 | right = NULL; |
597 | wret = del_ptr(trans, root, path, level + 1, pslot + | 687 | wret = del_ptr(trans, root, path, level + 1, pslot + |
598 | 1); | 688 | 1); |
@@ -602,14 +692,13 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
602 | if (wret) | 692 | if (wret) |
603 | ret = wret; | 693 | ret = wret; |
604 | } else { | 694 | } else { |
605 | btrfs_memcpy(root, parent, | 695 | struct btrfs_disk_key right_key; |
606 | &parent->ptrs[pslot + 1].key, | 696 | btrfs_node_key(right, &right_key, 0); |
607 | &right->ptrs[0].key, | 697 | btrfs_set_node_key(parent, &right_key, pslot + 1); |
608 | sizeof(struct btrfs_disk_key)); | 698 | btrfs_mark_buffer_dirty(parent); |
609 | btrfs_mark_buffer_dirty(parent_buf); | ||
610 | } | 699 | } |
611 | } | 700 | } |
612 | if (btrfs_header_nritems(&mid->header) == 1) { | 701 | if (btrfs_header_nritems(mid) == 1) { |
613 | /* | 702 | /* |
614 | * we're not allowed to leave a node with one item in the | 703 | * we're not allowed to leave a node with one item in the |
615 | * tree during a delete. A deletion from lower in the tree | 704 | * tree during a delete. A deletion from lower in the tree |
@@ -619,21 +708,20 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
619 | * otherwise we would have pulled some pointers from the | 708 | * otherwise we would have pulled some pointers from the |
620 | * right | 709 | * right |
621 | */ | 710 | */ |
622 | BUG_ON(!left_buf); | 711 | BUG_ON(!left); |
623 | wret = balance_node_right(trans, root, mid_buf, left_buf); | 712 | wret = balance_node_right(trans, root, mid, left); |
624 | if (wret < 0) { | 713 | if (wret < 0) { |
625 | ret = wret; | 714 | ret = wret; |
626 | goto enospc; | 715 | goto enospc; |
627 | } | 716 | } |
628 | BUG_ON(wret == 1); | 717 | BUG_ON(wret == 1); |
629 | } | 718 | } |
630 | if (btrfs_header_nritems(&mid->header) == 0) { | 719 | if (btrfs_header_nritems(mid) == 0) { |
631 | /* we've managed to empty the middle node, drop it */ | 720 | /* we've managed to empty the middle node, drop it */ |
632 | u64 blocknr = bh_blocknr(mid_buf); | 721 | u64 blocknr = extent_buffer_blocknr(mid); |
633 | clean_tree_block(trans, root, mid_buf); | 722 | clean_tree_block(trans, root, mid); |
634 | wait_on_buffer(mid_buf); | 723 | wait_on_tree_block_writeback(root, mid); |
635 | btrfs_block_release(root, mid_buf); | 724 | free_extent_buffer(mid); |
636 | mid_buf = NULL; | ||
637 | mid = NULL; | 725 | mid = NULL; |
638 | wret = del_ptr(trans, root, path, level + 1, pslot); | 726 | wret = del_ptr(trans, root, path, level + 1, pslot); |
639 | if (wret) | 727 | if (wret) |
@@ -643,37 +731,36 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
643 | ret = wret; | 731 | ret = wret; |
644 | } else { | 732 | } else { |
645 | /* update the parent key to reflect our changes */ | 733 | /* update the parent key to reflect our changes */ |
646 | btrfs_memcpy(root, parent, | 734 | struct btrfs_disk_key mid_key; |
647 | &parent->ptrs[pslot].key, &mid->ptrs[0].key, | 735 | btrfs_node_key(mid, &mid_key, 0); |
648 | sizeof(struct btrfs_disk_key)); | 736 | btrfs_set_node_key(parent, &mid_key, pslot); |
649 | btrfs_mark_buffer_dirty(parent_buf); | 737 | btrfs_mark_buffer_dirty(parent); |
650 | } | 738 | } |
651 | 739 | ||
652 | /* update the path */ | 740 | /* update the path */ |
653 | if (left_buf) { | 741 | if (left) { |
654 | if (btrfs_header_nritems(&left->header) > orig_slot) { | 742 | if (btrfs_header_nritems(left) > orig_slot) { |
655 | get_bh(left_buf); | 743 | extent_buffer_get(left); |
656 | path->nodes[level] = left_buf; | 744 | path->nodes[level] = left; |
657 | path->slots[level + 1] -= 1; | 745 | path->slots[level + 1] -= 1; |
658 | path->slots[level] = orig_slot; | 746 | path->slots[level] = orig_slot; |
659 | if (mid_buf) | 747 | if (mid) |
660 | btrfs_block_release(root, mid_buf); | 748 | free_extent_buffer(mid); |
661 | } else { | 749 | } else { |
662 | orig_slot -= btrfs_header_nritems(&left->header); | 750 | orig_slot -= btrfs_header_nritems(left); |
663 | path->slots[level] = orig_slot; | 751 | path->slots[level] = orig_slot; |
664 | } | 752 | } |
665 | } | 753 | } |
666 | /* double check we haven't messed things up */ | 754 | /* double check we haven't messed things up */ |
667 | check_block(root, path, level); | 755 | check_block(root, path, level); |
668 | if (orig_ptr != | 756 | if (orig_ptr != |
669 | btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), | 757 | btrfs_node_blockptr(path->nodes[level], path->slots[level])) |
670 | path->slots[level])) | ||
671 | BUG(); | 758 | BUG(); |
672 | enospc: | 759 | enospc: |
673 | if (right_buf) | 760 | if (right) |
674 | btrfs_block_release(root, right_buf); | 761 | free_extent_buffer(right); |
675 | if (left_buf) | 762 | if (left) |
676 | btrfs_block_release(root, left_buf); | 763 | free_extent_buffer(left); |
677 | return ret; | 764 | return ret; |
678 | } | 765 | } |
679 | 766 | ||
@@ -682,14 +769,10 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
682 | struct btrfs_root *root, | 769 | struct btrfs_root *root, |
683 | struct btrfs_path *path, int level) | 770 | struct btrfs_path *path, int level) |
684 | { | 771 | { |
685 | struct buffer_head *right_buf; | 772 | struct extent_buffer *right = NULL; |
686 | struct buffer_head *mid_buf; | 773 | struct extent_buffer *mid; |
687 | struct buffer_head *left_buf; | 774 | struct extent_buffer *left = NULL; |
688 | struct buffer_head *parent_buf = NULL; | 775 | struct extent_buffer *parent = NULL; |
689 | struct btrfs_node *right = NULL; | ||
690 | struct btrfs_node *mid; | ||
691 | struct btrfs_node *left = NULL; | ||
692 | struct btrfs_node *parent = NULL; | ||
693 | int ret = 0; | 776 | int ret = 0; |
694 | int wret; | 777 | int wret; |
695 | int pslot; | 778 | int pslot; |
@@ -699,107 +782,101 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
699 | if (level == 0) | 782 | if (level == 0) |
700 | return 1; | 783 | return 1; |
701 | 784 | ||
702 | mid_buf = path->nodes[level]; | 785 | mid = path->nodes[level]; |
703 | mid = btrfs_buffer_node(mid_buf); | ||
704 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | 786 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); |
705 | 787 | ||
706 | if (level < BTRFS_MAX_LEVEL - 1) | 788 | if (level < BTRFS_MAX_LEVEL - 1) |
707 | parent_buf = path->nodes[level + 1]; | 789 | parent = path->nodes[level + 1]; |
708 | pslot = path->slots[level + 1]; | 790 | pslot = path->slots[level + 1]; |
709 | 791 | ||
710 | if (!parent_buf) | 792 | if (!parent) |
711 | return 1; | 793 | return 1; |
712 | parent = btrfs_buffer_node(parent_buf); | ||
713 | 794 | ||
714 | left_buf = read_node_slot(root, parent_buf, pslot - 1); | 795 | left = read_node_slot(root, parent, pslot - 1); |
715 | 796 | ||
716 | /* first, try to make some room in the middle buffer */ | 797 | /* first, try to make some room in the middle buffer */ |
717 | if (left_buf) { | 798 | if (left) { |
718 | u32 left_nr; | 799 | u32 left_nr; |
719 | left = btrfs_buffer_node(left_buf); | 800 | left_nr = btrfs_header_nritems(left); |
720 | left_nr = btrfs_header_nritems(&left->header); | ||
721 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 801 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
722 | wret = 1; | 802 | wret = 1; |
723 | } else { | 803 | } else { |
724 | ret = btrfs_cow_block(trans, root, left_buf, parent_buf, | 804 | ret = btrfs_cow_block(trans, root, left, parent, |
725 | pslot - 1, &left_buf); | 805 | pslot - 1, &left); |
726 | if (ret) | 806 | if (ret) |
727 | wret = 1; | 807 | wret = 1; |
728 | else { | 808 | else { |
729 | left = btrfs_buffer_node(left_buf); | ||
730 | wret = push_node_left(trans, root, | 809 | wret = push_node_left(trans, root, |
731 | left_buf, mid_buf); | 810 | left, mid); |
732 | } | 811 | } |
733 | } | 812 | } |
734 | if (wret < 0) | 813 | if (wret < 0) |
735 | ret = wret; | 814 | ret = wret; |
736 | if (wret == 0) { | 815 | if (wret == 0) { |
816 | struct btrfs_disk_key disk_key; | ||
737 | orig_slot += left_nr; | 817 | orig_slot += left_nr; |
738 | btrfs_memcpy(root, parent, | 818 | btrfs_node_key(mid, &disk_key, 0); |
739 | &parent->ptrs[pslot].key, | 819 | btrfs_set_node_key(parent, &disk_key, pslot); |
740 | &mid->ptrs[0].key, | 820 | btrfs_mark_buffer_dirty(parent); |
741 | sizeof(struct btrfs_disk_key)); | 821 | if (btrfs_header_nritems(left) > orig_slot) { |
742 | btrfs_mark_buffer_dirty(parent_buf); | 822 | path->nodes[level] = left; |
743 | if (btrfs_header_nritems(&left->header) > orig_slot) { | ||
744 | path->nodes[level] = left_buf; | ||
745 | path->slots[level + 1] -= 1; | 823 | path->slots[level + 1] -= 1; |
746 | path->slots[level] = orig_slot; | 824 | path->slots[level] = orig_slot; |
747 | btrfs_block_release(root, mid_buf); | 825 | free_extent_buffer(mid); |
748 | } else { | 826 | } else { |
749 | orig_slot -= | 827 | orig_slot -= |
750 | btrfs_header_nritems(&left->header); | 828 | btrfs_header_nritems(left); |
751 | path->slots[level] = orig_slot; | 829 | path->slots[level] = orig_slot; |
752 | btrfs_block_release(root, left_buf); | 830 | free_extent_buffer(left); |
753 | } | 831 | } |
754 | check_node(root, path, level); | 832 | check_node(root, path, level); |
755 | return 0; | 833 | return 0; |
756 | } | 834 | } |
757 | btrfs_block_release(root, left_buf); | 835 | free_extent_buffer(left); |
758 | } | 836 | } |
759 | right_buf = read_node_slot(root, parent_buf, pslot + 1); | 837 | right= read_node_slot(root, parent, pslot + 1); |
760 | 838 | ||
761 | /* | 839 | /* |
762 | * then try to empty the right most buffer into the middle | 840 | * then try to empty the right most buffer into the middle |
763 | */ | 841 | */ |
764 | if (right_buf) { | 842 | if (right) { |
765 | u32 right_nr; | 843 | u32 right_nr; |
766 | right = btrfs_buffer_node(right_buf); | 844 | right_nr = btrfs_header_nritems(right); |
767 | right_nr = btrfs_header_nritems(&right->header); | ||
768 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 845 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
769 | wret = 1; | 846 | wret = 1; |
770 | } else { | 847 | } else { |
771 | ret = btrfs_cow_block(trans, root, right_buf, | 848 | ret = btrfs_cow_block(trans, root, right, |
772 | parent_buf, pslot + 1, | 849 | parent, pslot + 1, |
773 | &right_buf); | 850 | &right); |
774 | if (ret) | 851 | if (ret) |
775 | wret = 1; | 852 | wret = 1; |
776 | else { | 853 | else { |
777 | right = btrfs_buffer_node(right_buf); | ||
778 | wret = balance_node_right(trans, root, | 854 | wret = balance_node_right(trans, root, |
779 | right_buf, mid_buf); | 855 | right, mid); |
780 | } | 856 | } |
781 | } | 857 | } |
782 | if (wret < 0) | 858 | if (wret < 0) |
783 | ret = wret; | 859 | ret = wret; |
784 | if (wret == 0) { | 860 | if (wret == 0) { |
785 | btrfs_memcpy(root, parent, | 861 | struct btrfs_disk_key disk_key; |
786 | &parent->ptrs[pslot + 1].key, | 862 | |
787 | &right->ptrs[0].key, | 863 | btrfs_node_key(right, &disk_key, 0); |
788 | sizeof(struct btrfs_disk_key)); | 864 | btrfs_set_node_key(parent, &disk_key, pslot + 1); |
789 | btrfs_mark_buffer_dirty(parent_buf); | 865 | btrfs_mark_buffer_dirty(parent); |
790 | if (btrfs_header_nritems(&mid->header) <= orig_slot) { | 866 | |
791 | path->nodes[level] = right_buf; | 867 | if (btrfs_header_nritems(mid) <= orig_slot) { |
868 | path->nodes[level] = right; | ||
792 | path->slots[level + 1] += 1; | 869 | path->slots[level + 1] += 1; |
793 | path->slots[level] = orig_slot - | 870 | path->slots[level] = orig_slot - |
794 | btrfs_header_nritems(&mid->header); | 871 | btrfs_header_nritems(mid); |
795 | btrfs_block_release(root, mid_buf); | 872 | free_extent_buffer(mid); |
796 | } else { | 873 | } else { |
797 | btrfs_block_release(root, right_buf); | 874 | free_extent_buffer(right); |
798 | } | 875 | } |
799 | check_node(root, path, level); | 876 | check_node(root, path, level); |
800 | return 0; | 877 | return 0; |
801 | } | 878 | } |
802 | btrfs_block_release(root, right_buf); | 879 | free_extent_buffer(right); |
803 | } | 880 | } |
804 | check_node(root, path, level); | 881 | check_node(root, path, level); |
805 | return 1; | 882 | return 1; |
@@ -811,10 +888,9 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
811 | static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | 888 | static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, |
812 | int level, int slot) | 889 | int level, int slot) |
813 | { | 890 | { |
814 | struct btrfs_node *node; | 891 | struct extent_buffer *node; |
815 | int i; | 892 | int i; |
816 | u32 nritems; | 893 | u32 nritems; |
817 | u64 item_objectid; | ||
818 | u64 blocknr; | 894 | u64 blocknr; |
819 | u64 search; | 895 | u64 search; |
820 | u64 cluster_start; | 896 | u64 cluster_start; |
@@ -823,7 +899,7 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | |||
823 | int direction = path->reada; | 899 | int direction = path->reada; |
824 | struct radix_tree_root found; | 900 | struct radix_tree_root found; |
825 | unsigned long gang[8]; | 901 | unsigned long gang[8]; |
826 | struct buffer_head *bh; | 902 | struct extent_buffer *eb; |
827 | 903 | ||
828 | if (level == 0) | 904 | if (level == 0) |
829 | return; | 905 | return; |
@@ -831,18 +907,17 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | |||
831 | if (!path->nodes[level]) | 907 | if (!path->nodes[level]) |
832 | return; | 908 | return; |
833 | 909 | ||
834 | node = btrfs_buffer_node(path->nodes[level]); | 910 | node = path->nodes[level]; |
835 | search = btrfs_node_blockptr(node, slot); | 911 | search = btrfs_node_blockptr(node, slot); |
836 | bh = btrfs_find_tree_block(root, search); | 912 | eb = btrfs_find_tree_block(root, search); |
837 | if (bh) { | 913 | if (eb) { |
838 | brelse(bh); | 914 | free_extent_buffer(eb); |
839 | return; | 915 | return; |
840 | } | 916 | } |
841 | 917 | ||
842 | init_bit_radix(&found); | 918 | init_bit_radix(&found); |
843 | nritems = btrfs_header_nritems(&node->header); | 919 | nritems = btrfs_header_nritems(node); |
844 | for (i = slot; i < nritems; i++) { | 920 | for (i = slot; i < nritems; i++) { |
845 | item_objectid = btrfs_disk_key_objectid(&node->ptrs[i].key); | ||
846 | blocknr = btrfs_node_blockptr(node, i); | 921 | blocknr = btrfs_node_blockptr(node, i); |
847 | set_radix_bit(&found, blocknr); | 922 | set_radix_bit(&found, blocknr); |
848 | } | 923 | } |
@@ -886,8 +961,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
886 | *root, struct btrfs_key *key, struct btrfs_path *p, int | 961 | *root, struct btrfs_key *key, struct btrfs_path *p, int |
887 | ins_len, int cow) | 962 | ins_len, int cow) |
888 | { | 963 | { |
889 | struct buffer_head *b; | 964 | struct extent_buffer *b; |
890 | struct btrfs_node *c; | ||
891 | u64 blocknr; | 965 | u64 blocknr; |
892 | int slot; | 966 | int slot; |
893 | int ret; | 967 | int ret; |
@@ -901,10 +975,9 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
901 | WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); | 975 | WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex)); |
902 | again: | 976 | again: |
903 | b = root->node; | 977 | b = root->node; |
904 | get_bh(b); | 978 | extent_buffer_get(b); |
905 | while (b) { | 979 | while (b) { |
906 | c = btrfs_buffer_node(b); | 980 | level = btrfs_header_level(b); |
907 | level = btrfs_header_level(&c->header); | ||
908 | if (cow) { | 981 | if (cow) { |
909 | int wret; | 982 | int wret; |
910 | wret = btrfs_cow_block(trans, root, b, | 983 | wret = btrfs_cow_block(trans, root, b, |
@@ -912,32 +985,30 @@ again: | |||
912 | p->slots[level + 1], | 985 | p->slots[level + 1], |
913 | &b); | 986 | &b); |
914 | if (wret) { | 987 | if (wret) { |
915 | btrfs_block_release(root, b); | 988 | free_extent_buffer(b); |
916 | return wret; | 989 | return wret; |
917 | } | 990 | } |
918 | c = btrfs_buffer_node(b); | ||
919 | } | 991 | } |
920 | BUG_ON(!cow && ins_len); | 992 | BUG_ON(!cow && ins_len); |
921 | if (level != btrfs_header_level(&c->header)) | 993 | if (level != btrfs_header_level(b)) |
922 | WARN_ON(1); | 994 | WARN_ON(1); |
923 | level = btrfs_header_level(&c->header); | 995 | level = btrfs_header_level(b); |
924 | p->nodes[level] = b; | 996 | p->nodes[level] = b; |
925 | ret = check_block(root, p, level); | 997 | ret = check_block(root, p, level); |
926 | if (ret) | 998 | if (ret) |
927 | return -1; | 999 | return -1; |
928 | ret = bin_search(c, key, &slot); | 1000 | ret = bin_search(b, key, level, &slot); |
929 | if (!btrfs_is_leaf(c)) { | 1001 | if (level != 0) { |
930 | if (ret && slot > 0) | 1002 | if (ret && slot > 0) |
931 | slot -= 1; | 1003 | slot -= 1; |
932 | p->slots[level] = slot; | 1004 | p->slots[level] = slot; |
933 | if (ins_len > 0 && btrfs_header_nritems(&c->header) >= | 1005 | if (ins_len > 0 && btrfs_header_nritems(b) >= |
934 | BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1006 | BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
935 | int sret = split_node(trans, root, p, level); | 1007 | int sret = split_node(trans, root, p, level); |
936 | BUG_ON(sret > 0); | 1008 | BUG_ON(sret > 0); |
937 | if (sret) | 1009 | if (sret) |
938 | return sret; | 1010 | return sret; |
939 | b = p->nodes[level]; | 1011 | b = p->nodes[level]; |
940 | c = btrfs_buffer_node(b); | ||
941 | slot = p->slots[level]; | 1012 | slot = p->slots[level]; |
942 | } else if (ins_len < 0) { | 1013 | } else if (ins_len < 0) { |
943 | int sret = balance_level(trans, root, p, | 1014 | int sret = balance_level(trans, root, p, |
@@ -947,22 +1018,19 @@ again: | |||
947 | b = p->nodes[level]; | 1018 | b = p->nodes[level]; |
948 | if (!b) | 1019 | if (!b) |
949 | goto again; | 1020 | goto again; |
950 | c = btrfs_buffer_node(b); | ||
951 | slot = p->slots[level]; | 1021 | slot = p->slots[level]; |
952 | BUG_ON(btrfs_header_nritems(&c->header) == 1); | 1022 | BUG_ON(btrfs_header_nritems(b) == 1); |
953 | } | 1023 | } |
954 | /* this is only true while dropping a snapshot */ | 1024 | /* this is only true while dropping a snapshot */ |
955 | if (level == lowest_level) | 1025 | if (level == lowest_level) |
956 | break; | 1026 | break; |
957 | blocknr = btrfs_node_blockptr(c, slot); | 1027 | blocknr = btrfs_node_blockptr(b, slot); |
958 | if (should_reada) | 1028 | if (should_reada) |
959 | reada_for_search(root, p, level, slot); | 1029 | reada_for_search(root, p, level, slot); |
960 | b = read_tree_block(root, btrfs_node_blockptr(c, slot)); | 1030 | b = read_tree_block(root, btrfs_node_blockptr(b, slot)); |
961 | |||
962 | } else { | 1031 | } else { |
963 | struct btrfs_leaf *l = (struct btrfs_leaf *)c; | ||
964 | p->slots[level] = slot; | 1032 | p->slots[level] = slot; |
965 | if (ins_len > 0 && btrfs_leaf_free_space(root, l) < | 1033 | if (ins_len > 0 && btrfs_leaf_free_space(root, b) < |
966 | sizeof(struct btrfs_item) + ins_len) { | 1034 | sizeof(struct btrfs_item) + ins_len) { |
967 | int sret = split_leaf(trans, root, key, | 1035 | int sret = split_leaf(trans, root, key, |
968 | p, ins_len); | 1036 | p, ins_len); |
@@ -986,19 +1054,20 @@ again: | |||
986 | * If this fails to write a tree block, it returns -1, but continues | 1054 | * If this fails to write a tree block, it returns -1, but continues |
987 | * fixing up the blocks in ram so the tree is consistent. | 1055 | * fixing up the blocks in ram so the tree is consistent. |
988 | */ | 1056 | */ |
989 | static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root | 1057 | static int fixup_low_keys(struct btrfs_trans_handle *trans, |
990 | *root, struct btrfs_path *path, struct btrfs_disk_key | 1058 | struct btrfs_root *root, struct btrfs_path *path, |
991 | *key, int level) | 1059 | struct btrfs_disk_key *key, int level) |
992 | { | 1060 | { |
993 | int i; | 1061 | int i; |
994 | int ret = 0; | 1062 | int ret = 0; |
1063 | struct extent_buffer *t; | ||
1064 | |||
995 | for (i = level; i < BTRFS_MAX_LEVEL; i++) { | 1065 | for (i = level; i < BTRFS_MAX_LEVEL; i++) { |
996 | struct btrfs_node *t; | ||
997 | int tslot = path->slots[i]; | 1066 | int tslot = path->slots[i]; |
998 | if (!path->nodes[i]) | 1067 | if (!path->nodes[i]) |
999 | break; | 1068 | break; |
1000 | t = btrfs_buffer_node(path->nodes[i]); | 1069 | t = path->nodes[i]; |
1001 | btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); | 1070 | btrfs_set_node_key(t, key, tslot); |
1002 | btrfs_mark_buffer_dirty(path->nodes[i]); | 1071 | btrfs_mark_buffer_dirty(path->nodes[i]); |
1003 | if (tslot != 0) | 1072 | if (tslot != 0) |
1004 | break; | 1073 | break; |
@@ -1014,18 +1083,16 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1014 | * error, and > 0 if there was no room in the left hand block. | 1083 | * error, and > 0 if there was no room in the left hand block. |
1015 | */ | 1084 | */ |
1016 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | 1085 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root |
1017 | *root, struct buffer_head *dst_buf, struct | 1086 | *root, struct extent_buffer *dst, |
1018 | buffer_head *src_buf) | 1087 | struct extent_buffer *src) |
1019 | { | 1088 | { |
1020 | struct btrfs_node *src = btrfs_buffer_node(src_buf); | ||
1021 | struct btrfs_node *dst = btrfs_buffer_node(dst_buf); | ||
1022 | int push_items = 0; | 1089 | int push_items = 0; |
1023 | int src_nritems; | 1090 | int src_nritems; |
1024 | int dst_nritems; | 1091 | int dst_nritems; |
1025 | int ret = 0; | 1092 | int ret = 0; |
1026 | 1093 | ||
1027 | src_nritems = btrfs_header_nritems(&src->header); | 1094 | src_nritems = btrfs_header_nritems(src); |
1028 | dst_nritems = btrfs_header_nritems(&dst->header); | 1095 | dst_nritems = btrfs_header_nritems(dst); |
1029 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; | 1096 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; |
1030 | 1097 | ||
1031 | if (push_items <= 0) { | 1098 | if (push_items <= 0) { |
@@ -1035,17 +1102,21 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1035 | if (src_nritems < push_items) | 1102 | if (src_nritems < push_items) |
1036 | push_items = src_nritems; | 1103 | push_items = src_nritems; |
1037 | 1104 | ||
1038 | btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, | 1105 | copy_extent_buffer(dst, src, |
1039 | push_items * sizeof(struct btrfs_key_ptr)); | 1106 | btrfs_node_key_ptr_offset(dst_nritems), |
1107 | btrfs_node_key_ptr_offset(0), | ||
1108 | push_items * sizeof(struct btrfs_key_ptr)); | ||
1109 | |||
1040 | if (push_items < src_nritems) { | 1110 | if (push_items < src_nritems) { |
1041 | btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, | 1111 | memmove_extent_buffer(src, btrfs_node_key_ptr_offset(0), |
1042 | (src_nritems - push_items) * | 1112 | btrfs_node_key_ptr_offset(push_items), |
1043 | sizeof(struct btrfs_key_ptr)); | 1113 | (src_nritems - push_items) * |
1044 | } | 1114 | sizeof(struct btrfs_key_ptr)); |
1045 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); | 1115 | } |
1046 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); | 1116 | btrfs_set_header_nritems(src, src_nritems - push_items); |
1047 | btrfs_mark_buffer_dirty(src_buf); | 1117 | btrfs_set_header_nritems(dst, dst_nritems + push_items); |
1048 | btrfs_mark_buffer_dirty(dst_buf); | 1118 | btrfs_mark_buffer_dirty(src); |
1119 | btrfs_mark_buffer_dirty(dst); | ||
1049 | return ret; | 1120 | return ret; |
1050 | } | 1121 | } |
1051 | 1122 | ||
@@ -1058,24 +1129,22 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1058 | * | 1129 | * |
1059 | * this will only push up to 1/2 the contents of the left node over | 1130 | * this will only push up to 1/2 the contents of the left node over |
1060 | */ | 1131 | */ |
1061 | static int balance_node_right(struct btrfs_trans_handle *trans, struct | 1132 | static int balance_node_right(struct btrfs_trans_handle *trans, |
1062 | btrfs_root *root, struct buffer_head *dst_buf, | 1133 | struct btrfs_root *root, |
1063 | struct buffer_head *src_buf) | 1134 | struct extent_buffer *dst, |
1135 | struct extent_buffer *src) | ||
1064 | { | 1136 | { |
1065 | struct btrfs_node *src = btrfs_buffer_node(src_buf); | ||
1066 | struct btrfs_node *dst = btrfs_buffer_node(dst_buf); | ||
1067 | int push_items = 0; | 1137 | int push_items = 0; |
1068 | int max_push; | 1138 | int max_push; |
1069 | int src_nritems; | 1139 | int src_nritems; |
1070 | int dst_nritems; | 1140 | int dst_nritems; |
1071 | int ret = 0; | 1141 | int ret = 0; |
1072 | 1142 | ||
1073 | src_nritems = btrfs_header_nritems(&src->header); | 1143 | src_nritems = btrfs_header_nritems(src); |
1074 | dst_nritems = btrfs_header_nritems(&dst->header); | 1144 | dst_nritems = btrfs_header_nritems(dst); |
1075 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; | 1145 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; |
1076 | if (push_items <= 0) { | 1146 | if (push_items <= 0) |
1077 | return 1; | 1147 | return 1; |
1078 | } | ||
1079 | 1148 | ||
1080 | max_push = src_nritems / 2 + 1; | 1149 | max_push = src_nritems / 2 + 1; |
1081 | /* don't try to empty the node */ | 1150 | /* don't try to empty the node */ |
@@ -1085,18 +1154,21 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct | |||
1085 | if (max_push < push_items) | 1154 | if (max_push < push_items) |
1086 | push_items = max_push; | 1155 | push_items = max_push; |
1087 | 1156 | ||
1088 | btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, | 1157 | memmove_extent_buffer(dst, btrfs_node_key_ptr_offset(push_items), |
1089 | dst_nritems * sizeof(struct btrfs_key_ptr)); | 1158 | btrfs_node_key_ptr_offset(0), |
1159 | (dst_nritems) * | ||
1160 | sizeof(struct btrfs_key_ptr)); | ||
1090 | 1161 | ||
1091 | btrfs_memcpy(root, dst, dst->ptrs, | 1162 | copy_extent_buffer(dst, src, |
1092 | src->ptrs + src_nritems - push_items, | 1163 | btrfs_node_key_ptr_offset(0), |
1093 | push_items * sizeof(struct btrfs_key_ptr)); | 1164 | btrfs_node_key_ptr_offset(src_nritems - push_items), |
1165 | push_items * sizeof(struct btrfs_key_ptr)); | ||
1094 | 1166 | ||
1095 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); | 1167 | btrfs_set_header_nritems(src, src_nritems - push_items); |
1096 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); | 1168 | btrfs_set_header_nritems(dst, dst_nritems + push_items); |
1097 | 1169 | ||
1098 | btrfs_mark_buffer_dirty(src_buf); | 1170 | btrfs_mark_buffer_dirty(src); |
1099 | btrfs_mark_buffer_dirty(dst_buf); | 1171 | btrfs_mark_buffer_dirty(dst); |
1100 | return ret; | 1172 | return ret; |
1101 | } | 1173 | } |
1102 | 1174 | ||
@@ -1107,45 +1179,46 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct | |||
1107 | * | 1179 | * |
1108 | * returns zero on success or < 0 on failure. | 1180 | * returns zero on success or < 0 on failure. |
1109 | */ | 1181 | */ |
1110 | static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root | 1182 | static int insert_new_root(struct btrfs_trans_handle *trans, |
1111 | *root, struct btrfs_path *path, int level) | 1183 | struct btrfs_root *root, |
1184 | struct btrfs_path *path, int level) | ||
1112 | { | 1185 | { |
1113 | struct buffer_head *t; | 1186 | struct extent_buffer *lower; |
1114 | struct btrfs_node *lower; | 1187 | struct extent_buffer *c; |
1115 | struct btrfs_node *c; | 1188 | struct btrfs_disk_key lower_key; |
1116 | struct btrfs_disk_key *lower_key; | ||
1117 | 1189 | ||
1118 | BUG_ON(path->nodes[level]); | 1190 | BUG_ON(path->nodes[level]); |
1119 | BUG_ON(path->nodes[level-1] != root->node); | 1191 | BUG_ON(path->nodes[level-1] != root->node); |
1120 | 1192 | ||
1121 | t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr, 0); | 1193 | c = btrfs_alloc_free_block(trans, root, |
1122 | if (IS_ERR(t)) | 1194 | extent_buffer_blocknr(root->node), 0); |
1123 | return PTR_ERR(t); | 1195 | if (IS_ERR(c)) |
1124 | c = btrfs_buffer_node(t); | 1196 | return PTR_ERR(c); |
1125 | memset(c, 0, root->blocksize); | 1197 | memset_extent_buffer(c, 0, 0, root->nodesize); |
1126 | btrfs_set_header_nritems(&c->header, 1); | 1198 | btrfs_set_header_nritems(c, 1); |
1127 | btrfs_set_header_level(&c->header, level); | 1199 | btrfs_set_header_level(c, level); |
1128 | btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); | 1200 | btrfs_set_header_blocknr(c, extent_buffer_blocknr(c)); |
1129 | btrfs_set_header_generation(&c->header, trans->transid); | 1201 | btrfs_set_header_generation(c, trans->transid); |
1130 | btrfs_set_header_owner(&c->header, root->root_key.objectid); | 1202 | btrfs_set_header_owner(c, root->root_key.objectid); |
1131 | lower = btrfs_buffer_node(path->nodes[level-1]); | 1203 | lower = path->nodes[level-1]; |
1132 | memcpy(c->header.fsid, root->fs_info->disk_super->fsid, | 1204 | |
1133 | sizeof(c->header.fsid)); | 1205 | write_extent_buffer(c, root->fs_info->fsid, |
1134 | if (btrfs_is_leaf(lower)) | 1206 | (unsigned long)btrfs_header_fsid(c), |
1135 | lower_key = &((struct btrfs_leaf *)lower)->items[0].key; | 1207 | BTRFS_FSID_SIZE); |
1208 | if (level == 1) | ||
1209 | btrfs_item_key(lower, &lower_key, 0); | ||
1136 | else | 1210 | else |
1137 | lower_key = &lower->ptrs[0].key; | 1211 | btrfs_node_key(lower, &lower_key, 0); |
1138 | btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, | 1212 | btrfs_set_node_key(c, &lower_key, 0); |
1139 | sizeof(struct btrfs_disk_key)); | 1213 | btrfs_set_node_blockptr(c, 0, extent_buffer_blocknr(lower)); |
1140 | btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1])); | ||
1141 | 1214 | ||
1142 | btrfs_mark_buffer_dirty(t); | 1215 | btrfs_mark_buffer_dirty(c); |
1143 | 1216 | ||
1144 | /* the super has an extra ref to root->node */ | 1217 | /* the super has an extra ref to root->node */ |
1145 | btrfs_block_release(root, root->node); | 1218 | free_extent_buffer(root->node); |
1146 | root->node = t; | 1219 | root->node = c; |
1147 | get_bh(t); | 1220 | extent_buffer_get(c); |
1148 | path->nodes[level] = t; | 1221 | path->nodes[level] = c; |
1149 | path->slots[level] = 0; | 1222 | path->slots[level] = 0; |
1150 | return 0; | 1223 | return 0; |
1151 | } | 1224 | } |
@@ -1163,26 +1236,26 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1163 | *root, struct btrfs_path *path, struct btrfs_disk_key | 1236 | *root, struct btrfs_path *path, struct btrfs_disk_key |
1164 | *key, u64 blocknr, int slot, int level) | 1237 | *key, u64 blocknr, int slot, int level) |
1165 | { | 1238 | { |
1166 | struct btrfs_node *lower; | 1239 | struct extent_buffer *lower; |
1167 | int nritems; | 1240 | int nritems; |
1168 | 1241 | ||
1169 | BUG_ON(!path->nodes[level]); | 1242 | BUG_ON(!path->nodes[level]); |
1170 | lower = btrfs_buffer_node(path->nodes[level]); | 1243 | lower = path->nodes[level]; |
1171 | nritems = btrfs_header_nritems(&lower->header); | 1244 | nritems = btrfs_header_nritems(lower); |
1172 | if (slot > nritems) | 1245 | if (slot > nritems) |
1173 | BUG(); | 1246 | BUG(); |
1174 | if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) | 1247 | if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) |
1175 | BUG(); | 1248 | BUG(); |
1176 | if (slot != nritems) { | 1249 | if (slot != nritems) { |
1177 | btrfs_memmove(root, lower, lower->ptrs + slot + 1, | 1250 | memmove_extent_buffer(lower, |
1178 | lower->ptrs + slot, | 1251 | btrfs_node_key_ptr_offset(slot + 1), |
1252 | btrfs_node_key_ptr_offset(slot), | ||
1179 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); | 1253 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); |
1180 | } | 1254 | } |
1181 | btrfs_memcpy(root, lower, &lower->ptrs[slot].key, | 1255 | btrfs_set_node_key(lower, key, slot); |
1182 | key, sizeof(struct btrfs_disk_key)); | ||
1183 | btrfs_set_node_blockptr(lower, slot, blocknr); | 1256 | btrfs_set_node_blockptr(lower, slot, blocknr); |
1184 | btrfs_set_header_nritems(&lower->header, nritems + 1); | 1257 | btrfs_set_header_nritems(lower, nritems + 1); |
1185 | btrfs_mark_buffer_dirty(path->nodes[level]); | 1258 | btrfs_mark_buffer_dirty(lower); |
1186 | check_node(root, path, level); | 1259 | check_node(root, path, level); |
1187 | return 0; | 1260 | return 0; |
1188 | } | 1261 | } |
@@ -1199,69 +1272,73 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1199 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | 1272 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root |
1200 | *root, struct btrfs_path *path, int level) | 1273 | *root, struct btrfs_path *path, int level) |
1201 | { | 1274 | { |
1202 | struct buffer_head *t; | 1275 | struct extent_buffer *c; |
1203 | struct btrfs_node *c; | 1276 | struct extent_buffer *split; |
1204 | struct buffer_head *split_buffer; | 1277 | struct btrfs_disk_key disk_key; |
1205 | struct btrfs_node *split; | ||
1206 | int mid; | 1278 | int mid; |
1207 | int ret; | 1279 | int ret; |
1208 | int wret; | 1280 | int wret; |
1209 | u32 c_nritems; | 1281 | u32 c_nritems; |
1210 | 1282 | ||
1211 | t = path->nodes[level]; | 1283 | c = path->nodes[level]; |
1212 | c = btrfs_buffer_node(t); | 1284 | if (c == root->node) { |
1213 | if (t == root->node) { | ||
1214 | /* trying to split the root, lets make a new one */ | 1285 | /* trying to split the root, lets make a new one */ |
1215 | ret = insert_new_root(trans, root, path, level + 1); | 1286 | ret = insert_new_root(trans, root, path, level + 1); |
1216 | if (ret) | 1287 | if (ret) |
1217 | return ret; | 1288 | return ret; |
1218 | } else { | 1289 | } else { |
1219 | ret = push_nodes_for_insert(trans, root, path, level); | 1290 | ret = push_nodes_for_insert(trans, root, path, level); |
1220 | t = path->nodes[level]; | 1291 | c = path->nodes[level]; |
1221 | c = btrfs_buffer_node(t); | 1292 | if (!ret && btrfs_header_nritems(c) < |
1222 | if (!ret && | ||
1223 | btrfs_header_nritems(&c->header) < | ||
1224 | BTRFS_NODEPTRS_PER_BLOCK(root) - 1) | 1293 | BTRFS_NODEPTRS_PER_BLOCK(root) - 1) |
1225 | return 0; | 1294 | return 0; |
1226 | if (ret < 0) | 1295 | if (ret < 0) |
1227 | return ret; | 1296 | return ret; |
1228 | } | 1297 | } |
1229 | 1298 | ||
1230 | c_nritems = btrfs_header_nritems(&c->header); | 1299 | c_nritems = btrfs_header_nritems(c); |
1231 | split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr, 0); | 1300 | split = btrfs_alloc_free_block(trans, root, |
1232 | if (IS_ERR(split_buffer)) | 1301 | extent_buffer_blocknr(c), 0); |
1233 | return PTR_ERR(split_buffer); | 1302 | if (IS_ERR(split)) |
1303 | return PTR_ERR(split); | ||
1304 | |||
1305 | btrfs_set_header_flags(split, btrfs_header_flags(c)); | ||
1306 | btrfs_set_header_level(split, btrfs_header_level(c)); | ||
1307 | btrfs_set_header_blocknr(split, extent_buffer_blocknr(split)); | ||
1308 | btrfs_set_header_generation(split, trans->transid); | ||
1309 | btrfs_set_header_owner(split, root->root_key.objectid); | ||
1310 | write_extent_buffer(split, root->fs_info->fsid, | ||
1311 | (unsigned long)btrfs_header_fsid(split), | ||
1312 | BTRFS_FSID_SIZE); | ||
1234 | 1313 | ||
1235 | split = btrfs_buffer_node(split_buffer); | ||
1236 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); | ||
1237 | btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); | ||
1238 | btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); | ||
1239 | btrfs_set_header_generation(&split->header, trans->transid); | ||
1240 | btrfs_set_header_owner(&split->header, root->root_key.objectid); | ||
1241 | memcpy(split->header.fsid, root->fs_info->disk_super->fsid, | ||
1242 | sizeof(split->header.fsid)); | ||
1243 | mid = (c_nritems + 1) / 2; | 1314 | mid = (c_nritems + 1) / 2; |
1244 | btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, | 1315 | |
1245 | (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); | 1316 | copy_extent_buffer(split, c, |
1246 | btrfs_set_header_nritems(&split->header, c_nritems - mid); | 1317 | btrfs_node_key_ptr_offset(0), |
1247 | btrfs_set_header_nritems(&c->header, mid); | 1318 | btrfs_node_key_ptr_offset(mid), |
1319 | (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); | ||
1320 | btrfs_set_header_nritems(split, c_nritems - mid); | ||
1321 | btrfs_set_header_nritems(c, mid); | ||
1248 | ret = 0; | 1322 | ret = 0; |
1249 | 1323 | ||
1250 | btrfs_mark_buffer_dirty(t); | 1324 | btrfs_mark_buffer_dirty(c); |
1251 | btrfs_mark_buffer_dirty(split_buffer); | 1325 | btrfs_mark_buffer_dirty(split); |
1252 | wret = insert_ptr(trans, root, path, &split->ptrs[0].key, | 1326 | |
1253 | bh_blocknr(split_buffer), path->slots[level + 1] + 1, | 1327 | btrfs_node_key(split, &disk_key, 0); |
1328 | wret = insert_ptr(trans, root, path, &disk_key, | ||
1329 | extent_buffer_blocknr(split), | ||
1330 | path->slots[level + 1] + 1, | ||
1254 | level + 1); | 1331 | level + 1); |
1255 | if (wret) | 1332 | if (wret) |
1256 | ret = wret; | 1333 | ret = wret; |
1257 | 1334 | ||
1258 | if (path->slots[level] >= mid) { | 1335 | if (path->slots[level] >= mid) { |
1259 | path->slots[level] -= mid; | 1336 | path->slots[level] -= mid; |
1260 | btrfs_block_release(root, t); | 1337 | free_extent_buffer(c); |
1261 | path->nodes[level] = split_buffer; | 1338 | path->nodes[level] = split; |
1262 | path->slots[level + 1] += 1; | 1339 | path->slots[level + 1] += 1; |
1263 | } else { | 1340 | } else { |
1264 | btrfs_block_release(root, split_buffer); | 1341 | free_extent_buffer(split); |
1265 | } | 1342 | } |
1266 | return ret; | 1343 | return ret; |
1267 | } | 1344 | } |
@@ -1271,16 +1348,16 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1271 | * and nr indicate which items in the leaf to check. This totals up the | 1348 | * and nr indicate which items in the leaf to check. This totals up the |
1272 | * space used both by the item structs and the item data | 1349 | * space used both by the item structs and the item data |
1273 | */ | 1350 | */ |
1274 | static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) | 1351 | static int leaf_space_used(struct extent_buffer *l, int start, int nr) |
1275 | { | 1352 | { |
1276 | int data_len; | 1353 | int data_len; |
1277 | int nritems = btrfs_header_nritems(&l->header); | 1354 | int nritems = btrfs_header_nritems(l); |
1278 | int end = min(nritems, start + nr) - 1; | 1355 | int end = min(nritems, start + nr) - 1; |
1279 | 1356 | ||
1280 | if (!nr) | 1357 | if (!nr) |
1281 | return 0; | 1358 | return 0; |
1282 | data_len = btrfs_item_end(l->items + start); | 1359 | data_len = btrfs_item_end_nr(l, start); |
1283 | data_len = data_len - btrfs_item_offset(l->items + end); | 1360 | data_len = data_len - btrfs_item_offset_nr(l, end); |
1284 | data_len += sizeof(struct btrfs_item) * nr; | 1361 | data_len += sizeof(struct btrfs_item) * nr; |
1285 | WARN_ON(data_len < 0); | 1362 | WARN_ON(data_len < 0); |
1286 | return data_len; | 1363 | return data_len; |
@@ -1291,10 +1368,17 @@ static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) | |||
1291 | * the start of the leaf data. IOW, how much room | 1368 | * the start of the leaf data. IOW, how much room |
1292 | * the leaf has left for both items and data | 1369 | * the leaf has left for both items and data |
1293 | */ | 1370 | */ |
1294 | int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) | 1371 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf) |
1295 | { | 1372 | { |
1296 | int nritems = btrfs_header_nritems(&leaf->header); | 1373 | int nritems = btrfs_header_nritems(leaf); |
1297 | return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); | 1374 | int ret; |
1375 | ret = BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems); | ||
1376 | if (ret < 0) { | ||
1377 | printk("leaf free space ret %d, leaf data size %lu, used %d nritems %d\n", | ||
1378 | ret, BTRFS_LEAF_DATA_SIZE(root), | ||
1379 | leaf_space_used(leaf, 0, nritems), nritems); | ||
1380 | } | ||
1381 | return ret; | ||
1298 | } | 1382 | } |
1299 | 1383 | ||
1300 | /* | 1384 | /* |
@@ -1307,12 +1391,10 @@ int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf) | |||
1307 | static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | 1391 | static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root |
1308 | *root, struct btrfs_path *path, int data_size) | 1392 | *root, struct btrfs_path *path, int data_size) |
1309 | { | 1393 | { |
1310 | struct buffer_head *left_buf = path->nodes[0]; | 1394 | struct extent_buffer *left = path->nodes[0]; |
1311 | struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); | 1395 | struct extent_buffer *right; |
1312 | struct btrfs_leaf *right; | 1396 | struct extent_buffer *upper; |
1313 | struct buffer_head *right_buf; | 1397 | struct btrfs_disk_key disk_key; |
1314 | struct buffer_head *upper; | ||
1315 | struct btrfs_node *upper_node; | ||
1316 | int slot; | 1398 | int slot; |
1317 | int i; | 1399 | int i; |
1318 | int free_space; | 1400 | int free_space; |
@@ -1321,6 +1403,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1321 | struct btrfs_item *item; | 1403 | struct btrfs_item *item; |
1322 | u32 left_nritems; | 1404 | u32 left_nritems; |
1323 | u32 right_nritems; | 1405 | u32 right_nritems; |
1406 | u32 data_end; | ||
1324 | int ret; | 1407 | int ret; |
1325 | 1408 | ||
1326 | slot = path->slots[1]; | 1409 | slot = path->slots[1]; |
@@ -1328,102 +1411,109 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1328 | return 1; | 1411 | return 1; |
1329 | } | 1412 | } |
1330 | upper = path->nodes[1]; | 1413 | upper = path->nodes[1]; |
1331 | upper_node = btrfs_buffer_node(upper); | 1414 | if (slot >= btrfs_header_nritems(upper) - 1) |
1332 | if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { | ||
1333 | return 1; | 1415 | return 1; |
1334 | } | 1416 | |
1335 | right_buf = read_tree_block(root, | 1417 | right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1)); |
1336 | btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); | ||
1337 | right = btrfs_buffer_leaf(right_buf); | ||
1338 | free_space = btrfs_leaf_free_space(root, right); | 1418 | free_space = btrfs_leaf_free_space(root, right); |
1339 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 1419 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
1340 | btrfs_block_release(root, right_buf); | 1420 | free_extent_buffer(right); |
1341 | return 1; | 1421 | return 1; |
1342 | } | 1422 | } |
1423 | |||
1343 | /* cow and double check */ | 1424 | /* cow and double check */ |
1344 | ret = btrfs_cow_block(trans, root, right_buf, upper, | 1425 | ret = btrfs_cow_block(trans, root, right, upper, |
1345 | slot + 1, &right_buf); | 1426 | slot + 1, &right); |
1346 | if (ret) { | 1427 | if (ret) { |
1347 | btrfs_block_release(root, right_buf); | 1428 | free_extent_buffer(right); |
1348 | return 1; | 1429 | return 1; |
1349 | } | 1430 | } |
1350 | right = btrfs_buffer_leaf(right_buf); | ||
1351 | free_space = btrfs_leaf_free_space(root, right); | 1431 | free_space = btrfs_leaf_free_space(root, right); |
1352 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 1432 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
1353 | btrfs_block_release(root, right_buf); | 1433 | free_extent_buffer(right); |
1354 | return 1; | 1434 | return 1; |
1355 | } | 1435 | } |
1356 | 1436 | ||
1357 | left_nritems = btrfs_header_nritems(&left->header); | 1437 | left_nritems = btrfs_header_nritems(left); |
1358 | if (left_nritems == 0) { | 1438 | if (left_nritems == 0) { |
1359 | btrfs_block_release(root, right_buf); | 1439 | free_extent_buffer(right); |
1360 | return 1; | 1440 | return 1; |
1361 | } | 1441 | } |
1442 | |||
1362 | for (i = left_nritems - 1; i >= 1; i--) { | 1443 | for (i = left_nritems - 1; i >= 1; i--) { |
1363 | item = left->items + i; | 1444 | item = btrfs_item_nr(left, i); |
1364 | if (path->slots[0] == i) | 1445 | if (path->slots[0] == i) |
1365 | push_space += data_size + sizeof(*item); | 1446 | push_space += data_size + sizeof(*item); |
1366 | if (btrfs_item_size(item) + sizeof(*item) + push_space > | 1447 | if (btrfs_item_size(left, item) + sizeof(*item) + push_space > |
1367 | free_space) | 1448 | free_space) |
1368 | break; | 1449 | break; |
1369 | push_items++; | 1450 | push_items++; |
1370 | push_space += btrfs_item_size(item) + sizeof(*item); | 1451 | push_space += btrfs_item_size(left, item) + sizeof(*item); |
1371 | } | 1452 | } |
1453 | |||
1372 | if (push_items == 0) { | 1454 | if (push_items == 0) { |
1373 | btrfs_block_release(root, right_buf); | 1455 | free_extent_buffer(right); |
1374 | return 1; | 1456 | return 1; |
1375 | } | 1457 | } |
1458 | |||
1376 | if (push_items == left_nritems) | 1459 | if (push_items == left_nritems) |
1377 | WARN_ON(1); | 1460 | WARN_ON(1); |
1378 | right_nritems = btrfs_header_nritems(&right->header); | 1461 | |
1379 | /* push left to right */ | 1462 | /* push left to right */ |
1380 | push_space = btrfs_item_end(left->items + left_nritems - push_items); | 1463 | right_nritems = btrfs_header_nritems(right); |
1464 | push_space = btrfs_item_end_nr(left, left_nritems - push_items); | ||
1381 | push_space -= leaf_data_end(root, left); | 1465 | push_space -= leaf_data_end(root, left); |
1466 | |||
1382 | /* make room in the right data area */ | 1467 | /* make room in the right data area */ |
1383 | btrfs_memmove(root, right, btrfs_leaf_data(right) + | 1468 | data_end = leaf_data_end(root, right); |
1384 | leaf_data_end(root, right) - push_space, | 1469 | memmove_extent_buffer(right, |
1385 | btrfs_leaf_data(right) + | 1470 | btrfs_leaf_data(right) + data_end - push_space, |
1386 | leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - | 1471 | btrfs_leaf_data(right) + data_end, |
1387 | leaf_data_end(root, right)); | 1472 | BTRFS_LEAF_DATA_SIZE(root) - data_end); |
1473 | |||
1388 | /* copy from the left data area */ | 1474 | /* copy from the left data area */ |
1389 | btrfs_memcpy(root, right, btrfs_leaf_data(right) + | 1475 | copy_extent_buffer(right, left, btrfs_leaf_data(right) + |
1390 | BTRFS_LEAF_DATA_SIZE(root) - push_space, | 1476 | BTRFS_LEAF_DATA_SIZE(root) - push_space, |
1391 | btrfs_leaf_data(left) + leaf_data_end(root, left), | 1477 | btrfs_leaf_data(left) + leaf_data_end(root, left), |
1392 | push_space); | 1478 | push_space); |
1393 | btrfs_memmove(root, right, right->items + push_items, right->items, | 1479 | |
1394 | right_nritems * sizeof(struct btrfs_item)); | 1480 | memmove_extent_buffer(right, btrfs_item_nr_offset(push_items), |
1481 | btrfs_item_nr_offset(0), | ||
1482 | right_nritems * sizeof(struct btrfs_item)); | ||
1483 | |||
1395 | /* copy the items from left to right */ | 1484 | /* copy the items from left to right */ |
1396 | btrfs_memcpy(root, right, right->items, left->items + | 1485 | copy_extent_buffer(right, left, btrfs_item_nr_offset(0), |
1397 | left_nritems - push_items, | 1486 | btrfs_item_nr_offset(left_nritems - push_items), |
1398 | push_items * sizeof(struct btrfs_item)); | 1487 | push_items * sizeof(struct btrfs_item)); |
1399 | 1488 | ||
1400 | /* update the item pointers */ | 1489 | /* update the item pointers */ |
1401 | right_nritems += push_items; | 1490 | right_nritems += push_items; |
1402 | btrfs_set_header_nritems(&right->header, right_nritems); | 1491 | btrfs_set_header_nritems(right, right_nritems); |
1403 | push_space = BTRFS_LEAF_DATA_SIZE(root); | 1492 | push_space = BTRFS_LEAF_DATA_SIZE(root); |
1404 | for (i = 0; i < right_nritems; i++) { | 1493 | for (i = 0; i < right_nritems; i++) { |
1405 | btrfs_set_item_offset(right->items + i, push_space - | 1494 | item = btrfs_item_nr(right, i); |
1406 | btrfs_item_size(right->items + i)); | 1495 | btrfs_set_item_offset(right, item, push_space - |
1407 | push_space = btrfs_item_offset(right->items + i); | 1496 | btrfs_item_size(right, item)); |
1497 | push_space = btrfs_item_offset(right, item); | ||
1408 | } | 1498 | } |
1409 | left_nritems -= push_items; | 1499 | left_nritems -= push_items; |
1410 | btrfs_set_header_nritems(&left->header, left_nritems); | 1500 | btrfs_set_header_nritems(left, left_nritems); |
1411 | 1501 | ||
1412 | btrfs_mark_buffer_dirty(left_buf); | 1502 | btrfs_mark_buffer_dirty(left); |
1413 | btrfs_mark_buffer_dirty(right_buf); | 1503 | btrfs_mark_buffer_dirty(right); |
1414 | 1504 | ||
1415 | btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, | 1505 | btrfs_item_key(right, &disk_key, 0); |
1416 | &right->items[0].key, sizeof(struct btrfs_disk_key)); | 1506 | btrfs_set_node_key(upper, &disk_key, slot + 1); |
1417 | btrfs_mark_buffer_dirty(upper); | 1507 | btrfs_mark_buffer_dirty(upper); |
1418 | 1508 | ||
1419 | /* then fixup the leaf pointer in the path */ | 1509 | /* then fixup the leaf pointer in the path */ |
1420 | if (path->slots[0] >= left_nritems) { | 1510 | if (path->slots[0] >= left_nritems) { |
1421 | path->slots[0] -= left_nritems; | 1511 | path->slots[0] -= left_nritems; |
1422 | btrfs_block_release(root, path->nodes[0]); | 1512 | free_extent_buffer(path->nodes[0]); |
1423 | path->nodes[0] = right_buf; | 1513 | path->nodes[0] = right; |
1424 | path->slots[1] += 1; | 1514 | path->slots[1] += 1; |
1425 | } else { | 1515 | } else { |
1426 | btrfs_block_release(root, right_buf); | 1516 | free_extent_buffer(right); |
1427 | } | 1517 | } |
1428 | if (path->nodes[1]) | 1518 | if (path->nodes[1]) |
1429 | check_node(root, path, 1); | 1519 | check_node(root, path, 1); |
@@ -1436,10 +1526,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1436 | static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | 1526 | static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root |
1437 | *root, struct btrfs_path *path, int data_size) | 1527 | *root, struct btrfs_path *path, int data_size) |
1438 | { | 1528 | { |
1439 | struct buffer_head *right_buf = path->nodes[0]; | 1529 | struct btrfs_disk_key disk_key; |
1440 | struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); | 1530 | struct extent_buffer *right = path->nodes[0]; |
1441 | struct buffer_head *t; | 1531 | struct extent_buffer *left; |
1442 | struct btrfs_leaf *left; | ||
1443 | int slot; | 1532 | int slot; |
1444 | int i; | 1533 | int i; |
1445 | int free_space; | 1534 | int free_space; |
@@ -1447,119 +1536,128 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1447 | int push_items = 0; | 1536 | int push_items = 0; |
1448 | struct btrfs_item *item; | 1537 | struct btrfs_item *item; |
1449 | u32 old_left_nritems; | 1538 | u32 old_left_nritems; |
1539 | u32 right_nritems; | ||
1450 | int ret = 0; | 1540 | int ret = 0; |
1451 | int wret; | 1541 | int wret; |
1452 | 1542 | ||
1453 | slot = path->slots[1]; | 1543 | slot = path->slots[1]; |
1454 | if (slot == 0) { | 1544 | if (slot == 0) |
1455 | return 1; | 1545 | return 1; |
1456 | } | 1546 | if (!path->nodes[1]) |
1457 | if (!path->nodes[1]) { | ||
1458 | return 1; | 1547 | return 1; |
1459 | } | 1548 | |
1460 | t = read_tree_block(root, | 1549 | left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1], |
1461 | btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); | 1550 | slot - 1)); |
1462 | left = btrfs_buffer_leaf(t); | ||
1463 | free_space = btrfs_leaf_free_space(root, left); | 1551 | free_space = btrfs_leaf_free_space(root, left); |
1464 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 1552 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
1465 | btrfs_block_release(root, t); | 1553 | free_extent_buffer(left); |
1466 | return 1; | 1554 | return 1; |
1467 | } | 1555 | } |
1468 | 1556 | ||
1469 | /* cow and double check */ | 1557 | /* cow and double check */ |
1470 | ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); | 1558 | ret = btrfs_cow_block(trans, root, left, |
1559 | path->nodes[1], slot - 1, &left); | ||
1471 | if (ret) { | 1560 | if (ret) { |
1472 | /* we hit -ENOSPC, but it isn't fatal here */ | 1561 | /* we hit -ENOSPC, but it isn't fatal here */ |
1473 | btrfs_block_release(root, t); | 1562 | free_extent_buffer(left); |
1474 | return 1; | 1563 | return 1; |
1475 | } | 1564 | } |
1476 | left = btrfs_buffer_leaf(t); | ||
1477 | free_space = btrfs_leaf_free_space(root, left); | 1565 | free_space = btrfs_leaf_free_space(root, left); |
1478 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 1566 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
1479 | btrfs_block_release(root, t); | 1567 | free_extent_buffer(left); |
1480 | return 1; | 1568 | return 1; |
1481 | } | 1569 | } |
1482 | 1570 | ||
1483 | if (btrfs_header_nritems(&right->header) == 0) { | 1571 | right_nritems = btrfs_header_nritems(right); |
1484 | btrfs_block_release(root, t); | 1572 | if (right_nritems == 0) { |
1573 | free_extent_buffer(left); | ||
1485 | return 1; | 1574 | return 1; |
1486 | } | 1575 | } |
1487 | 1576 | ||
1488 | for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) { | 1577 | for (i = 0; i < right_nritems - 1; i++) { |
1489 | item = right->items + i; | 1578 | item = btrfs_item_nr(right, i); |
1490 | if (path->slots[0] == i) | 1579 | if (path->slots[0] == i) |
1491 | push_space += data_size + sizeof(*item); | 1580 | push_space += data_size + sizeof(*item); |
1492 | if (btrfs_item_size(item) + sizeof(*item) + push_space > | 1581 | if (btrfs_item_size(right, item) + sizeof(*item) + push_space > |
1493 | free_space) | 1582 | free_space) |
1494 | break; | 1583 | break; |
1495 | push_items++; | 1584 | push_items++; |
1496 | push_space += btrfs_item_size(item) + sizeof(*item); | 1585 | push_space += btrfs_item_size(right, item) + sizeof(*item); |
1497 | } | 1586 | } |
1498 | if (push_items == 0) { | 1587 | if (push_items == 0) { |
1499 | btrfs_block_release(root, t); | 1588 | free_extent_buffer(left); |
1500 | return 1; | 1589 | return 1; |
1501 | } | 1590 | } |
1502 | if (push_items == btrfs_header_nritems(&right->header)) | 1591 | if (push_items == btrfs_header_nritems(right)) |
1503 | WARN_ON(1); | 1592 | WARN_ON(1); |
1593 | |||
1504 | /* push data from right to left */ | 1594 | /* push data from right to left */ |
1505 | btrfs_memcpy(root, left, left->items + | 1595 | copy_extent_buffer(left, right, |
1506 | btrfs_header_nritems(&left->header), | 1596 | btrfs_item_nr_offset(btrfs_header_nritems(left)), |
1507 | right->items, push_items * sizeof(struct btrfs_item)); | 1597 | btrfs_item_nr_offset(0), |
1598 | push_items * sizeof(struct btrfs_item)); | ||
1599 | |||
1508 | push_space = BTRFS_LEAF_DATA_SIZE(root) - | 1600 | push_space = BTRFS_LEAF_DATA_SIZE(root) - |
1509 | btrfs_item_offset(right->items + push_items -1); | 1601 | btrfs_item_offset_nr(right, push_items -1); |
1510 | btrfs_memcpy(root, left, btrfs_leaf_data(left) + | 1602 | |
1603 | copy_extent_buffer(left, right, btrfs_leaf_data(left) + | ||
1511 | leaf_data_end(root, left) - push_space, | 1604 | leaf_data_end(root, left) - push_space, |
1512 | btrfs_leaf_data(right) + | 1605 | btrfs_leaf_data(right) + |
1513 | btrfs_item_offset(right->items + push_items - 1), | 1606 | btrfs_item_offset_nr(right, push_items - 1), |
1514 | push_space); | 1607 | push_space); |
1515 | old_left_nritems = btrfs_header_nritems(&left->header); | 1608 | old_left_nritems = btrfs_header_nritems(left); |
1516 | BUG_ON(old_left_nritems < 0); | 1609 | BUG_ON(old_left_nritems < 0); |
1517 | 1610 | ||
1518 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { | 1611 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { |
1519 | u32 ioff = btrfs_item_offset(left->items + i); | 1612 | u32 ioff; |
1520 | btrfs_set_item_offset(left->items + i, ioff - | 1613 | item = btrfs_item_nr(left, i); |
1521 | (BTRFS_LEAF_DATA_SIZE(root) - | 1614 | ioff = btrfs_item_offset(left, item); |
1522 | btrfs_item_offset(left->items + | 1615 | btrfs_set_item_offset(left, item, |
1523 | old_left_nritems - 1))); | 1616 | ioff - (BTRFS_LEAF_DATA_SIZE(root) - |
1617 | btrfs_item_offset_nr(left, old_left_nritems - 1))); | ||
1524 | } | 1618 | } |
1525 | btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); | 1619 | btrfs_set_header_nritems(left, old_left_nritems + push_items); |
1526 | 1620 | ||
1527 | /* fixup right node */ | 1621 | /* fixup right node */ |
1528 | push_space = btrfs_item_offset(right->items + push_items - 1) - | 1622 | push_space = btrfs_item_offset_nr(right, push_items - 1) - |
1529 | leaf_data_end(root, right); | 1623 | leaf_data_end(root, right); |
1530 | btrfs_memmove(root, right, btrfs_leaf_data(right) + | 1624 | memmove_extent_buffer(right, btrfs_leaf_data(right) + |
1531 | BTRFS_LEAF_DATA_SIZE(root) - push_space, | 1625 | BTRFS_LEAF_DATA_SIZE(root) - push_space, |
1532 | btrfs_leaf_data(right) + | 1626 | btrfs_leaf_data(right) + |
1533 | leaf_data_end(root, right), push_space); | 1627 | leaf_data_end(root, right), push_space); |
1534 | btrfs_memmove(root, right, right->items, right->items + push_items, | 1628 | |
1535 | (btrfs_header_nritems(&right->header) - push_items) * | 1629 | memmove_extent_buffer(right, btrfs_item_nr_offset(0), |
1536 | sizeof(struct btrfs_item)); | 1630 | btrfs_item_nr_offset(push_items), |
1537 | btrfs_set_header_nritems(&right->header, | 1631 | (btrfs_header_nritems(right) - push_items) * |
1538 | btrfs_header_nritems(&right->header) - | 1632 | sizeof(struct btrfs_item)); |
1539 | push_items); | 1633 | |
1634 | right_nritems = btrfs_header_nritems(right) - push_items; | ||
1635 | btrfs_set_header_nritems(right, right_nritems); | ||
1540 | push_space = BTRFS_LEAF_DATA_SIZE(root); | 1636 | push_space = BTRFS_LEAF_DATA_SIZE(root); |
1541 | 1637 | ||
1542 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { | 1638 | for (i = 0; i < right_nritems; i++) { |
1543 | btrfs_set_item_offset(right->items + i, push_space - | 1639 | item = btrfs_item_nr(right, i); |
1544 | btrfs_item_size(right->items + i)); | 1640 | btrfs_set_item_offset(right, item, push_space - |
1545 | push_space = btrfs_item_offset(right->items + i); | 1641 | btrfs_item_size(right, item)); |
1642 | push_space = btrfs_item_offset(right, item); | ||
1546 | } | 1643 | } |
1547 | 1644 | ||
1548 | btrfs_mark_buffer_dirty(t); | 1645 | btrfs_mark_buffer_dirty(left); |
1549 | btrfs_mark_buffer_dirty(right_buf); | 1646 | btrfs_mark_buffer_dirty(right); |
1550 | 1647 | ||
1551 | wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); | 1648 | btrfs_item_key(right, &disk_key, 0); |
1649 | wret = fixup_low_keys(trans, root, path, &disk_key, 1); | ||
1552 | if (wret) | 1650 | if (wret) |
1553 | ret = wret; | 1651 | ret = wret; |
1554 | 1652 | ||
1555 | /* then fixup the leaf pointer in the path */ | 1653 | /* then fixup the leaf pointer in the path */ |
1556 | if (path->slots[0] < push_items) { | 1654 | if (path->slots[0] < push_items) { |
1557 | path->slots[0] += old_left_nritems; | 1655 | path->slots[0] += old_left_nritems; |
1558 | btrfs_block_release(root, path->nodes[0]); | 1656 | free_extent_buffer(path->nodes[0]); |
1559 | path->nodes[0] = t; | 1657 | path->nodes[0] = left; |
1560 | path->slots[1] -= 1; | 1658 | path->slots[1] -= 1; |
1561 | } else { | 1659 | } else { |
1562 | btrfs_block_release(root, t); | 1660 | free_extent_buffer(left); |
1563 | path->slots[0] -= push_items; | 1661 | path->slots[0] -= push_items; |
1564 | } | 1662 | } |
1565 | BUG_ON(path->slots[0] < 0); | 1663 | BUG_ON(path->slots[0] < 0); |
@@ -1578,13 +1676,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1578 | *root, struct btrfs_key *ins_key, | 1676 | *root, struct btrfs_key *ins_key, |
1579 | struct btrfs_path *path, int data_size) | 1677 | struct btrfs_path *path, int data_size) |
1580 | { | 1678 | { |
1581 | struct buffer_head *l_buf; | 1679 | struct extent_buffer *l; |
1582 | struct btrfs_leaf *l; | ||
1583 | u32 nritems; | 1680 | u32 nritems; |
1584 | int mid; | 1681 | int mid; |
1585 | int slot; | 1682 | int slot; |
1586 | struct btrfs_leaf *right; | 1683 | struct extent_buffer *right; |
1587 | struct buffer_head *right_buffer; | ||
1588 | int space_needed = data_size + sizeof(struct btrfs_item); | 1684 | int space_needed = data_size + sizeof(struct btrfs_item); |
1589 | int data_copy_size; | 1685 | int data_copy_size; |
1590 | int rt_data_off; | 1686 | int rt_data_off; |
@@ -1603,8 +1699,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1603 | if (wret < 0) | 1699 | if (wret < 0) |
1604 | return wret; | 1700 | return wret; |
1605 | } | 1701 | } |
1606 | l_buf = path->nodes[0]; | 1702 | l = path->nodes[0]; |
1607 | l = btrfs_buffer_leaf(l_buf); | ||
1608 | 1703 | ||
1609 | /* did the pushes work? */ | 1704 | /* did the pushes work? */ |
1610 | if (btrfs_leaf_free_space(root, l) >= | 1705 | if (btrfs_leaf_free_space(root, l) >= |
@@ -1617,36 +1712,38 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1617 | return ret; | 1712 | return ret; |
1618 | } | 1713 | } |
1619 | slot = path->slots[0]; | 1714 | slot = path->slots[0]; |
1620 | nritems = btrfs_header_nritems(&l->header); | 1715 | nritems = btrfs_header_nritems(l); |
1621 | mid = (nritems + 1)/ 2; | 1716 | mid = (nritems + 1)/ 2; |
1622 | 1717 | ||
1623 | right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0); | 1718 | right = btrfs_alloc_free_block(trans, root, |
1624 | if (IS_ERR(right_buffer)) | 1719 | extent_buffer_blocknr(l), 0); |
1625 | return PTR_ERR(right_buffer); | 1720 | if (IS_ERR(right)) |
1626 | 1721 | return PTR_ERR(right); | |
1627 | right = btrfs_buffer_leaf(right_buffer); | 1722 | |
1628 | memset(&right->header, 0, sizeof(right->header)); | 1723 | memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); |
1629 | btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); | 1724 | btrfs_set_header_blocknr(right, extent_buffer_blocknr(right)); |
1630 | btrfs_set_header_generation(&right->header, trans->transid); | 1725 | btrfs_set_header_generation(right, trans->transid); |
1631 | btrfs_set_header_owner(&right->header, root->root_key.objectid); | 1726 | btrfs_set_header_owner(right, root->root_key.objectid); |
1632 | btrfs_set_header_level(&right->header, 0); | 1727 | btrfs_set_header_level(right, 0); |
1633 | memcpy(right->header.fsid, root->fs_info->disk_super->fsid, | 1728 | write_extent_buffer(right, root->fs_info->fsid, |
1634 | sizeof(right->header.fsid)); | 1729 | (unsigned long)btrfs_header_fsid(right), |
1730 | BTRFS_FSID_SIZE); | ||
1731 | |||
1635 | if (mid <= slot) { | 1732 | if (mid <= slot) { |
1636 | if (nritems == 1 || | 1733 | if (nritems == 1 || |
1637 | leaf_space_used(l, mid, nritems - mid) + space_needed > | 1734 | leaf_space_used(l, mid, nritems - mid) + space_needed > |
1638 | BTRFS_LEAF_DATA_SIZE(root)) { | 1735 | BTRFS_LEAF_DATA_SIZE(root)) { |
1639 | if (slot >= nritems) { | 1736 | if (slot >= nritems) { |
1640 | btrfs_cpu_key_to_disk(&disk_key, ins_key); | 1737 | btrfs_cpu_key_to_disk(&disk_key, ins_key); |
1641 | btrfs_set_header_nritems(&right->header, 0); | 1738 | btrfs_set_header_nritems(right, 0); |
1642 | wret = insert_ptr(trans, root, path, | 1739 | wret = insert_ptr(trans, root, path, |
1643 | &disk_key, | 1740 | &disk_key, |
1644 | bh_blocknr(right_buffer), | 1741 | extent_buffer_blocknr(right), |
1645 | path->slots[1] + 1, 1); | 1742 | path->slots[1] + 1, 1); |
1646 | if (wret) | 1743 | if (wret) |
1647 | ret = wret; | 1744 | ret = wret; |
1648 | btrfs_block_release(root, path->nodes[0]); | 1745 | free_extent_buffer(path->nodes[0]); |
1649 | path->nodes[0] = right_buffer; | 1746 | path->nodes[0] = right; |
1650 | path->slots[0] = 0; | 1747 | path->slots[0] = 0; |
1651 | path->slots[1] += 1; | 1748 | path->slots[1] += 1; |
1652 | return ret; | 1749 | return ret; |
@@ -1659,15 +1756,15 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1659 | BTRFS_LEAF_DATA_SIZE(root)) { | 1756 | BTRFS_LEAF_DATA_SIZE(root)) { |
1660 | if (slot == 0) { | 1757 | if (slot == 0) { |
1661 | btrfs_cpu_key_to_disk(&disk_key, ins_key); | 1758 | btrfs_cpu_key_to_disk(&disk_key, ins_key); |
1662 | btrfs_set_header_nritems(&right->header, 0); | 1759 | btrfs_set_header_nritems(right, 0); |
1663 | wret = insert_ptr(trans, root, path, | 1760 | wret = insert_ptr(trans, root, path, |
1664 | &disk_key, | 1761 | &disk_key, |
1665 | bh_blocknr(right_buffer), | 1762 | extent_buffer_blocknr(right), |
1666 | path->slots[1], 1); | 1763 | path->slots[1], 1); |
1667 | if (wret) | 1764 | if (wret) |
1668 | ret = wret; | 1765 | ret = wret; |
1669 | btrfs_block_release(root, path->nodes[0]); | 1766 | free_extent_buffer(path->nodes[0]); |
1670 | path->nodes[0] = right_buffer; | 1767 | path->nodes[0] = right; |
1671 | path->slots[0] = 0; | 1768 | path->slots[0] = 0; |
1672 | if (path->slots[1] == 0) { | 1769 | if (path->slots[1] == 0) { |
1673 | wret = fixup_low_keys(trans, root, | 1770 | wret = fixup_low_keys(trans, root, |
@@ -1681,61 +1778,74 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1681 | double_split = 1; | 1778 | double_split = 1; |
1682 | } | 1779 | } |
1683 | } | 1780 | } |
1684 | btrfs_set_header_nritems(&right->header, nritems - mid); | 1781 | nritems = nritems - mid; |
1685 | data_copy_size = btrfs_item_end(l->items + mid) - | 1782 | btrfs_set_header_nritems(right, nritems); |
1686 | leaf_data_end(root, l); | 1783 | data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(root, l); |
1687 | btrfs_memcpy(root, right, right->items, l->items + mid, | 1784 | |
1688 | (nritems - mid) * sizeof(struct btrfs_item)); | 1785 | copy_extent_buffer(right, l, btrfs_item_nr_offset(0), |
1689 | btrfs_memcpy(root, right, | 1786 | btrfs_item_nr_offset(mid), |
1787 | nritems * sizeof(struct btrfs_item)); | ||
1788 | |||
1789 | copy_extent_buffer(right, l, | ||
1690 | btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - | 1790 | btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - |
1691 | data_copy_size, btrfs_leaf_data(l) + | 1791 | data_copy_size, btrfs_leaf_data(l) + |
1692 | leaf_data_end(root, l), data_copy_size); | 1792 | leaf_data_end(root, l), data_copy_size); |
1793 | |||
1693 | rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - | 1794 | rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - |
1694 | btrfs_item_end(l->items + mid); | 1795 | btrfs_item_end_nr(l, mid); |
1695 | 1796 | ||
1696 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { | 1797 | for (i = 0; i < nritems; i++) { |
1697 | u32 ioff = btrfs_item_offset(right->items + i); | 1798 | struct btrfs_item *item = btrfs_item_nr(right, i); |
1698 | btrfs_set_item_offset(right->items + i, ioff + rt_data_off); | 1799 | u32 ioff = btrfs_item_offset(right, item); |
1800 | btrfs_set_item_offset(right, item, ioff + rt_data_off); | ||
1699 | } | 1801 | } |
1700 | 1802 | ||
1701 | btrfs_set_header_nritems(&l->header, mid); | 1803 | btrfs_set_header_nritems(l, mid); |
1702 | ret = 0; | 1804 | ret = 0; |
1703 | wret = insert_ptr(trans, root, path, &right->items[0].key, | 1805 | btrfs_item_key(right, &disk_key, 0); |
1704 | bh_blocknr(right_buffer), path->slots[1] + 1, 1); | 1806 | wret = insert_ptr(trans, root, path, &disk_key, |
1807 | extent_buffer_blocknr(right), path->slots[1] + 1, 1); | ||
1705 | if (wret) | 1808 | if (wret) |
1706 | ret = wret; | 1809 | ret = wret; |
1707 | btrfs_mark_buffer_dirty(right_buffer); | 1810 | |
1708 | btrfs_mark_buffer_dirty(l_buf); | 1811 | btrfs_mark_buffer_dirty(right); |
1812 | btrfs_mark_buffer_dirty(l); | ||
1709 | BUG_ON(path->slots[0] != slot); | 1813 | BUG_ON(path->slots[0] != slot); |
1814 | |||
1710 | if (mid <= slot) { | 1815 | if (mid <= slot) { |
1711 | btrfs_block_release(root, path->nodes[0]); | 1816 | free_extent_buffer(path->nodes[0]); |
1712 | path->nodes[0] = right_buffer; | 1817 | path->nodes[0] = right; |
1713 | path->slots[0] -= mid; | 1818 | path->slots[0] -= mid; |
1714 | path->slots[1] += 1; | 1819 | path->slots[1] += 1; |
1715 | } else | 1820 | } else |
1716 | btrfs_block_release(root, right_buffer); | 1821 | free_extent_buffer(right); |
1822 | |||
1717 | BUG_ON(path->slots[0] < 0); | 1823 | BUG_ON(path->slots[0] < 0); |
1718 | check_node(root, path, 1); | 1824 | check_node(root, path, 1); |
1825 | check_leaf(root, path, 0); | ||
1719 | 1826 | ||
1720 | if (!double_split) | 1827 | if (!double_split) |
1721 | return ret; | 1828 | return ret; |
1722 | right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0); | 1829 | |
1723 | if (IS_ERR(right_buffer)) | 1830 | right = btrfs_alloc_free_block(trans, root, |
1724 | return PTR_ERR(right_buffer); | 1831 | extent_buffer_blocknr(l), 0); |
1725 | 1832 | if (IS_ERR(right)) | |
1726 | right = btrfs_buffer_leaf(right_buffer); | 1833 | return PTR_ERR(right); |
1727 | memset(&right->header, 0, sizeof(right->header)); | 1834 | |
1728 | btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); | 1835 | memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); |
1729 | btrfs_set_header_generation(&right->header, trans->transid); | 1836 | btrfs_set_header_blocknr(right, extent_buffer_blocknr(right)); |
1730 | btrfs_set_header_owner(&right->header, root->root_key.objectid); | 1837 | btrfs_set_header_generation(right, trans->transid); |
1731 | btrfs_set_header_level(&right->header, 0); | 1838 | btrfs_set_header_owner(right, root->root_key.objectid); |
1732 | memcpy(right->header.fsid, root->fs_info->disk_super->fsid, | 1839 | btrfs_set_header_level(right, 0); |
1733 | sizeof(right->header.fsid)); | 1840 | write_extent_buffer(right, root->fs_info->fsid, |
1841 | (unsigned long)btrfs_header_fsid(right), | ||
1842 | BTRFS_FSID_SIZE); | ||
1843 | |||
1734 | btrfs_cpu_key_to_disk(&disk_key, ins_key); | 1844 | btrfs_cpu_key_to_disk(&disk_key, ins_key); |
1735 | btrfs_set_header_nritems(&right->header, 0); | 1845 | btrfs_set_header_nritems(right, 0); |
1736 | wret = insert_ptr(trans, root, path, | 1846 | wret = insert_ptr(trans, root, path, |
1737 | &disk_key, | 1847 | &disk_key, |
1738 | bh_blocknr(right_buffer), | 1848 | extent_buffer_blocknr(right), |
1739 | path->slots[1], 1); | 1849 | path->slots[1], 1); |
1740 | if (wret) | 1850 | if (wret) |
1741 | ret = wret; | 1851 | ret = wret; |
@@ -1744,8 +1854,8 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1744 | if (wret) | 1854 | if (wret) |
1745 | ret = wret; | 1855 | ret = wret; |
1746 | } | 1856 | } |
1747 | btrfs_block_release(root, path->nodes[0]); | 1857 | free_extent_buffer(path->nodes[0]); |
1748 | path->nodes[0] = right_buffer; | 1858 | path->nodes[0] = right; |
1749 | path->slots[0] = 0; | 1859 | path->slots[0] = 0; |
1750 | check_node(root, path, 1); | 1860 | check_node(root, path, 1); |
1751 | check_leaf(root, path, 0); | 1861 | check_leaf(root, path, 0); |
@@ -1760,8 +1870,8 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
1760 | int ret = 0; | 1870 | int ret = 0; |
1761 | int slot; | 1871 | int slot; |
1762 | int slot_orig; | 1872 | int slot_orig; |
1763 | struct btrfs_leaf *leaf; | 1873 | struct extent_buffer *leaf; |
1764 | struct buffer_head *leaf_buf; | 1874 | struct btrfs_item *item; |
1765 | u32 nritems; | 1875 | u32 nritems; |
1766 | unsigned int data_end; | 1876 | unsigned int data_end; |
1767 | unsigned int old_data_start; | 1877 | unsigned int old_data_start; |
@@ -1770,15 +1880,14 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
1770 | int i; | 1880 | int i; |
1771 | 1881 | ||
1772 | slot_orig = path->slots[0]; | 1882 | slot_orig = path->slots[0]; |
1773 | leaf_buf = path->nodes[0]; | 1883 | leaf = path->nodes[0]; |
1774 | leaf = btrfs_buffer_leaf(leaf_buf); | ||
1775 | 1884 | ||
1776 | nritems = btrfs_header_nritems(&leaf->header); | 1885 | nritems = btrfs_header_nritems(leaf); |
1777 | data_end = leaf_data_end(root, leaf); | 1886 | data_end = leaf_data_end(root, leaf); |
1778 | 1887 | ||
1779 | slot = path->slots[0]; | 1888 | slot = path->slots[0]; |
1780 | old_data_start = btrfs_item_offset(leaf->items + slot); | 1889 | old_data_start = btrfs_item_offset_nr(leaf, slot); |
1781 | old_size = btrfs_item_size(leaf->items + slot); | 1890 | old_size = btrfs_item_size_nr(leaf, slot); |
1782 | BUG_ON(old_size <= new_size); | 1891 | BUG_ON(old_size <= new_size); |
1783 | size_diff = old_size - new_size; | 1892 | size_diff = old_size - new_size; |
1784 | 1893 | ||
@@ -1790,32 +1899,38 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
1790 | */ | 1899 | */ |
1791 | /* first correct the data pointers */ | 1900 | /* first correct the data pointers */ |
1792 | for (i = slot; i < nritems; i++) { | 1901 | for (i = slot; i < nritems; i++) { |
1793 | u32 ioff = btrfs_item_offset(leaf->items + i); | 1902 | u32 ioff; |
1794 | btrfs_set_item_offset(leaf->items + i, | 1903 | item = btrfs_item_nr(leaf, i); |
1795 | ioff + size_diff); | 1904 | ioff = btrfs_item_offset(leaf, item); |
1905 | btrfs_set_item_offset(leaf, item, ioff + size_diff); | ||
1796 | } | 1906 | } |
1797 | /* shift the data */ | 1907 | /* shift the data */ |
1798 | btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + | 1908 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
1799 | data_end + size_diff, btrfs_leaf_data(leaf) + | 1909 | data_end + size_diff, btrfs_leaf_data(leaf) + |
1800 | data_end, old_data_start + new_size - data_end); | 1910 | data_end, old_data_start + new_size - data_end); |
1801 | btrfs_set_item_size(leaf->items + slot, new_size); | 1911 | |
1802 | btrfs_mark_buffer_dirty(leaf_buf); | 1912 | item = btrfs_item_nr(leaf, slot); |
1913 | btrfs_set_item_size(leaf, item, new_size); | ||
1914 | btrfs_mark_buffer_dirty(leaf); | ||
1803 | 1915 | ||
1804 | ret = 0; | 1916 | ret = 0; |
1805 | if (btrfs_leaf_free_space(root, leaf) < 0) | 1917 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
1918 | btrfs_print_leaf(root, leaf); | ||
1806 | BUG(); | 1919 | BUG(); |
1920 | } | ||
1807 | check_leaf(root, path, 0); | 1921 | check_leaf(root, path, 0); |
1808 | return ret; | 1922 | return ret; |
1809 | } | 1923 | } |
1810 | 1924 | ||
1811 | int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root | 1925 | int btrfs_extend_item(struct btrfs_trans_handle *trans, |
1812 | *root, struct btrfs_path *path, u32 data_size) | 1926 | struct btrfs_root *root, struct btrfs_path *path, |
1927 | u32 data_size) | ||
1813 | { | 1928 | { |
1814 | int ret = 0; | 1929 | int ret = 0; |
1815 | int slot; | 1930 | int slot; |
1816 | int slot_orig; | 1931 | int slot_orig; |
1817 | struct btrfs_leaf *leaf; | 1932 | struct extent_buffer *leaf; |
1818 | struct buffer_head *leaf_buf; | 1933 | struct btrfs_item *item; |
1819 | u32 nritems; | 1934 | u32 nritems; |
1820 | unsigned int data_end; | 1935 | unsigned int data_end; |
1821 | unsigned int old_data; | 1936 | unsigned int old_data; |
@@ -1823,16 +1938,17 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1823 | int i; | 1938 | int i; |
1824 | 1939 | ||
1825 | slot_orig = path->slots[0]; | 1940 | slot_orig = path->slots[0]; |
1826 | leaf_buf = path->nodes[0]; | 1941 | leaf = path->nodes[0]; |
1827 | leaf = btrfs_buffer_leaf(leaf_buf); | ||
1828 | 1942 | ||
1829 | nritems = btrfs_header_nritems(&leaf->header); | 1943 | nritems = btrfs_header_nritems(leaf); |
1830 | data_end = leaf_data_end(root, leaf); | 1944 | data_end = leaf_data_end(root, leaf); |
1831 | 1945 | ||
1832 | if (btrfs_leaf_free_space(root, leaf) < data_size) | 1946 | if (btrfs_leaf_free_space(root, leaf) < data_size) { |
1947 | btrfs_print_leaf(root, leaf); | ||
1833 | BUG(); | 1948 | BUG(); |
1949 | } | ||
1834 | slot = path->slots[0]; | 1950 | slot = path->slots[0]; |
1835 | old_data = btrfs_item_end(leaf->items + slot); | 1951 | old_data = btrfs_item_end_nr(leaf, slot); |
1836 | 1952 | ||
1837 | BUG_ON(slot < 0); | 1953 | BUG_ON(slot < 0); |
1838 | BUG_ON(slot >= nritems); | 1954 | BUG_ON(slot >= nritems); |
@@ -1842,22 +1958,28 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1842 | */ | 1958 | */ |
1843 | /* first correct the data pointers */ | 1959 | /* first correct the data pointers */ |
1844 | for (i = slot; i < nritems; i++) { | 1960 | for (i = slot; i < nritems; i++) { |
1845 | u32 ioff = btrfs_item_offset(leaf->items + i); | 1961 | u32 ioff; |
1846 | btrfs_set_item_offset(leaf->items + i, | 1962 | item = btrfs_item_nr(leaf, i); |
1847 | ioff - data_size); | 1963 | ioff = btrfs_item_offset(leaf, item); |
1964 | btrfs_set_item_offset(leaf, item, ioff - data_size); | ||
1848 | } | 1965 | } |
1966 | |||
1849 | /* shift the data */ | 1967 | /* shift the data */ |
1850 | btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + | 1968 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
1851 | data_end - data_size, btrfs_leaf_data(leaf) + | 1969 | data_end - data_size, btrfs_leaf_data(leaf) + |
1852 | data_end, old_data - data_end); | 1970 | data_end, old_data - data_end); |
1971 | |||
1853 | data_end = old_data; | 1972 | data_end = old_data; |
1854 | old_size = btrfs_item_size(leaf->items + slot); | 1973 | old_size = btrfs_item_size_nr(leaf, slot); |
1855 | btrfs_set_item_size(leaf->items + slot, old_size + data_size); | 1974 | item = btrfs_item_nr(leaf, slot); |
1856 | btrfs_mark_buffer_dirty(leaf_buf); | 1975 | btrfs_set_item_size(leaf, item, old_size + data_size); |
1976 | btrfs_mark_buffer_dirty(leaf); | ||
1857 | 1977 | ||
1858 | ret = 0; | 1978 | ret = 0; |
1859 | if (btrfs_leaf_free_space(root, leaf) < 0) | 1979 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
1980 | btrfs_print_leaf(root, leaf); | ||
1860 | BUG(); | 1981 | BUG(); |
1982 | } | ||
1861 | check_leaf(root, path, 0); | 1983 | check_leaf(root, path, 0); |
1862 | return ret; | 1984 | return ret; |
1863 | } | 1985 | } |
@@ -1866,15 +1988,16 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1866 | * Given a key and some data, insert an item into the tree. | 1988 | * Given a key and some data, insert an item into the tree. |
1867 | * This does all the path init required, making room in the tree if needed. | 1989 | * This does all the path init required, making room in the tree if needed. |
1868 | */ | 1990 | */ |
1869 | int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | 1991 | int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, |
1870 | *root, struct btrfs_path *path, struct btrfs_key | 1992 | struct btrfs_root *root, |
1871 | *cpu_key, u32 data_size) | 1993 | struct btrfs_path *path, |
1994 | struct btrfs_key *cpu_key, u32 data_size) | ||
1872 | { | 1995 | { |
1996 | struct extent_buffer *leaf; | ||
1997 | struct btrfs_item *item; | ||
1873 | int ret = 0; | 1998 | int ret = 0; |
1874 | int slot; | 1999 | int slot; |
1875 | int slot_orig; | 2000 | int slot_orig; |
1876 | struct btrfs_leaf *leaf; | ||
1877 | struct buffer_head *leaf_buf; | ||
1878 | u32 nritems; | 2001 | u32 nritems; |
1879 | unsigned int data_end; | 2002 | unsigned int data_end; |
1880 | struct btrfs_disk_key disk_key; | 2003 | struct btrfs_disk_key disk_key; |
@@ -1884,6 +2007,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1884 | /* create a root if there isn't one */ | 2007 | /* create a root if there isn't one */ |
1885 | if (!root->node) | 2008 | if (!root->node) |
1886 | BUG(); | 2009 | BUG(); |
2010 | |||
1887 | ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); | 2011 | ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); |
1888 | if (ret == 0) { | 2012 | if (ret == 0) { |
1889 | return -EEXIST; | 2013 | return -EEXIST; |
@@ -1892,57 +2016,68 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1892 | goto out; | 2016 | goto out; |
1893 | 2017 | ||
1894 | slot_orig = path->slots[0]; | 2018 | slot_orig = path->slots[0]; |
1895 | leaf_buf = path->nodes[0]; | 2019 | leaf = path->nodes[0]; |
1896 | leaf = btrfs_buffer_leaf(leaf_buf); | ||
1897 | 2020 | ||
1898 | nritems = btrfs_header_nritems(&leaf->header); | 2021 | nritems = btrfs_header_nritems(leaf); |
1899 | data_end = leaf_data_end(root, leaf); | 2022 | data_end = leaf_data_end(root, leaf); |
1900 | 2023 | ||
1901 | if (btrfs_leaf_free_space(root, leaf) < | 2024 | if (btrfs_leaf_free_space(root, leaf) < |
1902 | sizeof(struct btrfs_item) + data_size) { | 2025 | sizeof(struct btrfs_item) + data_size) { |
1903 | BUG(); | 2026 | BUG(); |
1904 | } | 2027 | } |
2028 | |||
1905 | slot = path->slots[0]; | 2029 | slot = path->slots[0]; |
1906 | BUG_ON(slot < 0); | 2030 | BUG_ON(slot < 0); |
2031 | |||
1907 | if (slot != nritems) { | 2032 | if (slot != nritems) { |
1908 | int i; | 2033 | int i; |
1909 | unsigned int old_data = btrfs_item_end(leaf->items + slot); | 2034 | unsigned int old_data = btrfs_item_end_nr(leaf, slot); |
1910 | 2035 | ||
2036 | if (old_data < data_end) { | ||
2037 | btrfs_print_leaf(root, leaf); | ||
2038 | printk("slot %d old_data %d data_end %d\n", | ||
2039 | slot, old_data, data_end); | ||
2040 | BUG_ON(1); | ||
2041 | } | ||
1911 | /* | 2042 | /* |
1912 | * item0..itemN ... dataN.offset..dataN.size .. data0.size | 2043 | * item0..itemN ... dataN.offset..dataN.size .. data0.size |
1913 | */ | 2044 | */ |
1914 | /* first correct the data pointers */ | 2045 | /* first correct the data pointers */ |
1915 | for (i = slot; i < nritems; i++) { | 2046 | for (i = slot; i < nritems; i++) { |
1916 | u32 ioff = btrfs_item_offset(leaf->items + i); | 2047 | u32 ioff; |
1917 | btrfs_set_item_offset(leaf->items + i, | 2048 | item = btrfs_item_nr(leaf, i); |
1918 | ioff - data_size); | 2049 | ioff = btrfs_item_offset(leaf, item); |
2050 | btrfs_set_item_offset(leaf, item, ioff - data_size); | ||
1919 | } | 2051 | } |
1920 | 2052 | ||
1921 | /* shift the items */ | 2053 | /* shift the items */ |
1922 | btrfs_memmove(root, leaf, leaf->items + slot + 1, | 2054 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), |
1923 | leaf->items + slot, | 2055 | btrfs_item_nr_offset(slot), |
1924 | (nritems - slot) * sizeof(struct btrfs_item)); | 2056 | (nritems - slot) * sizeof(struct btrfs_item)); |
1925 | 2057 | ||
1926 | /* shift the data */ | 2058 | /* shift the data */ |
1927 | btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + | 2059 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
1928 | data_end - data_size, btrfs_leaf_data(leaf) + | 2060 | data_end - data_size, btrfs_leaf_data(leaf) + |
1929 | data_end, old_data - data_end); | 2061 | data_end, old_data - data_end); |
1930 | data_end = old_data; | 2062 | data_end = old_data; |
1931 | } | 2063 | } |
2064 | |||
1932 | /* setup the item for the new data */ | 2065 | /* setup the item for the new data */ |
1933 | btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, | 2066 | btrfs_set_item_key(leaf, &disk_key, slot); |
1934 | sizeof(struct btrfs_disk_key)); | 2067 | item = btrfs_item_nr(leaf, slot); |
1935 | btrfs_set_item_offset(leaf->items + slot, data_end - data_size); | 2068 | btrfs_set_item_offset(leaf, item, data_end - data_size); |
1936 | btrfs_set_item_size(leaf->items + slot, data_size); | 2069 | btrfs_set_item_size(leaf, item, data_size); |
1937 | btrfs_set_header_nritems(&leaf->header, nritems + 1); | 2070 | btrfs_set_header_nritems(leaf, nritems + 1); |
1938 | btrfs_mark_buffer_dirty(leaf_buf); | 2071 | btrfs_mark_buffer_dirty(leaf); |
1939 | 2072 | ||
1940 | ret = 0; | 2073 | ret = 0; |
1941 | if (slot == 0) | 2074 | if (slot == 0) |
1942 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); | 2075 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); |
1943 | 2076 | ||
1944 | if (btrfs_leaf_free_space(root, leaf) < 0) | 2077 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
2078 | btrfs_print_leaf(root, leaf); | ||
1945 | BUG(); | 2079 | BUG(); |
2080 | } | ||
1946 | check_leaf(root, path, 0); | 2081 | check_leaf(root, path, 0); |
1947 | out: | 2082 | out: |
1948 | return ret; | 2083 | return ret; |
@@ -1958,17 +2093,17 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1958 | { | 2093 | { |
1959 | int ret = 0; | 2094 | int ret = 0; |
1960 | struct btrfs_path *path; | 2095 | struct btrfs_path *path; |
1961 | u8 *ptr; | 2096 | struct extent_buffer *leaf; |
2097 | unsigned long ptr; | ||
1962 | 2098 | ||
1963 | path = btrfs_alloc_path(); | 2099 | path = btrfs_alloc_path(); |
1964 | BUG_ON(!path); | 2100 | BUG_ON(!path); |
1965 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); | 2101 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); |
1966 | if (!ret) { | 2102 | if (!ret) { |
1967 | ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 2103 | leaf = path->nodes[0]; |
1968 | path->slots[0], u8); | 2104 | ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); |
1969 | btrfs_memcpy(root, path->nodes[0]->b_data, | 2105 | write_extent_buffer(leaf, data, ptr, data_size); |
1970 | ptr, data, data_size); | 2106 | btrfs_mark_buffer_dirty(leaf); |
1971 | btrfs_mark_buffer_dirty(path->nodes[0]); | ||
1972 | } | 2107 | } |
1973 | btrfs_free_path(path); | 2108 | btrfs_free_path(path); |
1974 | return ret; | 2109 | return ret; |
@@ -1984,30 +2119,30 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1984 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2119 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1985 | struct btrfs_path *path, int level, int slot) | 2120 | struct btrfs_path *path, int level, int slot) |
1986 | { | 2121 | { |
1987 | struct btrfs_node *node; | 2122 | struct extent_buffer *parent = path->nodes[level]; |
1988 | struct buffer_head *parent = path->nodes[level]; | ||
1989 | u32 nritems; | 2123 | u32 nritems; |
1990 | int ret = 0; | 2124 | int ret = 0; |
1991 | int wret; | 2125 | int wret; |
1992 | 2126 | ||
1993 | node = btrfs_buffer_node(parent); | 2127 | nritems = btrfs_header_nritems(parent); |
1994 | nritems = btrfs_header_nritems(&node->header); | ||
1995 | if (slot != nritems -1) { | 2128 | if (slot != nritems -1) { |
1996 | btrfs_memmove(root, node, node->ptrs + slot, | 2129 | memmove_extent_buffer(parent, |
1997 | node->ptrs + slot + 1, | 2130 | btrfs_node_key_ptr_offset(slot), |
2131 | btrfs_node_key_ptr_offset(slot + 1), | ||
1998 | sizeof(struct btrfs_key_ptr) * | 2132 | sizeof(struct btrfs_key_ptr) * |
1999 | (nritems - slot - 1)); | 2133 | (nritems - slot - 1)); |
2000 | } | 2134 | } |
2001 | nritems--; | 2135 | nritems--; |
2002 | btrfs_set_header_nritems(&node->header, nritems); | 2136 | btrfs_set_header_nritems(parent, nritems); |
2003 | if (nritems == 0 && parent == root->node) { | 2137 | if (nritems == 0 && parent == root->node) { |
2004 | struct btrfs_header *header = btrfs_buffer_header(root->node); | 2138 | BUG_ON(btrfs_header_level(root->node) != 1); |
2005 | BUG_ON(btrfs_header_level(header) != 1); | ||
2006 | /* just turn the root into a leaf and break */ | 2139 | /* just turn the root into a leaf and break */ |
2007 | btrfs_set_header_level(header, 0); | 2140 | btrfs_set_header_level(root->node, 0); |
2008 | } else if (slot == 0) { | 2141 | } else if (slot == 0) { |
2009 | wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, | 2142 | struct btrfs_disk_key disk_key; |
2010 | level + 1); | 2143 | |
2144 | btrfs_node_key(parent, &disk_key, 0); | ||
2145 | wret = fixup_low_keys(trans, root, path, &disk_key, level + 1); | ||
2011 | if (wret) | 2146 | if (wret) |
2012 | ret = wret; | 2147 | ret = wret; |
2013 | } | 2148 | } |
@@ -2023,59 +2158,67 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2023 | struct btrfs_path *path) | 2158 | struct btrfs_path *path) |
2024 | { | 2159 | { |
2025 | int slot; | 2160 | int slot; |
2026 | struct btrfs_leaf *leaf; | 2161 | struct extent_buffer *leaf; |
2027 | struct buffer_head *leaf_buf; | 2162 | struct btrfs_item *item; |
2028 | int doff; | 2163 | int doff; |
2029 | int dsize; | 2164 | int dsize; |
2030 | int ret = 0; | 2165 | int ret = 0; |
2031 | int wret; | 2166 | int wret; |
2032 | u32 nritems; | 2167 | u32 nritems; |
2033 | 2168 | ||
2034 | leaf_buf = path->nodes[0]; | 2169 | leaf = path->nodes[0]; |
2035 | leaf = btrfs_buffer_leaf(leaf_buf); | ||
2036 | slot = path->slots[0]; | 2170 | slot = path->slots[0]; |
2037 | doff = btrfs_item_offset(leaf->items + slot); | 2171 | doff = btrfs_item_offset_nr(leaf, slot); |
2038 | dsize = btrfs_item_size(leaf->items + slot); | 2172 | dsize = btrfs_item_size_nr(leaf, slot); |
2039 | nritems = btrfs_header_nritems(&leaf->header); | 2173 | nritems = btrfs_header_nritems(leaf); |
2040 | 2174 | ||
2041 | if (slot != nritems - 1) { | 2175 | if (slot != nritems - 1) { |
2042 | int i; | 2176 | int i; |
2043 | int data_end = leaf_data_end(root, leaf); | 2177 | int data_end = leaf_data_end(root, leaf); |
2044 | btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + | 2178 | |
2179 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + | ||
2045 | data_end + dsize, | 2180 | data_end + dsize, |
2046 | btrfs_leaf_data(leaf) + data_end, | 2181 | btrfs_leaf_data(leaf) + data_end, |
2047 | doff - data_end); | 2182 | doff - data_end); |
2183 | |||
2048 | for (i = slot + 1; i < nritems; i++) { | 2184 | for (i = slot + 1; i < nritems; i++) { |
2049 | u32 ioff = btrfs_item_offset(leaf->items + i); | 2185 | u32 ioff; |
2050 | btrfs_set_item_offset(leaf->items + i, ioff + dsize); | 2186 | item = btrfs_item_nr(leaf, i); |
2187 | ioff = btrfs_item_offset(leaf, item); | ||
2188 | btrfs_set_item_offset(leaf, item, ioff + dsize); | ||
2051 | } | 2189 | } |
2052 | btrfs_memmove(root, leaf, leaf->items + slot, | 2190 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), |
2053 | leaf->items + slot + 1, | 2191 | btrfs_item_nr_offset(slot + 1), |
2054 | sizeof(struct btrfs_item) * | 2192 | sizeof(struct btrfs_item) * |
2055 | (nritems - slot - 1)); | 2193 | (nritems - slot - 1)); |
2056 | } | 2194 | } |
2057 | btrfs_set_header_nritems(&leaf->header, nritems - 1); | 2195 | btrfs_set_header_nritems(leaf, nritems - 1); |
2058 | nritems--; | 2196 | nritems--; |
2197 | |||
2059 | /* delete the leaf if we've emptied it */ | 2198 | /* delete the leaf if we've emptied it */ |
2060 | if (nritems == 0) { | 2199 | if (nritems == 0) { |
2061 | if (leaf_buf == root->node) { | 2200 | if (leaf == root->node) { |
2062 | btrfs_set_header_level(&leaf->header, 0); | 2201 | btrfs_set_header_level(leaf, 0); |
2063 | } else { | 2202 | } else { |
2064 | clean_tree_block(trans, root, leaf_buf); | 2203 | clean_tree_block(trans, root, leaf); |
2065 | wait_on_buffer(leaf_buf); | 2204 | wait_on_tree_block_writeback(root, leaf); |
2066 | wret = del_ptr(trans, root, path, 1, path->slots[1]); | 2205 | wret = del_ptr(trans, root, path, 1, path->slots[1]); |
2067 | if (wret) | 2206 | if (wret) |
2068 | ret = wret; | 2207 | ret = wret; |
2069 | wret = btrfs_free_extent(trans, root, | 2208 | wret = btrfs_free_extent(trans, root, |
2070 | bh_blocknr(leaf_buf), 1, 1); | 2209 | extent_buffer_blocknr(leaf), |
2210 | 1, 1); | ||
2071 | if (wret) | 2211 | if (wret) |
2072 | ret = wret; | 2212 | ret = wret; |
2073 | } | 2213 | } |
2074 | } else { | 2214 | } else { |
2075 | int used = leaf_space_used(leaf, 0, nritems); | 2215 | int used = leaf_space_used(leaf, 0, nritems); |
2076 | if (slot == 0) { | 2216 | if (slot == 0) { |
2217 | struct btrfs_disk_key disk_key; | ||
2218 | |||
2219 | btrfs_item_key(leaf, &disk_key, 0); | ||
2077 | wret = fixup_low_keys(trans, root, path, | 2220 | wret = fixup_low_keys(trans, root, path, |
2078 | &leaf->items[0].key, 1); | 2221 | &disk_key, 1); |
2079 | if (wret) | 2222 | if (wret) |
2080 | ret = wret; | 2223 | ret = wret; |
2081 | } | 2224 | } |
@@ -2087,34 +2230,40 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2087 | * for possible call to del_ptr below | 2230 | * for possible call to del_ptr below |
2088 | */ | 2231 | */ |
2089 | slot = path->slots[1]; | 2232 | slot = path->slots[1]; |
2090 | get_bh(leaf_buf); | 2233 | extent_buffer_get(leaf); |
2234 | |||
2091 | wret = push_leaf_left(trans, root, path, 1); | 2235 | wret = push_leaf_left(trans, root, path, 1); |
2092 | if (wret < 0 && wret != -ENOSPC) | 2236 | if (wret < 0 && wret != -ENOSPC) |
2093 | ret = wret; | 2237 | ret = wret; |
2094 | if (path->nodes[0] == leaf_buf && | 2238 | |
2095 | btrfs_header_nritems(&leaf->header)) { | 2239 | if (path->nodes[0] == leaf && |
2240 | btrfs_header_nritems(leaf)) { | ||
2096 | wret = push_leaf_right(trans, root, path, 1); | 2241 | wret = push_leaf_right(trans, root, path, 1); |
2097 | if (wret < 0 && wret != -ENOSPC) | 2242 | if (wret < 0 && wret != -ENOSPC) |
2098 | ret = wret; | 2243 | ret = wret; |
2099 | } | 2244 | } |
2100 | if (btrfs_header_nritems(&leaf->header) == 0) { | 2245 | |
2101 | u64 blocknr = bh_blocknr(leaf_buf); | 2246 | if (btrfs_header_nritems(leaf) == 0) { |
2102 | clean_tree_block(trans, root, leaf_buf); | 2247 | u64 blocknr = extent_buffer_blocknr(leaf); |
2103 | wait_on_buffer(leaf_buf); | 2248 | |
2249 | clean_tree_block(trans, root, leaf); | ||
2250 | wait_on_tree_block_writeback(root, leaf); | ||
2251 | |||
2104 | wret = del_ptr(trans, root, path, 1, slot); | 2252 | wret = del_ptr(trans, root, path, 1, slot); |
2105 | if (wret) | 2253 | if (wret) |
2106 | ret = wret; | 2254 | ret = wret; |
2107 | btrfs_block_release(root, leaf_buf); | 2255 | |
2256 | free_extent_buffer(leaf); | ||
2108 | wret = btrfs_free_extent(trans, root, blocknr, | 2257 | wret = btrfs_free_extent(trans, root, blocknr, |
2109 | 1, 1); | 2258 | 1, 1); |
2110 | if (wret) | 2259 | if (wret) |
2111 | ret = wret; | 2260 | ret = wret; |
2112 | } else { | 2261 | } else { |
2113 | btrfs_mark_buffer_dirty(leaf_buf); | 2262 | btrfs_mark_buffer_dirty(leaf); |
2114 | btrfs_block_release(root, leaf_buf); | 2263 | free_extent_buffer(leaf); |
2115 | } | 2264 | } |
2116 | } else { | 2265 | } else { |
2117 | btrfs_mark_buffer_dirty(leaf_buf); | 2266 | btrfs_mark_buffer_dirty(leaf); |
2118 | } | 2267 | } |
2119 | } | 2268 | } |
2120 | return ret; | 2269 | return ret; |
@@ -2130,25 +2279,27 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2130 | int slot; | 2279 | int slot; |
2131 | int level = 1; | 2280 | int level = 1; |
2132 | u64 blocknr; | 2281 | u64 blocknr; |
2133 | struct buffer_head *c; | 2282 | struct extent_buffer *c; |
2134 | struct btrfs_node *c_node; | 2283 | struct extent_buffer *next = NULL; |
2135 | struct buffer_head *next = NULL; | ||
2136 | 2284 | ||
2137 | while(level < BTRFS_MAX_LEVEL) { | 2285 | while(level < BTRFS_MAX_LEVEL) { |
2138 | if (!path->nodes[level]) | 2286 | if (!path->nodes[level]) |
2139 | return 1; | 2287 | return 1; |
2288 | |||
2140 | slot = path->slots[level] + 1; | 2289 | slot = path->slots[level] + 1; |
2141 | c = path->nodes[level]; | 2290 | c = path->nodes[level]; |
2142 | c_node = btrfs_buffer_node(c); | 2291 | if (slot >= btrfs_header_nritems(c)) { |
2143 | if (slot >= btrfs_header_nritems(&c_node->header)) { | ||
2144 | level++; | 2292 | level++; |
2145 | continue; | 2293 | continue; |
2146 | } | 2294 | } |
2147 | blocknr = btrfs_node_blockptr(c_node, slot); | 2295 | |
2296 | blocknr = btrfs_node_blockptr(c, slot); | ||
2148 | if (next) | 2297 | if (next) |
2149 | btrfs_block_release(root, next); | 2298 | free_extent_buffer(next); |
2299 | |||
2150 | if (path->reada) | 2300 | if (path->reada) |
2151 | reada_for_search(root, path, level, slot); | 2301 | reada_for_search(root, path, level, slot); |
2302 | |||
2152 | next = read_tree_block(root, blocknr); | 2303 | next = read_tree_block(root, blocknr); |
2153 | break; | 2304 | break; |
2154 | } | 2305 | } |
@@ -2156,15 +2307,14 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2156 | while(1) { | 2307 | while(1) { |
2157 | level--; | 2308 | level--; |
2158 | c = path->nodes[level]; | 2309 | c = path->nodes[level]; |
2159 | btrfs_block_release(root, c); | 2310 | free_extent_buffer(c); |
2160 | path->nodes[level] = next; | 2311 | path->nodes[level] = next; |
2161 | path->slots[level] = 0; | 2312 | path->slots[level] = 0; |
2162 | if (!level) | 2313 | if (!level) |
2163 | break; | 2314 | break; |
2164 | if (path->reada) | 2315 | if (path->reada) |
2165 | reada_for_search(root, path, level, 0); | 2316 | reada_for_search(root, path, level, 0); |
2166 | next = read_tree_block(root, | 2317 | next = read_tree_block(root, btrfs_node_blockptr(next, 0)); |
2167 | btrfs_node_blockptr(btrfs_buffer_node(next), 0)); | ||
2168 | } | 2318 | } |
2169 | return 0; | 2319 | return 0; |
2170 | } | 2320 | } |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 800a3499cc3f..c4b829806855 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -20,10 +20,10 @@ | |||
20 | #define __BTRFS__ | 20 | #define __BTRFS__ |
21 | 21 | ||
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/buffer_head.h> | ||
24 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
25 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
26 | #include "bit-radix.h" | 25 | #include "bit-radix.h" |
26 | #include "extent_map.h" | ||
27 | 27 | ||
28 | struct btrfs_trans_handle; | 28 | struct btrfs_trans_handle; |
29 | struct btrfs_transaction; | 29 | struct btrfs_transaction; |
@@ -32,7 +32,7 @@ extern struct kmem_cache *btrfs_transaction_cachep; | |||
32 | extern struct kmem_cache *btrfs_bit_radix_cachep; | 32 | extern struct kmem_cache *btrfs_bit_radix_cachep; |
33 | extern struct kmem_cache *btrfs_path_cachep; | 33 | extern struct kmem_cache *btrfs_path_cachep; |
34 | 34 | ||
35 | #define BTRFS_MAGIC "_BtRfS_M" | 35 | #define BTRFS_MAGIC "_B2RfS_M" |
36 | 36 | ||
37 | #define BTRFS_ROOT_TREE_OBJECTID 1ULL | 37 | #define BTRFS_ROOT_TREE_OBJECTID 1ULL |
38 | #define BTRFS_EXTENT_TREE_OBJECTID 2ULL | 38 | #define BTRFS_EXTENT_TREE_OBJECTID 2ULL |
@@ -78,41 +78,41 @@ extern struct kmem_cache *btrfs_path_cachep; | |||
78 | */ | 78 | */ |
79 | struct btrfs_disk_key { | 79 | struct btrfs_disk_key { |
80 | __le64 objectid; | 80 | __le64 objectid; |
81 | __le32 flags; | 81 | u8 type; |
82 | __le64 offset; | 82 | __le64 offset; |
83 | } __attribute__ ((__packed__)); | 83 | } __attribute__ ((__packed__)); |
84 | 84 | ||
85 | struct btrfs_key { | 85 | struct btrfs_key { |
86 | u64 objectid; | 86 | u64 objectid; |
87 | u32 flags; | 87 | u8 type; |
88 | u64 offset; | 88 | u64 offset; |
89 | } __attribute__ ((__packed__)); | 89 | } __attribute__ ((__packed__)); |
90 | 90 | ||
91 | #define BTRFS_FSID_SIZE 16 | ||
91 | /* | 92 | /* |
92 | * every tree block (leaf or node) starts with this header. | 93 | * every tree block (leaf or node) starts with this header. |
93 | */ | 94 | */ |
94 | struct btrfs_header { | 95 | struct btrfs_header { |
95 | u8 csum[BTRFS_CSUM_SIZE]; | 96 | u8 csum[BTRFS_CSUM_SIZE]; |
96 | u8 fsid[16]; /* FS specific uuid */ | 97 | u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ |
97 | __le64 blocknr; /* which block this node is supposed to live in */ | 98 | __le64 blocknr; /* which block this node is supposed to live in */ |
98 | __le64 generation; | 99 | __le64 generation; |
99 | __le64 owner; | 100 | __le64 owner; |
100 | __le16 nritems; | 101 | __le32 nritems; |
101 | __le16 flags; | 102 | __le16 flags; |
102 | u8 level; | 103 | u8 level; |
103 | } __attribute__ ((__packed__)); | 104 | } __attribute__ ((__packed__)); |
104 | 105 | ||
105 | #define BTRFS_MAX_LEVEL 8 | 106 | #define BTRFS_MAX_LEVEL 8 |
106 | #define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->blocksize - \ | 107 | #define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \ |
107 | sizeof(struct btrfs_header)) / \ | 108 | sizeof(struct btrfs_header)) / \ |
108 | (sizeof(struct btrfs_disk_key) + sizeof(u64))) | 109 | (sizeof(struct btrfs_disk_key) + sizeof(u64))) |
109 | #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) | 110 | #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) |
110 | #define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->blocksize)) | 111 | #define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize)) |
111 | #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ | 112 | #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ |
112 | sizeof(struct btrfs_item) - \ | 113 | sizeof(struct btrfs_item) - \ |
113 | sizeof(struct btrfs_file_extent_item)) | 114 | sizeof(struct btrfs_file_extent_item)) |
114 | 115 | ||
115 | struct buffer_head; | ||
116 | /* | 116 | /* |
117 | * the super block basically lists the main trees of the FS | 117 | * the super block basically lists the main trees of the FS |
118 | * it currently lacks any block count etc etc | 118 | * it currently lacks any block count etc etc |
@@ -128,7 +128,9 @@ struct btrfs_super_block { | |||
128 | __le64 total_blocks; | 128 | __le64 total_blocks; |
129 | __le64 blocks_used; | 129 | __le64 blocks_used; |
130 | __le64 root_dir_objectid; | 130 | __le64 root_dir_objectid; |
131 | __le32 blocksize; | 131 | __le32 sectorsize; |
132 | __le32 nodesize; | ||
133 | __le32 leafsize; | ||
132 | } __attribute__ ((__packed__)); | 134 | } __attribute__ ((__packed__)); |
133 | 135 | ||
134 | /* | 136 | /* |
@@ -138,7 +140,7 @@ struct btrfs_super_block { | |||
138 | struct btrfs_item { | 140 | struct btrfs_item { |
139 | struct btrfs_disk_key key; | 141 | struct btrfs_disk_key key; |
140 | __le32 offset; | 142 | __le32 offset; |
141 | __le16 size; | 143 | __le32 size; |
142 | } __attribute__ ((__packed__)); | 144 | } __attribute__ ((__packed__)); |
143 | 145 | ||
144 | /* | 146 | /* |
@@ -176,7 +178,7 @@ struct btrfs_node { | |||
176 | * used while walking the tree. | 178 | * used while walking the tree. |
177 | */ | 179 | */ |
178 | struct btrfs_path { | 180 | struct btrfs_path { |
179 | struct buffer_head *nodes[BTRFS_MAX_LEVEL]; | 181 | struct extent_buffer *nodes[BTRFS_MAX_LEVEL]; |
180 | int slots[BTRFS_MAX_LEVEL]; | 182 | int slots[BTRFS_MAX_LEVEL]; |
181 | int reada; | 183 | int reada; |
182 | int lowest_level; | 184 | int lowest_level; |
@@ -292,6 +294,7 @@ struct btrfs_block_group_cache { | |||
292 | }; | 294 | }; |
293 | 295 | ||
294 | struct btrfs_fs_info { | 296 | struct btrfs_fs_info { |
297 | u8 fsid[BTRFS_FSID_SIZE]; | ||
295 | struct btrfs_root *extent_root; | 298 | struct btrfs_root *extent_root; |
296 | struct btrfs_root *tree_root; | 299 | struct btrfs_root *tree_root; |
297 | struct radix_tree_root fs_roots_radix; | 300 | struct radix_tree_root fs_roots_radix; |
@@ -304,9 +307,8 @@ struct btrfs_fs_info { | |||
304 | u64 generation; | 307 | u64 generation; |
305 | u64 last_trans_committed; | 308 | u64 last_trans_committed; |
306 | struct btrfs_transaction *running_transaction; | 309 | struct btrfs_transaction *running_transaction; |
307 | struct btrfs_super_block *disk_super; | ||
308 | struct btrfs_super_block super_copy; | 310 | struct btrfs_super_block super_copy; |
309 | struct buffer_head *sb_buffer; | 311 | struct extent_buffer *sb_buffer; |
310 | struct super_block *sb; | 312 | struct super_block *sb; |
311 | struct inode *btree_inode; | 313 | struct inode *btree_inode; |
312 | struct mutex trans_mutex; | 314 | struct mutex trans_mutex; |
@@ -325,8 +327,8 @@ struct btrfs_fs_info { | |||
325 | * and for the extent tree extent_root root. | 327 | * and for the extent tree extent_root root. |
326 | */ | 328 | */ |
327 | struct btrfs_root { | 329 | struct btrfs_root { |
328 | struct buffer_head *node; | 330 | struct extent_buffer *node; |
329 | struct buffer_head *commit_root; | 331 | struct extent_buffer *commit_root; |
330 | struct btrfs_root_item root_item; | 332 | struct btrfs_root_item root_item; |
331 | struct btrfs_key root_key; | 333 | struct btrfs_key root_key; |
332 | struct btrfs_fs_info *fs_info; | 334 | struct btrfs_fs_info *fs_info; |
@@ -336,7 +338,16 @@ struct btrfs_root { | |||
336 | struct rw_semaphore snap_sem; | 338 | struct rw_semaphore snap_sem; |
337 | u64 objectid; | 339 | u64 objectid; |
338 | u64 last_trans; | 340 | u64 last_trans; |
339 | u32 blocksize; | 341 | |
342 | /* data allocations are done in sectorsize units */ | ||
343 | u32 sectorsize; | ||
344 | |||
345 | /* node allocations are done in nodesize units */ | ||
346 | u32 nodesize; | ||
347 | |||
348 | /* leaf allocations are done in leafsize units */ | ||
349 | u32 leafsize; | ||
350 | |||
340 | u32 type; | 351 | u32 type; |
341 | u64 highest_inode; | 352 | u64 highest_inode; |
342 | u64 last_inode_alloc; | 353 | u64 last_inode_alloc; |
@@ -347,12 +358,6 @@ struct btrfs_root { | |||
347 | char *name; | 358 | char *name; |
348 | }; | 359 | }; |
349 | 360 | ||
350 | /* the lower bits in the key flags defines the item type */ | ||
351 | #define BTRFS_KEY_TYPE_MAX 256 | ||
352 | #define BTRFS_KEY_TYPE_SHIFT 24 | ||
353 | #define BTRFS_KEY_TYPE_MASK (((u32)BTRFS_KEY_TYPE_MAX - 1) << \ | ||
354 | BTRFS_KEY_TYPE_SHIFT) | ||
355 | |||
356 | /* | 361 | /* |
357 | * inode items have the data typically returned from stat and store other | 362 | * inode items have the data typically returned from stat and store other |
358 | * info about object characteristics. There is one for every file and dir in | 363 | * info about object characteristics. There is one for every file and dir in |
@@ -402,246 +407,253 @@ struct btrfs_root { | |||
402 | */ | 407 | */ |
403 | #define BTRFS_STRING_ITEM_KEY 253 | 408 | #define BTRFS_STRING_ITEM_KEY 253 |
404 | 409 | ||
410 | /* some macros to generate set/get funcs for the struct fields. This | ||
411 | * assumes there is a lefoo_to_cpu for every type, so lets make a simple | ||
412 | * one for u8: | ||
413 | */ | ||
414 | #define le8_to_cpu(v) (v) | ||
415 | #define cpu_to_le8(v) (v) | ||
416 | #define __le8 u8 | ||
417 | |||
418 | #define read_eb_member(eb, ptr, type, member, result) ( \ | ||
419 | read_extent_buffer(eb, (char *)(result), \ | ||
420 | ((unsigned long)(ptr)) + \ | ||
421 | offsetof(type, member), \ | ||
422 | sizeof(((type *)0)->member))) | ||
423 | |||
424 | #define write_eb_member(eb, ptr, type, member, result) ( \ | ||
425 | write_extent_buffer(eb, (char *)(result), \ | ||
426 | ((unsigned long)(ptr)) + \ | ||
427 | offsetof(type, member), \ | ||
428 | sizeof(((type *)0)->member))) | ||
429 | |||
430 | #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ | ||
431 | static inline u##bits btrfs_##name(struct extent_buffer *eb, \ | ||
432 | type *s) \ | ||
433 | { \ | ||
434 | __le##bits res; \ | ||
435 | read_eb_member(eb, s, type, member, &res); \ | ||
436 | return le##bits##_to_cpu(res); \ | ||
437 | } \ | ||
438 | static inline void btrfs_set_##name(struct extent_buffer *eb, \ | ||
439 | type *s, u##bits val) \ | ||
440 | { \ | ||
441 | val = cpu_to_le##bits(val); \ | ||
442 | write_eb_member(eb, s, type, member, &val); \ | ||
443 | } | ||
444 | |||
445 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ | ||
446 | static inline u##bits btrfs_##name(struct extent_buffer *eb) \ | ||
447 | { \ | ||
448 | __le##bits res; \ | ||
449 | read_eb_member(eb, NULL, type, member, &res); \ | ||
450 | return le##bits##_to_cpu(res); \ | ||
451 | } \ | ||
452 | static inline void btrfs_set_##name(struct extent_buffer *eb, \ | ||
453 | u##bits val) \ | ||
454 | { \ | ||
455 | val = cpu_to_le##bits(val); \ | ||
456 | write_eb_member(eb, NULL, type, member, &val); \ | ||
457 | } | ||
405 | 458 | ||
406 | static inline u64 btrfs_block_group_used(struct btrfs_block_group_item *bi) | 459 | #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ |
407 | { | 460 | static inline u##bits btrfs_##name(type *s) \ |
408 | return le64_to_cpu(bi->used); | 461 | { \ |
409 | } | 462 | return le##bits##_to_cpu(s->member); \ |
410 | 463 | } \ | |
411 | static inline void btrfs_set_block_group_used(struct | 464 | static inline void btrfs_set_##name(type *s, u##bits val) \ |
412 | btrfs_block_group_item *bi, | 465 | { \ |
413 | u64 val) | 466 | s->member = cpu_to_le##bits(val); \ |
414 | { | ||
415 | bi->used = cpu_to_le64(val); | ||
416 | } | ||
417 | |||
418 | static inline u64 btrfs_inode_generation(struct btrfs_inode_item *i) | ||
419 | { | ||
420 | return le64_to_cpu(i->generation); | ||
421 | } | ||
422 | |||
423 | static inline void btrfs_set_inode_generation(struct btrfs_inode_item *i, | ||
424 | u64 val) | ||
425 | { | ||
426 | i->generation = cpu_to_le64(val); | ||
427 | } | ||
428 | |||
429 | static inline u64 btrfs_inode_size(struct btrfs_inode_item *i) | ||
430 | { | ||
431 | return le64_to_cpu(i->size); | ||
432 | } | ||
433 | |||
434 | static inline void btrfs_set_inode_size(struct btrfs_inode_item *i, u64 val) | ||
435 | { | ||
436 | i->size = cpu_to_le64(val); | ||
437 | } | ||
438 | |||
439 | static inline u64 btrfs_inode_nblocks(struct btrfs_inode_item *i) | ||
440 | { | ||
441 | return le64_to_cpu(i->nblocks); | ||
442 | } | ||
443 | |||
444 | static inline void btrfs_set_inode_nblocks(struct btrfs_inode_item *i, u64 val) | ||
445 | { | ||
446 | i->nblocks = cpu_to_le64(val); | ||
447 | } | ||
448 | |||
449 | static inline u64 btrfs_inode_block_group(struct btrfs_inode_item *i) | ||
450 | { | ||
451 | return le64_to_cpu(i->block_group); | ||
452 | } | ||
453 | |||
454 | static inline void btrfs_set_inode_block_group(struct btrfs_inode_item *i, | ||
455 | u64 val) | ||
456 | { | ||
457 | i->block_group = cpu_to_le64(val); | ||
458 | } | ||
459 | |||
460 | static inline u32 btrfs_inode_nlink(struct btrfs_inode_item *i) | ||
461 | { | ||
462 | return le32_to_cpu(i->nlink); | ||
463 | } | ||
464 | |||
465 | static inline void btrfs_set_inode_nlink(struct btrfs_inode_item *i, u32 val) | ||
466 | { | ||
467 | i->nlink = cpu_to_le32(val); | ||
468 | } | ||
469 | |||
470 | static inline u32 btrfs_inode_uid(struct btrfs_inode_item *i) | ||
471 | { | ||
472 | return le32_to_cpu(i->uid); | ||
473 | } | ||
474 | |||
475 | static inline void btrfs_set_inode_uid(struct btrfs_inode_item *i, u32 val) | ||
476 | { | ||
477 | i->uid = cpu_to_le32(val); | ||
478 | } | ||
479 | |||
480 | static inline u32 btrfs_inode_gid(struct btrfs_inode_item *i) | ||
481 | { | ||
482 | return le32_to_cpu(i->gid); | ||
483 | } | ||
484 | |||
485 | static inline void btrfs_set_inode_gid(struct btrfs_inode_item *i, u32 val) | ||
486 | { | ||
487 | i->gid = cpu_to_le32(val); | ||
488 | } | ||
489 | |||
490 | static inline u32 btrfs_inode_mode(struct btrfs_inode_item *i) | ||
491 | { | ||
492 | return le32_to_cpu(i->mode); | ||
493 | } | ||
494 | |||
495 | static inline void btrfs_set_inode_mode(struct btrfs_inode_item *i, u32 val) | ||
496 | { | ||
497 | i->mode = cpu_to_le32(val); | ||
498 | } | 467 | } |
499 | 468 | ||
500 | static inline u32 btrfs_inode_rdev(struct btrfs_inode_item *i) | 469 | /* struct btrfs_block_group_item */ |
501 | { | 470 | BTRFS_SETGET_STACK_FUNCS(block_group_used, struct btrfs_block_group_item, |
502 | return le32_to_cpu(i->rdev); | 471 | used, 64); |
503 | } | 472 | BTRFS_SETGET_FUNCS(disk_block_group_used, struct btrfs_block_group_item, |
473 | used, 64); | ||
504 | 474 | ||
505 | static inline void btrfs_set_inode_rdev(struct btrfs_inode_item *i, u32 val) | 475 | /* struct btrfs_inode_item */ |
506 | { | 476 | BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64); |
507 | i->rdev = cpu_to_le32(val); | 477 | BTRFS_SETGET_FUNCS(inode_size, struct btrfs_inode_item, size, 64); |
508 | } | 478 | BTRFS_SETGET_FUNCS(inode_nblocks, struct btrfs_inode_item, nblocks, 64); |
479 | BTRFS_SETGET_FUNCS(inode_block_group, struct btrfs_inode_item, block_group, 64); | ||
480 | BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32); | ||
481 | BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32); | ||
482 | BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32); | ||
483 | BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32); | ||
484 | BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 32); | ||
485 | BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 16); | ||
486 | BTRFS_SETGET_FUNCS(inode_compat_flags, struct btrfs_inode_item, | ||
487 | compat_flags, 16); | ||
509 | 488 | ||
510 | static inline u16 btrfs_inode_flags(struct btrfs_inode_item *i) | 489 | static inline struct btrfs_inode_timespec * |
490 | btrfs_inode_atime(struct btrfs_inode_item *inode_item) | ||
511 | { | 491 | { |
512 | return le16_to_cpu(i->flags); | 492 | unsigned long ptr = (unsigned long)inode_item; |
493 | ptr += offsetof(struct btrfs_inode_item, atime); | ||
494 | return (struct btrfs_inode_timespec *)ptr; | ||
513 | } | 495 | } |
514 | 496 | ||
515 | static inline void btrfs_set_inode_flags(struct btrfs_inode_item *i, u16 val) | 497 | static inline struct btrfs_inode_timespec * |
498 | btrfs_inode_mtime(struct btrfs_inode_item *inode_item) | ||
516 | { | 499 | { |
517 | i->flags = cpu_to_le16(val); | 500 | unsigned long ptr = (unsigned long)inode_item; |
501 | ptr += offsetof(struct btrfs_inode_item, mtime); | ||
502 | return (struct btrfs_inode_timespec *)ptr; | ||
518 | } | 503 | } |
519 | 504 | ||
520 | static inline u16 btrfs_inode_compat_flags(struct btrfs_inode_item *i) | 505 | static inline struct btrfs_inode_timespec * |
506 | btrfs_inode_ctime(struct btrfs_inode_item *inode_item) | ||
521 | { | 507 | { |
522 | return le16_to_cpu(i->compat_flags); | 508 | unsigned long ptr = (unsigned long)inode_item; |
509 | ptr += offsetof(struct btrfs_inode_item, ctime); | ||
510 | return (struct btrfs_inode_timespec *)ptr; | ||
523 | } | 511 | } |
524 | 512 | ||
525 | static inline void btrfs_set_inode_compat_flags(struct btrfs_inode_item *i, | 513 | static inline struct btrfs_inode_timespec * |
526 | u16 val) | 514 | btrfs_inode_otime(struct btrfs_inode_item *inode_item) |
527 | { | 515 | { |
528 | i->compat_flags = cpu_to_le16(val); | 516 | unsigned long ptr = (unsigned long)inode_item; |
517 | ptr += offsetof(struct btrfs_inode_item, otime); | ||
518 | return (struct btrfs_inode_timespec *)ptr; | ||
529 | } | 519 | } |
530 | 520 | ||
531 | static inline u64 btrfs_timespec_sec(struct btrfs_inode_timespec *ts) | 521 | BTRFS_SETGET_FUNCS(timespec_sec, struct btrfs_inode_timespec, sec, 64); |
532 | { | 522 | BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_inode_timespec, nsec, 32); |
533 | return le64_to_cpu(ts->sec); | ||
534 | } | ||
535 | 523 | ||
536 | static inline void btrfs_set_timespec_sec(struct btrfs_inode_timespec *ts, | 524 | /* struct btrfs_extent_item */ |
537 | u64 val) | 525 | BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); |
538 | { | 526 | BTRFS_SETGET_FUNCS(extent_owner, struct btrfs_extent_item, owner, 32); |
539 | ts->sec = cpu_to_le64(val); | ||
540 | } | ||
541 | 527 | ||
542 | static inline u32 btrfs_timespec_nsec(struct btrfs_inode_timespec *ts) | 528 | BTRFS_SETGET_STACK_FUNCS(stack_extent_refs, struct btrfs_extent_item, |
543 | { | 529 | refs, 32); |
544 | return le32_to_cpu(ts->nsec); | 530 | BTRFS_SETGET_STACK_FUNCS(stack_extent_owner, struct btrfs_extent_item, |
545 | } | 531 | owner, 32); |
546 | 532 | ||
547 | static inline void btrfs_set_timespec_nsec(struct btrfs_inode_timespec *ts, | 533 | /* struct btrfs_node */ |
548 | u32 val) | 534 | BTRFS_SETGET_FUNCS(key_blockptr, struct btrfs_key_ptr, blockptr, 64); |
549 | { | ||
550 | ts->nsec = cpu_to_le32(val); | ||
551 | } | ||
552 | 535 | ||
553 | static inline u32 btrfs_extent_refs(struct btrfs_extent_item *ei) | 536 | static inline u64 btrfs_node_blockptr(struct extent_buffer *eb, int nr) |
554 | { | 537 | { |
555 | return le32_to_cpu(ei->refs); | 538 | unsigned long ptr; |
539 | ptr = offsetof(struct btrfs_node, ptrs) + | ||
540 | sizeof(struct btrfs_key_ptr) * nr; | ||
541 | return btrfs_key_blockptr(eb, (struct btrfs_key_ptr *)ptr); | ||
556 | } | 542 | } |
557 | 543 | ||
558 | static inline void btrfs_set_extent_refs(struct btrfs_extent_item *ei, u32 val) | 544 | static inline void btrfs_set_node_blockptr(struct extent_buffer *eb, |
545 | int nr, u64 val) | ||
559 | { | 546 | { |
560 | ei->refs = cpu_to_le32(val); | 547 | unsigned long ptr; |
548 | ptr = offsetof(struct btrfs_node, ptrs) + | ||
549 | sizeof(struct btrfs_key_ptr) * nr; | ||
550 | btrfs_set_key_blockptr(eb, (struct btrfs_key_ptr *)ptr, val); | ||
561 | } | 551 | } |
562 | 552 | ||
563 | static inline u64 btrfs_extent_owner(struct btrfs_extent_item *ei) | 553 | static unsigned long btrfs_node_key_ptr_offset(int nr) |
564 | { | 554 | { |
565 | return le64_to_cpu(ei->owner); | 555 | return offsetof(struct btrfs_node, ptrs) + |
556 | sizeof(struct btrfs_key_ptr) * nr; | ||
566 | } | 557 | } |
567 | 558 | ||
568 | static inline void btrfs_set_extent_owner(struct btrfs_extent_item *ei, u64 val) | 559 | static void btrfs_node_key(struct extent_buffer *eb, |
560 | struct btrfs_disk_key *disk_key, int nr) | ||
569 | { | 561 | { |
570 | ei->owner = cpu_to_le64(val); | 562 | unsigned long ptr; |
563 | ptr = btrfs_node_key_ptr_offset(nr); | ||
564 | read_eb_member(eb, (struct btrfs_key_ptr *)ptr, | ||
565 | struct btrfs_key_ptr, key, disk_key); | ||
571 | } | 566 | } |
572 | 567 | static inline void btrfs_set_node_key(struct extent_buffer *eb, | |
573 | static inline u64 btrfs_node_blockptr(struct btrfs_node *n, int nr) | 568 | struct btrfs_disk_key *disk_key, int nr) |
574 | { | 569 | { |
575 | return le64_to_cpu(n->ptrs[nr].blockptr); | 570 | unsigned long ptr; |
571 | ptr = btrfs_node_key_ptr_offset(nr); | ||
572 | write_eb_member(eb, (struct btrfs_key_ptr *)ptr, | ||
573 | struct btrfs_key_ptr, key, disk_key); | ||
576 | } | 574 | } |
577 | 575 | ||
576 | /* struct btrfs_item */ | ||
577 | BTRFS_SETGET_FUNCS(item_offset, struct btrfs_item, offset, 32); | ||
578 | BTRFS_SETGET_FUNCS(item_size, struct btrfs_item, size, 32); | ||
578 | 579 | ||
579 | static inline void btrfs_set_node_blockptr(struct btrfs_node *n, int nr, | 580 | static inline unsigned long btrfs_item_nr_offset(int nr) |
580 | u64 val) | ||
581 | { | 581 | { |
582 | n->ptrs[nr].blockptr = cpu_to_le64(val); | 582 | return offsetof(struct btrfs_leaf, items) + |
583 | sizeof(struct btrfs_item) * nr; | ||
583 | } | 584 | } |
584 | 585 | ||
585 | static inline u32 btrfs_item_offset(struct btrfs_item *item) | 586 | static inline struct btrfs_item *btrfs_item_nr(struct extent_buffer *eb, |
587 | int nr) | ||
586 | { | 588 | { |
587 | return le32_to_cpu(item->offset); | 589 | return (struct btrfs_item *)btrfs_item_nr_offset(nr); |
588 | } | 590 | } |
589 | 591 | ||
590 | static inline void btrfs_set_item_offset(struct btrfs_item *item, u32 val) | 592 | static inline u32 btrfs_item_end(struct extent_buffer *eb, |
593 | struct btrfs_item *item) | ||
591 | { | 594 | { |
592 | item->offset = cpu_to_le32(val); | 595 | return btrfs_item_offset(eb, item) + btrfs_item_size(eb, item); |
593 | } | 596 | } |
594 | 597 | ||
595 | static inline u32 btrfs_item_end(struct btrfs_item *item) | 598 | static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) |
596 | { | 599 | { |
597 | return le32_to_cpu(item->offset) + le16_to_cpu(item->size); | 600 | return btrfs_item_end(eb, btrfs_item_nr(eb, nr)); |
598 | } | 601 | } |
599 | 602 | ||
600 | static inline u16 btrfs_item_size(struct btrfs_item *item) | 603 | static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) |
601 | { | 604 | { |
602 | return le16_to_cpu(item->size); | 605 | return btrfs_item_offset(eb, btrfs_item_nr(eb, nr)); |
603 | } | 606 | } |
604 | 607 | ||
605 | static inline void btrfs_set_item_size(struct btrfs_item *item, u16 val) | 608 | static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) |
606 | { | 609 | { |
607 | item->size = cpu_to_le16(val); | 610 | return btrfs_item_size(eb, btrfs_item_nr(eb, nr)); |
608 | } | 611 | } |
609 | 612 | ||
610 | static inline u16 btrfs_dir_flags(struct btrfs_dir_item *d) | 613 | static inline void btrfs_item_key(struct extent_buffer *eb, |
614 | struct btrfs_disk_key *disk_key, int nr) | ||
611 | { | 615 | { |
612 | return le16_to_cpu(d->flags); | 616 | struct btrfs_item *item = btrfs_item_nr(eb, nr); |
617 | read_eb_member(eb, item, struct btrfs_item, key, disk_key); | ||
613 | } | 618 | } |
614 | 619 | ||
615 | static inline void btrfs_set_dir_flags(struct btrfs_dir_item *d, u16 val) | 620 | static inline void btrfs_set_item_key(struct extent_buffer *eb, |
621 | struct btrfs_disk_key *disk_key, int nr) | ||
616 | { | 622 | { |
617 | d->flags = cpu_to_le16(val); | 623 | struct btrfs_item *item = btrfs_item_nr(eb, nr); |
624 | write_eb_member(eb, item, struct btrfs_item, key, disk_key); | ||
618 | } | 625 | } |
619 | 626 | ||
620 | static inline u8 btrfs_dir_type(struct btrfs_dir_item *d) | 627 | /* struct btrfs_dir_item */ |
621 | { | 628 | BTRFS_SETGET_FUNCS(dir_flags, struct btrfs_dir_item, flags, 16); |
622 | return d->type; | 629 | BTRFS_SETGET_FUNCS(dir_type, struct btrfs_dir_item, type, 8); |
623 | } | 630 | BTRFS_SETGET_FUNCS(dir_name_len, struct btrfs_dir_item, name_len, 16); |
624 | 631 | ||
625 | static inline void btrfs_set_dir_type(struct btrfs_dir_item *d, u8 val) | 632 | static inline void btrfs_dir_item_key(struct extent_buffer *eb, |
633 | struct btrfs_dir_item *item, | ||
634 | struct btrfs_disk_key *key) | ||
626 | { | 635 | { |
627 | d->type = val; | 636 | read_eb_member(eb, item, struct btrfs_dir_item, location, key); |
628 | } | 637 | } |
629 | 638 | ||
630 | static inline u16 btrfs_dir_name_len(struct btrfs_dir_item *d) | 639 | static inline void btrfs_set_dir_item_key(struct extent_buffer *eb, |
640 | struct btrfs_dir_item *item, | ||
641 | struct btrfs_disk_key *key) | ||
631 | { | 642 | { |
632 | return le16_to_cpu(d->name_len); | 643 | write_eb_member(eb, item, struct btrfs_dir_item, location, key); |
633 | } | 644 | } |
634 | 645 | ||
635 | static inline void btrfs_set_dir_name_len(struct btrfs_dir_item *d, u16 val) | 646 | /* struct btrfs_disk_key */ |
636 | { | 647 | BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key, |
637 | d->name_len = cpu_to_le16(val); | 648 | objectid, 64); |
638 | } | 649 | BTRFS_SETGET_STACK_FUNCS(disk_key_offset, struct btrfs_disk_key, offset, 64); |
650 | BTRFS_SETGET_STACK_FUNCS(disk_key_type, struct btrfs_disk_key, type, 8); | ||
639 | 651 | ||
640 | static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, | 652 | static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, |
641 | struct btrfs_disk_key *disk) | 653 | struct btrfs_disk_key *disk) |
642 | { | 654 | { |
643 | cpu->offset = le64_to_cpu(disk->offset); | 655 | cpu->offset = le64_to_cpu(disk->offset); |
644 | cpu->flags = le32_to_cpu(disk->flags); | 656 | cpu->type = disk->type; |
645 | cpu->objectid = le64_to_cpu(disk->objectid); | 657 | cpu->objectid = le64_to_cpu(disk->objectid); |
646 | } | 658 | } |
647 | 659 | ||
@@ -649,400 +661,167 @@ static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk, | |||
649 | struct btrfs_key *cpu) | 661 | struct btrfs_key *cpu) |
650 | { | 662 | { |
651 | disk->offset = cpu_to_le64(cpu->offset); | 663 | disk->offset = cpu_to_le64(cpu->offset); |
652 | disk->flags = cpu_to_le32(cpu->flags); | 664 | disk->type = cpu->type; |
653 | disk->objectid = cpu_to_le64(cpu->objectid); | 665 | disk->objectid = cpu_to_le64(cpu->objectid); |
654 | } | 666 | } |
655 | 667 | ||
656 | static inline u64 btrfs_disk_key_objectid(struct btrfs_disk_key *disk) | 668 | static inline void btrfs_node_key_to_cpu(struct extent_buffer *eb, |
657 | { | 669 | struct btrfs_key *key, int nr) |
658 | return le64_to_cpu(disk->objectid); | ||
659 | } | ||
660 | |||
661 | static inline void btrfs_set_disk_key_objectid(struct btrfs_disk_key *disk, | ||
662 | u64 val) | ||
663 | { | ||
664 | disk->objectid = cpu_to_le64(val); | ||
665 | } | ||
666 | |||
667 | static inline u64 btrfs_disk_key_offset(struct btrfs_disk_key *disk) | ||
668 | { | ||
669 | return le64_to_cpu(disk->offset); | ||
670 | } | ||
671 | |||
672 | static inline void btrfs_set_disk_key_offset(struct btrfs_disk_key *disk, | ||
673 | u64 val) | ||
674 | { | ||
675 | disk->offset = cpu_to_le64(val); | ||
676 | } | ||
677 | |||
678 | static inline u32 btrfs_disk_key_flags(struct btrfs_disk_key *disk) | ||
679 | { | ||
680 | return le32_to_cpu(disk->flags); | ||
681 | } | ||
682 | |||
683 | static inline void btrfs_set_disk_key_flags(struct btrfs_disk_key *disk, | ||
684 | u32 val) | ||
685 | { | ||
686 | disk->flags = cpu_to_le32(val); | ||
687 | } | ||
688 | |||
689 | static inline u32 btrfs_disk_key_type(struct btrfs_disk_key *key) | ||
690 | { | ||
691 | return le32_to_cpu(key->flags) >> BTRFS_KEY_TYPE_SHIFT; | ||
692 | } | ||
693 | |||
694 | static inline void btrfs_set_disk_key_type(struct btrfs_disk_key *key, | ||
695 | u32 val) | ||
696 | { | ||
697 | u32 flags = btrfs_disk_key_flags(key); | ||
698 | BUG_ON(val >= BTRFS_KEY_TYPE_MAX); | ||
699 | val = val << BTRFS_KEY_TYPE_SHIFT; | ||
700 | flags = (flags & ~BTRFS_KEY_TYPE_MASK) | val; | ||
701 | btrfs_set_disk_key_flags(key, flags); | ||
702 | } | ||
703 | |||
704 | static inline u32 btrfs_key_type(struct btrfs_key *key) | ||
705 | { | ||
706 | return key->flags >> BTRFS_KEY_TYPE_SHIFT; | ||
707 | } | ||
708 | |||
709 | static inline void btrfs_set_key_type(struct btrfs_key *key, u32 val) | ||
710 | { | ||
711 | BUG_ON(val >= BTRFS_KEY_TYPE_MAX); | ||
712 | val = val << BTRFS_KEY_TYPE_SHIFT; | ||
713 | key->flags = (key->flags & ~(BTRFS_KEY_TYPE_MASK)) | val; | ||
714 | } | ||
715 | |||
716 | static inline u64 btrfs_header_blocknr(struct btrfs_header *h) | ||
717 | { | ||
718 | return le64_to_cpu(h->blocknr); | ||
719 | } | ||
720 | |||
721 | static inline void btrfs_set_header_blocknr(struct btrfs_header *h, u64 blocknr) | ||
722 | { | ||
723 | h->blocknr = cpu_to_le64(blocknr); | ||
724 | } | ||
725 | |||
726 | static inline u64 btrfs_header_generation(struct btrfs_header *h) | ||
727 | { | 670 | { |
728 | return le64_to_cpu(h->generation); | 671 | struct btrfs_disk_key disk_key; |
672 | btrfs_node_key(eb, &disk_key, nr); | ||
673 | btrfs_disk_key_to_cpu(key, &disk_key); | ||
729 | } | 674 | } |
730 | 675 | ||
731 | static inline void btrfs_set_header_generation(struct btrfs_header *h, | 676 | static inline void btrfs_item_key_to_cpu(struct extent_buffer *eb, |
732 | u64 val) | 677 | struct btrfs_key *key, int nr) |
733 | { | 678 | { |
734 | h->generation = cpu_to_le64(val); | 679 | struct btrfs_disk_key disk_key; |
680 | btrfs_item_key(eb, &disk_key, nr); | ||
681 | btrfs_disk_key_to_cpu(key, &disk_key); | ||
735 | } | 682 | } |
736 | 683 | ||
737 | static inline u64 btrfs_header_owner(struct btrfs_header *h) | 684 | static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, |
685 | struct btrfs_dir_item *item, | ||
686 | struct btrfs_key *key) | ||
738 | { | 687 | { |
739 | return le64_to_cpu(h->owner); | 688 | struct btrfs_disk_key disk_key; |
689 | btrfs_dir_item_key(eb, item, &disk_key); | ||
690 | btrfs_disk_key_to_cpu(key, &disk_key); | ||
740 | } | 691 | } |
741 | 692 | ||
742 | static inline void btrfs_set_header_owner(struct btrfs_header *h, | ||
743 | u64 val) | ||
744 | { | ||
745 | h->owner = cpu_to_le64(val); | ||
746 | } | ||
747 | |||
748 | static inline u16 btrfs_header_nritems(struct btrfs_header *h) | ||
749 | { | ||
750 | return le16_to_cpu(h->nritems); | ||
751 | } | ||
752 | |||
753 | static inline void btrfs_set_header_nritems(struct btrfs_header *h, u16 val) | ||
754 | { | ||
755 | h->nritems = cpu_to_le16(val); | ||
756 | } | ||
757 | |||
758 | static inline u16 btrfs_header_flags(struct btrfs_header *h) | ||
759 | { | ||
760 | return le16_to_cpu(h->flags); | ||
761 | } | ||
762 | |||
763 | static inline void btrfs_set_header_flags(struct btrfs_header *h, u16 val) | ||
764 | { | ||
765 | h->flags = cpu_to_le16(val); | ||
766 | } | ||
767 | |||
768 | static inline int btrfs_header_level(struct btrfs_header *h) | ||
769 | { | ||
770 | return h->level; | ||
771 | } | ||
772 | |||
773 | static inline void btrfs_set_header_level(struct btrfs_header *h, int level) | ||
774 | { | ||
775 | BUG_ON(level > BTRFS_MAX_LEVEL); | ||
776 | h->level = level; | ||
777 | } | ||
778 | |||
779 | static inline int btrfs_is_leaf(struct btrfs_node *n) | ||
780 | { | ||
781 | return (btrfs_header_level(&n->header) == 0); | ||
782 | } | ||
783 | |||
784 | static inline u64 btrfs_root_blocknr(struct btrfs_root_item *item) | ||
785 | { | ||
786 | return le64_to_cpu(item->blocknr); | ||
787 | } | ||
788 | |||
789 | static inline void btrfs_set_root_blocknr(struct btrfs_root_item *item, u64 val) | ||
790 | { | ||
791 | item->blocknr = cpu_to_le64(val); | ||
792 | } | ||
793 | |||
794 | static inline u64 btrfs_root_dirid(struct btrfs_root_item *item) | ||
795 | { | ||
796 | return le64_to_cpu(item->root_dirid); | ||
797 | } | ||
798 | |||
799 | static inline void btrfs_set_root_dirid(struct btrfs_root_item *item, u64 val) | ||
800 | { | ||
801 | item->root_dirid = cpu_to_le64(val); | ||
802 | } | ||
803 | |||
804 | static inline u32 btrfs_root_refs(struct btrfs_root_item *item) | ||
805 | { | ||
806 | return le32_to_cpu(item->refs); | ||
807 | } | ||
808 | |||
809 | static inline void btrfs_set_root_refs(struct btrfs_root_item *item, u32 val) | ||
810 | { | ||
811 | item->refs = cpu_to_le32(val); | ||
812 | } | ||
813 | |||
814 | static inline u32 btrfs_root_flags(struct btrfs_root_item *item) | ||
815 | { | ||
816 | return le32_to_cpu(item->flags); | ||
817 | } | ||
818 | |||
819 | static inline void btrfs_set_root_flags(struct btrfs_root_item *item, u32 val) | ||
820 | { | ||
821 | item->flags = cpu_to_le32(val); | ||
822 | } | ||
823 | |||
824 | static inline void btrfs_set_root_blocks_used(struct btrfs_root_item *item, | ||
825 | u64 val) | ||
826 | { | ||
827 | item->blocks_used = cpu_to_le64(val); | ||
828 | } | ||
829 | |||
830 | static inline u64 btrfs_root_blocks_used(struct btrfs_root_item *item) | ||
831 | { | ||
832 | return le64_to_cpu(item->blocks_used); | ||
833 | } | ||
834 | |||
835 | static inline void btrfs_set_root_block_limit(struct btrfs_root_item *item, | ||
836 | u64 val) | ||
837 | { | ||
838 | item->block_limit = cpu_to_le64(val); | ||
839 | } | ||
840 | |||
841 | static inline u64 btrfs_root_block_limit(struct btrfs_root_item *item) | ||
842 | { | ||
843 | return le64_to_cpu(item->block_limit); | ||
844 | } | ||
845 | 693 | ||
846 | static inline u64 btrfs_super_blocknr(struct btrfs_super_block *s) | 694 | static inline u8 btrfs_key_type(struct btrfs_key *key) |
847 | { | 695 | { |
848 | return le64_to_cpu(s->blocknr); | 696 | return key->type; |
849 | } | 697 | } |
850 | 698 | ||
851 | static inline void btrfs_set_super_blocknr(struct btrfs_super_block *s, u64 val) | 699 | static inline void btrfs_set_key_type(struct btrfs_key *key, u8 val) |
852 | { | 700 | { |
853 | s->blocknr = cpu_to_le64(val); | 701 | key->type = val; |
854 | } | 702 | } |
855 | 703 | ||
856 | static inline u64 btrfs_super_generation(struct btrfs_super_block *s) | 704 | /* struct btrfs_header */ |
857 | { | 705 | BTRFS_SETGET_HEADER_FUNCS(header_blocknr, struct btrfs_header, blocknr, 64); |
858 | return le64_to_cpu(s->generation); | 706 | BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header, |
859 | } | 707 | generation, 64); |
708 | BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64); | ||
709 | BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32); | ||
710 | BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 16); | ||
711 | BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8); | ||
860 | 712 | ||
861 | static inline void btrfs_set_super_generation(struct btrfs_super_block *s, | 713 | static inline u8 *btrfs_header_fsid(struct extent_buffer *eb) |
862 | u64 val) | ||
863 | { | 714 | { |
864 | s->generation = cpu_to_le64(val); | 715 | unsigned long ptr = offsetof(struct btrfs_header, fsid); |
716 | return (u8 *)ptr; | ||
865 | } | 717 | } |
866 | 718 | ||
867 | static inline u64 btrfs_super_root(struct btrfs_super_block *s) | 719 | static inline u8 *btrfs_super_fsid(struct extent_buffer *eb) |
868 | { | 720 | { |
869 | return le64_to_cpu(s->root); | 721 | unsigned long ptr = offsetof(struct btrfs_super_block, fsid); |
722 | return (u8 *)ptr; | ||
870 | } | 723 | } |
871 | 724 | ||
872 | static inline void btrfs_set_super_root(struct btrfs_super_block *s, u64 val) | 725 | static inline u8 *btrfs_header_csum(struct extent_buffer *eb) |
873 | { | 726 | { |
874 | s->root = cpu_to_le64(val); | 727 | unsigned long ptr = offsetof(struct btrfs_header, csum); |
728 | return (u8 *)ptr; | ||
875 | } | 729 | } |
876 | 730 | ||
877 | static inline u64 btrfs_super_total_blocks(struct btrfs_super_block *s) | 731 | static inline struct btrfs_node *btrfs_buffer_node(struct extent_buffer *eb) |
878 | { | 732 | { |
879 | return le64_to_cpu(s->total_blocks); | 733 | return NULL; |
880 | } | 734 | } |
881 | 735 | ||
882 | static inline void btrfs_set_super_total_blocks(struct btrfs_super_block *s, | 736 | static inline struct btrfs_leaf *btrfs_buffer_leaf(struct extent_buffer *eb) |
883 | u64 val) | ||
884 | { | 737 | { |
885 | s->total_blocks = cpu_to_le64(val); | 738 | return NULL; |
886 | } | 739 | } |
887 | 740 | ||
888 | static inline u64 btrfs_super_blocks_used(struct btrfs_super_block *s) | 741 | static inline struct btrfs_header *btrfs_buffer_header(struct extent_buffer *eb) |
889 | { | 742 | { |
890 | return le64_to_cpu(s->blocks_used); | 743 | return NULL; |
891 | } | 744 | } |
892 | 745 | ||
893 | static inline void btrfs_set_super_blocks_used(struct btrfs_super_block *s, | 746 | static inline int btrfs_is_leaf(struct extent_buffer *eb) |
894 | u64 val) | ||
895 | { | 747 | { |
896 | s->blocks_used = cpu_to_le64(val); | 748 | return (btrfs_header_level(eb) == 0); |
897 | } | 749 | } |
898 | 750 | ||
899 | static inline u32 btrfs_super_blocksize(struct btrfs_super_block *s) | 751 | /* struct btrfs_root_item */ |
900 | { | 752 | BTRFS_SETGET_FUNCS(disk_root_refs, struct btrfs_root_item, refs, 32); |
901 | return le32_to_cpu(s->blocksize); | 753 | BTRFS_SETGET_FUNCS(disk_root_blocknr, struct btrfs_root_item, blocknr, 64); |
902 | } | ||
903 | 754 | ||
904 | static inline void btrfs_set_super_blocksize(struct btrfs_super_block *s, | 755 | BTRFS_SETGET_STACK_FUNCS(root_blocknr, struct btrfs_root_item, blocknr, 64); |
905 | u32 val) | 756 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); |
906 | { | 757 | BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32); |
907 | s->blocksize = cpu_to_le32(val); | 758 | BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 32); |
908 | } | 759 | BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, blocks_used, 64); |
760 | BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, block_limit, 64); | ||
909 | 761 | ||
910 | static inline u64 btrfs_super_root_dir(struct btrfs_super_block *s) | 762 | /* struct btrfs_super_block */ |
911 | { | 763 | BTRFS_SETGET_STACK_FUNCS(super_blocknr, struct btrfs_super_block, blocknr, 64); |
912 | return le64_to_cpu(s->root_dir_objectid); | 764 | BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, |
913 | } | 765 | generation, 64); |
766 | BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64); | ||
767 | BTRFS_SETGET_STACK_FUNCS(super_total_blocks, struct btrfs_super_block, | ||
768 | total_blocks, 64); | ||
769 | BTRFS_SETGET_STACK_FUNCS(super_blocks_used, struct btrfs_super_block, | ||
770 | blocks_used, 64); | ||
771 | BTRFS_SETGET_STACK_FUNCS(super_sectorsize, struct btrfs_super_block, | ||
772 | sectorsize, 32); | ||
773 | BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block, | ||
774 | nodesize, 32); | ||
775 | BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block, | ||
776 | leafsize, 32); | ||
777 | BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block, | ||
778 | root_dir_objectid, 64); | ||
914 | 779 | ||
915 | static inline void btrfs_set_super_root_dir(struct btrfs_super_block *s, u64 | 780 | static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) |
916 | val) | ||
917 | { | 781 | { |
918 | s->root_dir_objectid = cpu_to_le64(val); | 782 | return offsetof(struct btrfs_leaf, items); |
919 | } | 783 | } |
920 | 784 | ||
921 | static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l) | 785 | /* struct btrfs_file_extent_item */ |
922 | { | 786 | BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8); |
923 | return (u8 *)l->items; | ||
924 | } | ||
925 | 787 | ||
926 | static inline int btrfs_file_extent_type(struct btrfs_file_extent_item *e) | 788 | static inline unsigned long btrfs_file_extent_inline_start(struct |
927 | { | ||
928 | return e->type; | ||
929 | } | ||
930 | static inline void btrfs_set_file_extent_type(struct btrfs_file_extent_item *e, | ||
931 | u8 val) | ||
932 | { | ||
933 | e->type = val; | ||
934 | } | ||
935 | |||
936 | static inline char *btrfs_file_extent_inline_start(struct | ||
937 | btrfs_file_extent_item *e) | 789 | btrfs_file_extent_item *e) |
938 | { | 790 | { |
939 | return (char *)(&e->disk_blocknr); | 791 | unsigned long offset = (unsigned long)e; |
792 | offset += offsetof(struct btrfs_file_extent_item, disk_blocknr); | ||
793 | return offset; | ||
940 | } | 794 | } |
941 | 795 | ||
942 | static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize) | 796 | static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize) |
943 | { | 797 | { |
944 | return (unsigned long)(&((struct | 798 | return offsetof(struct btrfs_file_extent_item, disk_blocknr) + datasize; |
945 | btrfs_file_extent_item *)NULL)->disk_blocknr) + datasize; | ||
946 | } | ||
947 | |||
948 | static inline u32 btrfs_file_extent_inline_len(struct btrfs_item *e) | ||
949 | { | ||
950 | struct btrfs_file_extent_item *fe = NULL; | ||
951 | return btrfs_item_size(e) - (unsigned long)(&fe->disk_blocknr); | ||
952 | } | ||
953 | |||
954 | static inline u64 btrfs_file_extent_disk_blocknr(struct btrfs_file_extent_item | ||
955 | *e) | ||
956 | { | ||
957 | return le64_to_cpu(e->disk_blocknr); | ||
958 | } | 799 | } |
959 | 800 | ||
960 | static inline void btrfs_set_file_extent_disk_blocknr(struct | 801 | static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, |
961 | btrfs_file_extent_item | 802 | struct btrfs_item *e) |
962 | *e, u64 val) | ||
963 | { | 803 | { |
964 | e->disk_blocknr = cpu_to_le64(val); | 804 | unsigned long offset; |
805 | offset = offsetof(struct btrfs_file_extent_item, disk_blocknr); | ||
806 | return btrfs_item_size(eb, e) - offset; | ||
965 | } | 807 | } |
966 | 808 | ||
967 | static inline u64 btrfs_file_extent_generation(struct btrfs_file_extent_item *e) | 809 | BTRFS_SETGET_FUNCS(file_extent_disk_blocknr, struct btrfs_file_extent_item, |
968 | { | 810 | disk_blocknr, 64); |
969 | return le64_to_cpu(e->generation); | 811 | BTRFS_SETGET_FUNCS(file_extent_generation, struct btrfs_file_extent_item, |
970 | } | 812 | generation, 64); |
971 | 813 | BTRFS_SETGET_FUNCS(file_extent_disk_num_blocks, struct btrfs_file_extent_item, | |
972 | static inline void btrfs_set_file_extent_generation(struct | 814 | disk_num_blocks, 64); |
973 | btrfs_file_extent_item *e, | 815 | BTRFS_SETGET_FUNCS(file_extent_offset, struct btrfs_file_extent_item, |
974 | u64 val) | 816 | offset, 64); |
975 | { | 817 | BTRFS_SETGET_FUNCS(file_extent_num_blocks, struct btrfs_file_extent_item, |
976 | e->generation = cpu_to_le64(val); | 818 | num_blocks, 64); |
977 | } | ||
978 | |||
979 | static inline u64 btrfs_file_extent_disk_num_blocks(struct | ||
980 | btrfs_file_extent_item *e) | ||
981 | { | ||
982 | return le64_to_cpu(e->disk_num_blocks); | ||
983 | } | ||
984 | |||
985 | static inline void btrfs_set_file_extent_disk_num_blocks(struct | ||
986 | btrfs_file_extent_item | ||
987 | *e, u64 val) | ||
988 | { | ||
989 | e->disk_num_blocks = cpu_to_le64(val); | ||
990 | } | ||
991 | |||
992 | static inline u64 btrfs_file_extent_offset(struct btrfs_file_extent_item *e) | ||
993 | { | ||
994 | return le64_to_cpu(e->offset); | ||
995 | } | ||
996 | |||
997 | static inline void btrfs_set_file_extent_offset(struct btrfs_file_extent_item | ||
998 | *e, u64 val) | ||
999 | { | ||
1000 | e->offset = cpu_to_le64(val); | ||
1001 | } | ||
1002 | |||
1003 | static inline u64 btrfs_file_extent_num_blocks(struct btrfs_file_extent_item | ||
1004 | *e) | ||
1005 | { | ||
1006 | return le64_to_cpu(e->num_blocks); | ||
1007 | } | ||
1008 | |||
1009 | static inline void btrfs_set_file_extent_num_blocks(struct | ||
1010 | btrfs_file_extent_item *e, | ||
1011 | u64 val) | ||
1012 | { | ||
1013 | e->num_blocks = cpu_to_le64(val); | ||
1014 | } | ||
1015 | 819 | ||
1016 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) | 820 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) |
1017 | { | 821 | { |
1018 | return sb->s_fs_info; | 822 | return sb->s_fs_info; |
1019 | } | 823 | } |
1020 | 824 | ||
1021 | static inline void btrfs_check_bounds(void *vptr, size_t len, | ||
1022 | void *vcontainer, size_t container_len) | ||
1023 | { | ||
1024 | char *ptr = vptr; | ||
1025 | char *container = vcontainer; | ||
1026 | WARN_ON(ptr < container); | ||
1027 | WARN_ON(ptr + len > container + container_len); | ||
1028 | } | ||
1029 | |||
1030 | static inline void btrfs_memcpy(struct btrfs_root *root, | ||
1031 | void *dst_block, | ||
1032 | void *dst, const void *src, size_t nr) | ||
1033 | { | ||
1034 | btrfs_check_bounds(dst, nr, dst_block, root->fs_info->sb->s_blocksize); | ||
1035 | memcpy(dst, src, nr); | ||
1036 | } | ||
1037 | |||
1038 | static inline void btrfs_memmove(struct btrfs_root *root, | ||
1039 | void *dst_block, | ||
1040 | void *dst, void *src, size_t nr) | ||
1041 | { | ||
1042 | btrfs_check_bounds(dst, nr, dst_block, root->fs_info->sb->s_blocksize); | ||
1043 | memmove(dst, src, nr); | ||
1044 | } | ||
1045 | |||
1046 | static inline int btrfs_set_root_name(struct btrfs_root *root, | 825 | static inline int btrfs_set_root_name(struct btrfs_root *root, |
1047 | const char *name, int len) | 826 | const char *name, int len) |
1048 | { | 827 | { |
@@ -1063,7 +842,11 @@ static inline int btrfs_set_root_name(struct btrfs_root *root, | |||
1063 | /* helper function to cast into the data area of the leaf. */ | 842 | /* helper function to cast into the data area of the leaf. */ |
1064 | #define btrfs_item_ptr(leaf, slot, type) \ | 843 | #define btrfs_item_ptr(leaf, slot, type) \ |
1065 | ((type *)(btrfs_leaf_data(leaf) + \ | 844 | ((type *)(btrfs_leaf_data(leaf) + \ |
1066 | btrfs_item_offset((leaf)->items + (slot)))) | 845 | btrfs_item_offset_nr(leaf, slot))) |
846 | |||
847 | #define btrfs_item_ptr_offset(leaf, slot) \ | ||
848 | ((unsigned long)(btrfs_leaf_data(leaf) + \ | ||
849 | btrfs_item_offset_nr(leaf, slot))) | ||
1067 | 850 | ||
1068 | /* mount option defines and helpers */ | 851 | /* mount option defines and helpers */ |
1069 | #define BTRFS_MOUNT_SUBVOL 0x000001 | 852 | #define BTRFS_MOUNT_SUBVOL 0x000001 |
@@ -1084,7 +867,7 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | |||
1084 | int data, int owner); | 867 | int data, int owner); |
1085 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 868 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
1086 | struct btrfs_root *root); | 869 | struct btrfs_root *root); |
1087 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 870 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1088 | struct btrfs_root *root, u64 hint, | 871 | struct btrfs_root *root, u64 hint, |
1089 | u64 empty_size); | 872 | u64 empty_size); |
1090 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 873 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
@@ -1092,7 +875,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1092 | u64 num_blocks, u64 empty_size, u64 search_start, | 875 | u64 num_blocks, u64 empty_size, u64 search_start, |
1093 | u64 search_end, struct btrfs_key *ins, int data); | 876 | u64 search_end, struct btrfs_key *ins, int data); |
1094 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 877 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1095 | struct buffer_head *buf); | 878 | struct extent_buffer *buf); |
1096 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 879 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
1097 | *root, u64 blocknr, u64 num_blocks, int pin); | 880 | *root, u64 blocknr, u64 num_blocks, int pin); |
1098 | int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | 881 | int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, |
@@ -1106,10 +889,10 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
1106 | int btrfs_free_block_groups(struct btrfs_fs_info *info); | 889 | int btrfs_free_block_groups(struct btrfs_fs_info *info); |
1107 | int btrfs_read_block_groups(struct btrfs_root *root); | 890 | int btrfs_read_block_groups(struct btrfs_root *root); |
1108 | /* ctree.c */ | 891 | /* ctree.c */ |
1109 | int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | 892 | int btrfs_cow_block(struct btrfs_trans_handle *trans, |
1110 | *root, struct buffer_head *buf, struct buffer_head | 893 | struct btrfs_root *root, struct extent_buffer *buf, |
1111 | *parent, int parent_slot, struct buffer_head | 894 | struct extent_buffer *parent, int parent_slot, |
1112 | **cow_ret); | 895 | struct extent_buffer **cow_ret); |
1113 | int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root | 896 | int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root |
1114 | *root, struct btrfs_path *path, u32 data_size); | 897 | *root, struct btrfs_path *path, u32 data_size); |
1115 | int btrfs_truncate_item(struct btrfs_trans_handle *trans, | 898 | int btrfs_truncate_item(struct btrfs_trans_handle *trans, |
@@ -1120,7 +903,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1120 | *root, struct btrfs_key *key, struct btrfs_path *p, int | 903 | *root, struct btrfs_key *key, struct btrfs_path *p, int |
1121 | ins_len, int cow); | 904 | ins_len, int cow); |
1122 | int btrfs_realloc_node(struct btrfs_trans_handle *trans, | 905 | int btrfs_realloc_node(struct btrfs_trans_handle *trans, |
1123 | struct btrfs_root *root, struct buffer_head *parent, | 906 | struct btrfs_root *root, struct extent_buffer *parent, |
1124 | int cache_only, u64 *last_ret); | 907 | int cache_only, u64 *last_ret); |
1125 | void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); | 908 | void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); |
1126 | struct btrfs_path *btrfs_alloc_path(void); | 909 | struct btrfs_path *btrfs_alloc_path(void); |
@@ -1134,7 +917,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1134 | *root, struct btrfs_path *path, struct btrfs_key | 917 | *root, struct btrfs_path *path, struct btrfs_key |
1135 | *cpu_key, u32 data_size); | 918 | *cpu_key, u32 data_size); |
1136 | int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); | 919 | int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); |
1137 | int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf); | 920 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); |
1138 | int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | 921 | int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root |
1139 | *root); | 922 | *root); |
1140 | /* root-item.c */ | 923 | /* root-item.c */ |
@@ -1179,9 +962,9 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, | |||
1179 | int btrfs_find_highest_inode(struct btrfs_root *fs_root, u64 *objectid); | 962 | int btrfs_find_highest_inode(struct btrfs_root *fs_root, u64 *objectid); |
1180 | 963 | ||
1181 | /* inode-item.c */ | 964 | /* inode-item.c */ |
1182 | int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root | 965 | int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans, |
1183 | *root, u64 objectid, struct btrfs_inode_item | 966 | struct btrfs_root *root, |
1184 | *inode_item); | 967 | struct btrfs_path *path, u64 objectid); |
1185 | int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root | 968 | int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root |
1186 | *root, struct btrfs_path *path, | 969 | *root, struct btrfs_path *path, |
1187 | struct btrfs_key *location, int mod); | 970 | struct btrfs_key *location, int mod); |
@@ -1224,8 +1007,6 @@ struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, | |||
1224 | struct btrfs_root *root); | 1007 | struct btrfs_root *root); |
1225 | int btrfs_commit_write(struct file *file, struct page *page, | 1008 | int btrfs_commit_write(struct file *file, struct page *page, |
1226 | unsigned from, unsigned to); | 1009 | unsigned from, unsigned to); |
1227 | int btrfs_get_block(struct inode *inode, sector_t iblock, | ||
1228 | struct buffer_head *result, int create); | ||
1229 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | 1010 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, |
1230 | size_t page_offset, u64 start, u64 end, | 1011 | size_t page_offset, u64 start, u64 end, |
1231 | int create); | 1012 | int create); |
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 49db5fa7ced3..6f19de41b878 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c | |||
@@ -33,7 +33,7 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle | |||
33 | int ret; | 33 | int ret; |
34 | char *ptr; | 34 | char *ptr; |
35 | struct btrfs_item *item; | 35 | struct btrfs_item *item; |
36 | struct btrfs_leaf *leaf; | 36 | struct extent_buffer *leaf; |
37 | 37 | ||
38 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); | 38 | ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); |
39 | if (ret == -EEXIST) { | 39 | if (ret == -EEXIST) { |
@@ -49,11 +49,11 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle | |||
49 | if (ret < 0) | 49 | if (ret < 0) |
50 | return ERR_PTR(ret); | 50 | return ERR_PTR(ret); |
51 | WARN_ON(ret > 0); | 51 | WARN_ON(ret > 0); |
52 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 52 | leaf = path->nodes[0]; |
53 | item = leaf->items + path->slots[0]; | 53 | item = btrfs_item_nr(leaf, path->slots[0]); |
54 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); | 54 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); |
55 | BUG_ON(data_size > btrfs_item_size(item)); | 55 | BUG_ON(data_size > btrfs_item_size(leaf, item)); |
56 | ptr += btrfs_item_size(item) - data_size; | 56 | ptr += btrfs_item_size(leaf, item) - data_size; |
57 | return (struct btrfs_dir_item *)ptr; | 57 | return (struct btrfs_dir_item *)ptr; |
58 | } | 58 | } |
59 | 59 | ||
@@ -65,12 +65,13 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
65 | int ret2 = 0; | 65 | int ret2 = 0; |
66 | struct btrfs_path *path; | 66 | struct btrfs_path *path; |
67 | struct btrfs_dir_item *dir_item; | 67 | struct btrfs_dir_item *dir_item; |
68 | char *name_ptr; | 68 | struct extent_buffer *leaf; |
69 | unsigned long name_ptr; | ||
69 | struct btrfs_key key; | 70 | struct btrfs_key key; |
71 | struct btrfs_disk_key disk_key; | ||
70 | u32 data_size; | 72 | u32 data_size; |
71 | 73 | ||
72 | key.objectid = dir; | 74 | key.objectid = dir; |
73 | key.flags = 0; | ||
74 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 75 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
75 | ret = btrfs_name_hash(name, name_len, &key.offset); | 76 | ret = btrfs_name_hash(name, name_len, &key.offset); |
76 | BUG_ON(ret); | 77 | BUG_ON(ret); |
@@ -85,14 +86,16 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
85 | goto out; | 86 | goto out; |
86 | } | 87 | } |
87 | 88 | ||
88 | btrfs_cpu_key_to_disk(&dir_item->location, location); | 89 | leaf = path->nodes[0]; |
89 | btrfs_set_dir_type(dir_item, type); | 90 | btrfs_cpu_key_to_disk(&disk_key, location); |
90 | btrfs_set_dir_flags(dir_item, 0); | 91 | btrfs_set_dir_item_key(leaf, dir_item, &disk_key); |
91 | btrfs_set_dir_name_len(dir_item, name_len); | 92 | btrfs_set_dir_type(leaf, dir_item, type); |
92 | name_ptr = (char *)(dir_item + 1); | 93 | btrfs_set_dir_flags(leaf, dir_item, 0); |
94 | btrfs_set_dir_name_len(leaf, dir_item, name_len); | ||
95 | name_ptr = (unsigned long)(dir_item + 1); | ||
93 | 96 | ||
94 | btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); | 97 | write_extent_buffer(leaf, name, name_ptr, name_len); |
95 | btrfs_mark_buffer_dirty(path->nodes[0]); | 98 | btrfs_mark_buffer_dirty(leaf); |
96 | 99 | ||
97 | second_insert: | 100 | second_insert: |
98 | /* FIXME, use some real flag for selecting the extra index */ | 101 | /* FIXME, use some real flag for selecting the extra index */ |
@@ -110,13 +113,15 @@ second_insert: | |||
110 | ret2 = PTR_ERR(dir_item); | 113 | ret2 = PTR_ERR(dir_item); |
111 | goto out; | 114 | goto out; |
112 | } | 115 | } |
113 | btrfs_cpu_key_to_disk(&dir_item->location, location); | 116 | leaf = path->nodes[0]; |
114 | btrfs_set_dir_type(dir_item, type); | 117 | btrfs_cpu_key_to_disk(&disk_key, location); |
115 | btrfs_set_dir_flags(dir_item, 0); | 118 | btrfs_set_dir_item_key(leaf, dir_item, &disk_key); |
116 | btrfs_set_dir_name_len(dir_item, name_len); | 119 | btrfs_set_dir_type(leaf, dir_item, type); |
117 | name_ptr = (char *)(dir_item + 1); | 120 | btrfs_set_dir_flags(leaf, dir_item, 0); |
118 | btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); | 121 | btrfs_set_dir_name_len(leaf, dir_item, name_len); |
119 | btrfs_mark_buffer_dirty(path->nodes[0]); | 122 | name_ptr = (unsigned long)(dir_item + 1); |
123 | write_extent_buffer(leaf, name, name_ptr, name_len); | ||
124 | btrfs_mark_buffer_dirty(leaf); | ||
120 | out: | 125 | out: |
121 | btrfs_free_path(path); | 126 | btrfs_free_path(path); |
122 | if (ret) | 127 | if (ret) |
@@ -136,14 +141,15 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, | |||
136 | struct btrfs_key key; | 141 | struct btrfs_key key; |
137 | int ins_len = mod < 0 ? -1 : 0; | 142 | int ins_len = mod < 0 ? -1 : 0; |
138 | int cow = mod != 0; | 143 | int cow = mod != 0; |
139 | struct btrfs_disk_key *found_key; | 144 | struct btrfs_key found_key; |
140 | struct btrfs_leaf *leaf; | 145 | struct extent_buffer *leaf; |
141 | 146 | ||
142 | key.objectid = dir; | 147 | key.objectid = dir; |
143 | key.flags = 0; | ||
144 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 148 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
149 | |||
145 | ret = btrfs_name_hash(name, name_len, &key.offset); | 150 | ret = btrfs_name_hash(name, name_len, &key.offset); |
146 | BUG_ON(ret); | 151 | BUG_ON(ret); |
152 | |||
147 | ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); | 153 | ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); |
148 | if (ret < 0) | 154 | if (ret < 0) |
149 | return ERR_PTR(ret); | 155 | return ERR_PTR(ret); |
@@ -152,12 +158,13 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, | |||
152 | return NULL; | 158 | return NULL; |
153 | path->slots[0]--; | 159 | path->slots[0]--; |
154 | } | 160 | } |
155 | leaf = btrfs_buffer_leaf(path->nodes[0]); | ||
156 | found_key = &leaf->items[path->slots[0]].key; | ||
157 | 161 | ||
158 | if (btrfs_disk_key_objectid(found_key) != dir || | 162 | leaf = path->nodes[0]; |
159 | btrfs_disk_key_type(found_key) != BTRFS_DIR_ITEM_KEY || | 163 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
160 | btrfs_disk_key_offset(found_key) != key.offset) | 164 | |
165 | if (found_key.objectid != dir || | ||
166 | btrfs_key_type(&found_key) != BTRFS_DIR_ITEM_KEY || | ||
167 | found_key.offset != key.offset) | ||
161 | return NULL; | 168 | return NULL; |
162 | 169 | ||
163 | return btrfs_match_dir_item_name(root, path, name, name_len); | 170 | return btrfs_match_dir_item_name(root, path, name, name_len); |
@@ -176,7 +183,6 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, | |||
176 | int cow = mod != 0; | 183 | int cow = mod != 0; |
177 | 184 | ||
178 | key.objectid = dir; | 185 | key.objectid = dir; |
179 | key.flags = 0; | ||
180 | btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY); | 186 | btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY); |
181 | key.offset = objectid; | 187 | key.offset = objectid; |
182 | 188 | ||
@@ -193,21 +199,22 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, | |||
193 | const char *name, int name_len) | 199 | const char *name, int name_len) |
194 | { | 200 | { |
195 | struct btrfs_dir_item *dir_item; | 201 | struct btrfs_dir_item *dir_item; |
196 | char *name_ptr; | 202 | unsigned long name_ptr; |
197 | u32 total_len; | 203 | u32 total_len; |
198 | u32 cur = 0; | 204 | u32 cur = 0; |
199 | u32 this_len; | 205 | u32 this_len; |
200 | struct btrfs_leaf *leaf; | 206 | struct extent_buffer *leaf; |
201 | 207 | ||
202 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 208 | leaf = path->nodes[0]; |
203 | dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); | 209 | dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); |
204 | total_len = btrfs_item_size(leaf->items + path->slots[0]); | 210 | total_len = btrfs_item_size_nr(leaf, path->slots[0]); |
205 | while(cur < total_len) { | 211 | while(cur < total_len) { |
206 | this_len = sizeof(*dir_item) + btrfs_dir_name_len(dir_item); | 212 | this_len = sizeof(*dir_item) + |
207 | name_ptr = (char *)(dir_item + 1); | 213 | btrfs_dir_name_len(leaf, dir_item); |
214 | name_ptr = (unsigned long)(dir_item + 1); | ||
208 | 215 | ||
209 | if (btrfs_dir_name_len(dir_item) == name_len && | 216 | if (btrfs_dir_name_len(leaf, dir_item) == name_len && |
210 | memcmp(name_ptr, name, name_len) == 0) | 217 | memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) |
211 | return dir_item; | 218 | return dir_item; |
212 | 219 | ||
213 | cur += this_len; | 220 | cur += this_len; |
@@ -223,20 +230,23 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, | |||
223 | struct btrfs_dir_item *di) | 230 | struct btrfs_dir_item *di) |
224 | { | 231 | { |
225 | 232 | ||
226 | struct btrfs_leaf *leaf; | 233 | struct extent_buffer *leaf; |
227 | u32 sub_item_len; | 234 | u32 sub_item_len; |
228 | u32 item_len; | 235 | u32 item_len; |
229 | int ret = 0; | 236 | int ret = 0; |
230 | 237 | ||
231 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 238 | leaf = path->nodes[0]; |
232 | sub_item_len = sizeof(*di) + btrfs_dir_name_len(di); | 239 | sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di); |
233 | item_len = btrfs_item_size(leaf->items + path->slots[0]); | 240 | item_len = btrfs_item_size_nr(leaf, path->slots[0]); |
234 | if (sub_item_len == btrfs_item_size(leaf->items + path->slots[0])) { | 241 | if (sub_item_len == item_len) { |
235 | ret = btrfs_del_item(trans, root, path); | 242 | ret = btrfs_del_item(trans, root, path); |
236 | } else { | 243 | } else { |
237 | char *ptr = (char *)di; | 244 | /* MARKER */ |
238 | char *start = btrfs_item_ptr(leaf, path->slots[0], char); | 245 | unsigned long ptr = (unsigned long)di; |
239 | btrfs_memmove(root, leaf, ptr, ptr + sub_item_len, | 246 | unsigned long start; |
247 | |||
248 | start = btrfs_item_ptr_offset(leaf, path->slots[0]); | ||
249 | memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, | ||
240 | item_len - (ptr + sub_item_len - start)); | 250 | item_len - (ptr + sub_item_len - start)); |
241 | ret = btrfs_truncate_item(trans, root, path, | 251 | ret = btrfs_truncate_item(trans, root, path, |
242 | item_len - sub_item_len); | 252 | item_len - sub_item_len); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ef6d76f2ec20..0c1f90cbedb0 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -23,138 +23,132 @@ | |||
23 | #include <linux/swap.h> | 23 | #include <linux/swap.h> |
24 | #include <linux/radix-tree.h> | 24 | #include <linux/radix-tree.h> |
25 | #include <linux/writeback.h> | 25 | #include <linux/writeback.h> |
26 | #include <linux/buffer_head.h> // for block_sync_page | ||
26 | #include "ctree.h" | 27 | #include "ctree.h" |
27 | #include "disk-io.h" | 28 | #include "disk-io.h" |
28 | #include "transaction.h" | 29 | #include "transaction.h" |
29 | #include "btrfs_inode.h" | 30 | #include "btrfs_inode.h" |
30 | 31 | ||
31 | u64 bh_blocknr(struct buffer_head *bh) | 32 | #if 0 |
33 | static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) | ||
32 | { | 34 | { |
33 | return bh->b_blocknr; | 35 | if (extent_buffer_blocknr(buf) != btrfs_header_blocknr(buf)) { |
34 | } | 36 | printk(KERN_CRIT "buf blocknr(buf) is %llu, header is %llu\n", |
35 | 37 | (unsigned long long)extent_buffer_blocknr(buf), | |
36 | static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf) | 38 | (unsigned long long)btrfs_header_blocknr(buf)); |
37 | { | ||
38 | struct btrfs_node *node = btrfs_buffer_node(buf); | ||
39 | if (bh_blocknr(buf) != btrfs_header_blocknr(&node->header)) { | ||
40 | printk(KERN_CRIT "bh_blocknr(buf) is %llu, header is %llu\n", | ||
41 | (unsigned long long)bh_blocknr(buf), | ||
42 | (unsigned long long)btrfs_header_blocknr(&node->header)); | ||
43 | return 1; | 39 | return 1; |
44 | } | 40 | } |
45 | return 0; | 41 | return 0; |
46 | } | 42 | } |
43 | #endif | ||
47 | 44 | ||
48 | struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr) | 45 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
46 | u64 blocknr) | ||
49 | { | 47 | { |
50 | struct address_space *mapping = root->fs_info->btree_inode->i_mapping; | 48 | struct inode *btree_inode = root->fs_info->btree_inode; |
51 | int blockbits = root->fs_info->sb->s_blocksize_bits; | 49 | return find_extent_buffer(&BTRFS_I(btree_inode)->extent_tree, |
52 | unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits); | 50 | blocknr * root->sectorsize, |
53 | struct page *page; | 51 | root->sectorsize, GFP_NOFS); |
54 | struct buffer_head *bh; | 52 | } |
55 | struct buffer_head *head; | ||
56 | struct buffer_head *ret = NULL; | ||
57 | |||
58 | |||
59 | page = find_lock_page(mapping, index); | ||
60 | if (!page) | ||
61 | return NULL; | ||
62 | |||
63 | if (!page_has_buffers(page)) | ||
64 | goto out_unlock; | ||
65 | 53 | ||
66 | head = page_buffers(page); | 54 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, |
67 | bh = head; | 55 | u64 blocknr) |
68 | do { | 56 | { |
69 | if (buffer_mapped(bh) && bh_blocknr(bh) == blocknr) { | 57 | struct inode *btree_inode = root->fs_info->btree_inode; |
70 | ret = bh; | 58 | return alloc_extent_buffer(&BTRFS_I(btree_inode)->extent_tree, |
71 | get_bh(bh); | 59 | blocknr * root->sectorsize, |
72 | goto out_unlock; | 60 | root->sectorsize, GFP_NOFS); |
73 | } | ||
74 | bh = bh->b_this_page; | ||
75 | } while (bh != head); | ||
76 | out_unlock: | ||
77 | unlock_page(page); | ||
78 | page_cache_release(page); | ||
79 | return ret; | ||
80 | } | 61 | } |
81 | 62 | ||
82 | int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh, | 63 | struct extent_map *btree_get_extent(struct inode *inode, struct page *page, |
83 | u64 logical) | 64 | size_t page_offset, u64 start, u64 end, |
65 | int create) | ||
84 | { | 66 | { |
85 | if (logical == 0) { | 67 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
86 | bh->b_bdev = NULL; | 68 | struct extent_map *em; |
87 | bh->b_blocknr = 0; | 69 | int ret; |
88 | set_buffer_mapped(bh); | 70 | |
89 | } else { | 71 | again: |
90 | map_bh(bh, root->fs_info->sb, logical); | 72 | em = lookup_extent_mapping(em_tree, start, end); |
73 | if (em) { | ||
74 | goto out; | ||
91 | } | 75 | } |
92 | return 0; | 76 | em = alloc_extent_map(GFP_NOFS); |
77 | if (!em) { | ||
78 | em = ERR_PTR(-ENOMEM); | ||
79 | goto out; | ||
80 | } | ||
81 | em->start = 0; | ||
82 | em->end = (i_size_read(inode) & ~((u64)PAGE_CACHE_SIZE -1)) - 1; | ||
83 | em->block_start = 0; | ||
84 | em->block_end = em->end; | ||
85 | em->bdev = inode->i_sb->s_bdev; | ||
86 | ret = add_extent_mapping(em_tree, em); | ||
87 | if (ret == -EEXIST) { | ||
88 | free_extent_map(em); | ||
89 | em = NULL; | ||
90 | goto again; | ||
91 | } else if (ret) { | ||
92 | em = ERR_PTR(ret); | ||
93 | } | ||
94 | out: | ||
95 | return em; | ||
93 | } | 96 | } |
94 | 97 | ||
95 | struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root, | 98 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
96 | u64 blocknr) | ||
97 | { | 99 | { |
98 | struct address_space *mapping = root->fs_info->btree_inode->i_mapping; | 100 | struct extent_map_tree *tree; |
99 | int blockbits = root->fs_info->sb->s_blocksize_bits; | 101 | tree = &BTRFS_I(page->mapping->host)->extent_tree; |
100 | unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits); | 102 | return extent_write_full_page(tree, page, btree_get_extent, wbc); |
101 | struct page *page; | 103 | } |
102 | struct buffer_head *bh; | 104 | int btree_readpage(struct file *file, struct page *page) |
103 | struct buffer_head *head; | 105 | { |
104 | struct buffer_head *ret = NULL; | 106 | struct extent_map_tree *tree; |
105 | int err; | 107 | tree = &BTRFS_I(page->mapping->host)->extent_tree; |
106 | u64 first_block = index << (PAGE_CACHE_SHIFT - blockbits); | 108 | return extent_read_full_page(tree, page, btree_get_extent); |
109 | } | ||
107 | 110 | ||
108 | page = find_or_create_page(mapping, index, GFP_NOFS); | 111 | static int btree_releasepage(struct page *page, gfp_t unused_gfp_flags) |
109 | if (!page) | 112 | { |
110 | return NULL; | 113 | struct extent_map_tree *tree; |
114 | int ret; | ||
111 | 115 | ||
112 | if (!page_has_buffers(page)) | 116 | BUG_ON(page->private != 1); |
113 | create_empty_buffers(page, root->fs_info->sb->s_blocksize, 0); | 117 | tree = &BTRFS_I(page->mapping->host)->extent_tree; |
114 | head = page_buffers(page); | 118 | ret = try_release_extent_mapping(tree, page); |
115 | bh = head; | 119 | if (ret == 1) { |
116 | do { | 120 | ClearPagePrivate(page); |
117 | if (!buffer_mapped(bh)) { | 121 | set_page_private(page, 0); |
118 | err = btrfs_map_bh_to_logical(root, bh, first_block); | 122 | page_cache_release(page); |
119 | BUG_ON(err); | 123 | } |
120 | } | ||
121 | if (bh_blocknr(bh) == blocknr) { | ||
122 | ret = bh; | ||
123 | get_bh(bh); | ||
124 | goto out_unlock; | ||
125 | } | ||
126 | bh = bh->b_this_page; | ||
127 | first_block++; | ||
128 | } while (bh != head); | ||
129 | out_unlock: | ||
130 | unlock_page(page); | ||
131 | if (ret) | ||
132 | touch_buffer(ret); | ||
133 | page_cache_release(page); | ||
134 | return ret; | 124 | return ret; |
135 | } | 125 | } |
136 | 126 | ||
137 | static int btree_get_block(struct inode *inode, sector_t iblock, | 127 | static void btree_invalidatepage(struct page *page, unsigned long offset) |
138 | struct buffer_head *bh, int create) | ||
139 | { | 128 | { |
140 | int err; | 129 | struct extent_map_tree *tree; |
141 | struct btrfs_root *root = BTRFS_I(bh->b_page->mapping->host)->root; | 130 | tree = &BTRFS_I(page->mapping->host)->extent_tree; |
142 | err = btrfs_map_bh_to_logical(root, bh, iblock); | 131 | extent_invalidatepage(tree, page, offset); |
143 | return err; | 132 | btree_releasepage(page, GFP_NOFS); |
144 | } | 133 | } |
145 | 134 | ||
146 | int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len, | 135 | int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len, |
147 | char *result) | 136 | char *result) |
148 | { | 137 | { |
138 | return 0; | ||
139 | #if 0 | ||
149 | u32 crc; | 140 | u32 crc; |
150 | crc = crc32c(0, data, len); | 141 | crc = crc32c(0, data, len); |
151 | memcpy(result, &crc, BTRFS_CRC32_SIZE); | 142 | memcpy(result, &crc, BTRFS_CRC32_SIZE); |
152 | return 0; | 143 | return 0; |
144 | #endif | ||
153 | } | 145 | } |
154 | 146 | ||
155 | static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh, | 147 | #if 0 |
148 | static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, | ||
156 | int verify) | 149 | int verify) |
157 | { | 150 | { |
151 | return 0; | ||
158 | char result[BTRFS_CRC32_SIZE]; | 152 | char result[BTRFS_CRC32_SIZE]; |
159 | int ret; | 153 | int ret; |
160 | struct btrfs_node *node; | 154 | struct btrfs_node *node; |
@@ -176,7 +170,9 @@ static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh, | |||
176 | } | 170 | } |
177 | return 0; | 171 | return 0; |
178 | } | 172 | } |
173 | #endif | ||
179 | 174 | ||
175 | #if 0 | ||
180 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 176 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
181 | { | 177 | { |
182 | struct buffer_head *bh; | 178 | struct buffer_head *bh; |
@@ -195,87 +191,65 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc) | |||
195 | } while (bh != head); | 191 | } while (bh != head); |
196 | return block_write_full_page(page, btree_get_block, wbc); | 192 | return block_write_full_page(page, btree_get_block, wbc); |
197 | } | 193 | } |
198 | 194 | #endif | |
199 | static int btree_readpage(struct file * file, struct page * page) | ||
200 | { | ||
201 | return block_read_full_page(page, btree_get_block); | ||
202 | } | ||
203 | 195 | ||
204 | static struct address_space_operations btree_aops = { | 196 | static struct address_space_operations btree_aops = { |
205 | .readpage = btree_readpage, | 197 | .readpage = btree_readpage, |
206 | .writepage = btree_writepage, | 198 | .writepage = btree_writepage, |
199 | .releasepage = btree_releasepage, | ||
200 | .invalidatepage = btree_invalidatepage, | ||
207 | .sync_page = block_sync_page, | 201 | .sync_page = block_sync_page, |
208 | }; | 202 | }; |
209 | 203 | ||
210 | int readahead_tree_block(struct btrfs_root *root, u64 blocknr) | 204 | int readahead_tree_block(struct btrfs_root *root, u64 blocknr) |
211 | { | 205 | { |
212 | struct buffer_head *bh = NULL; | 206 | struct extent_buffer *buf = NULL; |
207 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
213 | int ret = 0; | 208 | int ret = 0; |
214 | 209 | ||
215 | bh = btrfs_find_create_tree_block(root, blocknr); | 210 | buf = btrfs_find_create_tree_block(root, blocknr); |
216 | if (!bh) | 211 | if (!buf) |
217 | return 0; | 212 | return 0; |
218 | if (buffer_uptodate(bh)) { | 213 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree, |
219 | ret = 1; | 214 | buf, 0); |
220 | goto done; | 215 | free_extent_buffer(buf); |
221 | } | ||
222 | if (test_set_buffer_locked(bh)) { | ||
223 | ret = 1; | ||
224 | goto done; | ||
225 | } | ||
226 | if (!buffer_uptodate(bh)) { | ||
227 | get_bh(bh); | ||
228 | bh->b_end_io = end_buffer_read_sync; | ||
229 | submit_bh(READ, bh); | ||
230 | } else { | ||
231 | unlock_buffer(bh); | ||
232 | ret = 1; | ||
233 | } | ||
234 | done: | ||
235 | brelse(bh); | ||
236 | return ret; | 216 | return ret; |
237 | } | 217 | } |
238 | 218 | ||
239 | struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr) | 219 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr) |
240 | { | 220 | { |
241 | struct buffer_head *bh = NULL; | 221 | struct extent_buffer *buf = NULL; |
242 | 222 | struct inode *btree_inode = root->fs_info->btree_inode; | |
243 | bh = btrfs_find_create_tree_block(root, blocknr); | 223 | |
244 | if (!bh) | 224 | buf = btrfs_find_create_tree_block(root, blocknr); |
245 | return bh; | 225 | if (!buf) |
246 | if (buffer_uptodate(bh)) | 226 | return NULL; |
247 | goto uptodate; | 227 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree, |
248 | lock_buffer(bh); | 228 | buf, 1); |
249 | if (!buffer_uptodate(bh)) { | 229 | return buf; |
250 | get_bh(bh); | ||
251 | bh->b_end_io = end_buffer_read_sync; | ||
252 | submit_bh(READ, bh); | ||
253 | wait_on_buffer(bh); | ||
254 | if (!buffer_uptodate(bh)) | ||
255 | goto fail; | ||
256 | } else { | ||
257 | unlock_buffer(bh); | ||
258 | } | ||
259 | uptodate: | ||
260 | if (!buffer_checked(bh)) { | ||
261 | csum_tree_block(root, bh, 1); | ||
262 | set_buffer_checked(bh); | ||
263 | } | ||
264 | if (check_tree_block(root, bh)) | ||
265 | goto fail; | ||
266 | return bh; | ||
267 | fail: | ||
268 | brelse(bh); | ||
269 | return NULL; | ||
270 | } | 230 | } |
271 | 231 | ||
272 | int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 232 | int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
273 | struct buffer_head *buf) | 233 | struct extent_buffer *buf) |
274 | { | 234 | { |
275 | WARN_ON(atomic_read(&buf->b_count) == 0); | 235 | struct inode *btree_inode = root->fs_info->btree_inode; |
276 | lock_buffer(buf); | 236 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); |
277 | clear_buffer_dirty(buf); | 237 | return 0; |
278 | unlock_buffer(buf); | 238 | } |
239 | |||
240 | int wait_on_tree_block_writeback(struct btrfs_root *root, | ||
241 | struct extent_buffer *buf) | ||
242 | { | ||
243 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
244 | wait_on_extent_buffer_writeback(&BTRFS_I(btree_inode)->extent_tree, | ||
245 | buf); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | int set_tree_block_dirty(struct btrfs_root *root, struct extent_buffer *buf) | ||
250 | { | ||
251 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
252 | set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); | ||
279 | return 0; | 253 | return 0; |
280 | } | 254 | } |
281 | 255 | ||
@@ -287,7 +261,9 @@ static int __setup_root(int blocksize, | |||
287 | root->node = NULL; | 261 | root->node = NULL; |
288 | root->inode = NULL; | 262 | root->inode = NULL; |
289 | root->commit_root = NULL; | 263 | root->commit_root = NULL; |
290 | root->blocksize = blocksize; | 264 | root->sectorsize = blocksize; |
265 | root->nodesize = blocksize; | ||
266 | root->leafsize = blocksize; | ||
291 | root->ref_cows = 0; | 267 | root->ref_cows = 0; |
292 | root->fs_info = fs_info; | 268 | root->fs_info = fs_info; |
293 | root->objectid = objectid; | 269 | root->objectid = objectid; |
@@ -332,7 +308,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info, | |||
332 | struct btrfs_root *root; | 308 | struct btrfs_root *root; |
333 | struct btrfs_root *tree_root = fs_info->tree_root; | 309 | struct btrfs_root *tree_root = fs_info->tree_root; |
334 | struct btrfs_path *path; | 310 | struct btrfs_path *path; |
335 | struct btrfs_leaf *l; | 311 | struct extent_buffer *l; |
336 | u64 highest_inode; | 312 | u64 highest_inode; |
337 | int ret = 0; | 313 | int ret = 0; |
338 | 314 | ||
@@ -361,11 +337,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info, | |||
361 | ret = -ENOENT; | 337 | ret = -ENOENT; |
362 | goto out; | 338 | goto out; |
363 | } | 339 | } |
364 | l = btrfs_buffer_leaf(path->nodes[0]); | 340 | l = path->nodes[0]; |
365 | memcpy(&root->root_item, | 341 | read_extent_buffer(l, &root->root_item, |
366 | btrfs_item_ptr(l, path->slots[0], struct btrfs_root_item), | 342 | btrfs_item_ptr_offset(l, path->slots[0]), |
367 | sizeof(root->root_item)); | 343 | sizeof(root->root_item)); |
368 | memcpy(&root->root_key, location, sizeof(*location)); | ||
369 | ret = 0; | 344 | ret = 0; |
370 | out: | 345 | out: |
371 | btrfs_release_path(root, path); | 346 | btrfs_release_path(root, path); |
@@ -406,21 +381,21 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | |||
406 | (unsigned long)root->root_key.objectid, | 381 | (unsigned long)root->root_key.objectid, |
407 | root); | 382 | root); |
408 | if (ret) { | 383 | if (ret) { |
409 | brelse(root->node); | 384 | free_extent_buffer(root->node); |
410 | kfree(root); | 385 | kfree(root); |
411 | return ERR_PTR(ret); | 386 | return ERR_PTR(ret); |
412 | } | 387 | } |
413 | 388 | ||
414 | ret = btrfs_set_root_name(root, name, namelen); | 389 | ret = btrfs_set_root_name(root, name, namelen); |
415 | if (ret) { | 390 | if (ret) { |
416 | brelse(root->node); | 391 | free_extent_buffer(root->node); |
417 | kfree(root); | 392 | kfree(root); |
418 | return ERR_PTR(ret); | 393 | return ERR_PTR(ret); |
419 | } | 394 | } |
420 | 395 | ||
421 | ret = btrfs_sysfs_add_root(root); | 396 | ret = btrfs_sysfs_add_root(root); |
422 | if (ret) { | 397 | if (ret) { |
423 | brelse(root->node); | 398 | free_extent_buffer(root->node); |
424 | kfree(root->name); | 399 | kfree(root->name); |
425 | kfree(root); | 400 | kfree(root); |
426 | return ERR_PTR(ret); | 401 | return ERR_PTR(ret); |
@@ -471,6 +446,9 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
471 | fs_info->btree_inode->i_nlink = 1; | 446 | fs_info->btree_inode->i_nlink = 1; |
472 | fs_info->btree_inode->i_size = sb->s_bdev->bd_inode->i_size; | 447 | fs_info->btree_inode->i_size = sb->s_bdev->bd_inode->i_size; |
473 | fs_info->btree_inode->i_mapping->a_ops = &btree_aops; | 448 | fs_info->btree_inode->i_mapping->a_ops = &btree_aops; |
449 | extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree, | ||
450 | fs_info->btree_inode->i_mapping, | ||
451 | GFP_NOFS); | ||
474 | fs_info->do_barriers = 1; | 452 | fs_info->do_barriers = 1; |
475 | fs_info->closing = 0; | 453 | fs_info->closing = 0; |
476 | 454 | ||
@@ -493,10 +471,14 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
493 | 471 | ||
494 | if (!fs_info->sb_buffer) | 472 | if (!fs_info->sb_buffer) |
495 | goto fail_iput; | 473 | goto fail_iput; |
496 | disk_super = (struct btrfs_super_block *)fs_info->sb_buffer->b_data; | ||
497 | fs_info->disk_super = disk_super; | ||
498 | memcpy(&fs_info->super_copy, disk_super, sizeof(fs_info->super_copy)); | ||
499 | 474 | ||
475 | read_extent_buffer(fs_info->sb_buffer, &fs_info->super_copy, 0, | ||
476 | sizeof(fs_info->super_copy)); | ||
477 | |||
478 | read_extent_buffer(fs_info->sb_buffer, fs_info->fsid, | ||
479 | (unsigned long)btrfs_super_fsid(fs_info->sb_buffer), | ||
480 | BTRFS_FSID_SIZE); | ||
481 | disk_super = &fs_info->super_copy; | ||
500 | if (!btrfs_super_root(disk_super)) | 482 | if (!btrfs_super_root(disk_super)) |
501 | goto fail_sb_buffer; | 483 | goto fail_sb_buffer; |
502 | 484 | ||
@@ -530,9 +512,9 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
530 | return tree_root; | 512 | return tree_root; |
531 | 513 | ||
532 | fail_tree_root: | 514 | fail_tree_root: |
533 | btrfs_block_release(tree_root, tree_root->node); | 515 | free_extent_buffer(tree_root->node); |
534 | fail_sb_buffer: | 516 | fail_sb_buffer: |
535 | btrfs_block_release(tree_root, fs_info->sb_buffer); | 517 | free_extent_buffer(fs_info->sb_buffer); |
536 | fail_iput: | 518 | fail_iput: |
537 | iput(fs_info->btree_inode); | 519 | iput(fs_info->btree_inode); |
538 | fail: | 520 | fail: |
@@ -546,31 +528,13 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root | |||
546 | *root) | 528 | *root) |
547 | { | 529 | { |
548 | int ret; | 530 | int ret; |
549 | struct buffer_head *bh = root->fs_info->sb_buffer; | 531 | struct extent_buffer *super = root->fs_info->sb_buffer; |
550 | 532 | struct inode *btree_inode = root->fs_info->btree_inode; | |
551 | lock_buffer(bh); | 533 | |
552 | WARN_ON(atomic_read(&bh->b_count) < 1); | 534 | set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, super); |
553 | clear_buffer_dirty(bh); | 535 | ret = sync_page_range_nolock(btree_inode, btree_inode->i_mapping, |
554 | csum_tree_block(root, bh, 0); | 536 | super->start, super->len); |
555 | bh->b_end_io = end_buffer_write_sync; | 537 | return ret; |
556 | get_bh(bh); | ||
557 | if (root->fs_info->do_barriers) | ||
558 | ret = submit_bh(WRITE_BARRIER, bh); | ||
559 | else | ||
560 | ret = submit_bh(WRITE, bh); | ||
561 | if (ret == -EOPNOTSUPP) { | ||
562 | get_bh(bh); | ||
563 | lock_buffer(bh); | ||
564 | set_buffer_uptodate(bh); | ||
565 | root->fs_info->do_barriers = 0; | ||
566 | ret = submit_bh(WRITE, bh); | ||
567 | } | ||
568 | wait_on_buffer(bh); | ||
569 | if (!buffer_uptodate(bh)) { | ||
570 | WARN_ON(1); | ||
571 | return -EIO; | ||
572 | } | ||
573 | return 0; | ||
574 | } | 538 | } |
575 | 539 | ||
576 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | 540 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) |
@@ -581,9 +545,9 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | |||
581 | if (root->inode) | 545 | if (root->inode) |
582 | iput(root->inode); | 546 | iput(root->inode); |
583 | if (root->node) | 547 | if (root->node) |
584 | brelse(root->node); | 548 | free_extent_buffer(root->node); |
585 | if (root->commit_root) | 549 | if (root->commit_root) |
586 | brelse(root->commit_root); | 550 | free_extent_buffer(root->commit_root); |
587 | if (root->name) | 551 | if (root->name) |
588 | kfree(root->name); | 552 | kfree(root->name); |
589 | kfree(root); | 553 | kfree(root); |
@@ -629,12 +593,10 @@ int close_ctree(struct btrfs_root *root) | |||
629 | mutex_unlock(&fs_info->fs_mutex); | 593 | mutex_unlock(&fs_info->fs_mutex); |
630 | 594 | ||
631 | if (fs_info->extent_root->node) | 595 | if (fs_info->extent_root->node) |
632 | btrfs_block_release(fs_info->extent_root, | 596 | free_extent_buffer(fs_info->extent_root->node); |
633 | fs_info->extent_root->node); | ||
634 | if (fs_info->tree_root->node) | 597 | if (fs_info->tree_root->node) |
635 | btrfs_block_release(fs_info->tree_root, | 598 | free_extent_buffer(fs_info->tree_root->node); |
636 | fs_info->tree_root->node); | 599 | free_extent_buffer(fs_info->sb_buffer); |
637 | btrfs_block_release(root, fs_info->sb_buffer); | ||
638 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); | 600 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); |
639 | iput(fs_info->btree_inode); | 601 | iput(fs_info->btree_inode); |
640 | 602 | ||
@@ -645,25 +607,32 @@ int close_ctree(struct btrfs_root *root) | |||
645 | return 0; | 607 | return 0; |
646 | } | 608 | } |
647 | 609 | ||
648 | void btrfs_mark_buffer_dirty(struct buffer_head *bh) | 610 | int btrfs_buffer_uptodate(struct extent_buffer *buf) |
611 | { | ||
612 | struct inode *btree_inode = buf->pages[0]->mapping->host; | ||
613 | return extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, buf); | ||
614 | } | ||
615 | |||
616 | int btrfs_set_buffer_uptodate(struct extent_buffer *buf) | ||
649 | { | 617 | { |
650 | struct btrfs_root *root = BTRFS_I(bh->b_page->mapping->host)->root; | 618 | struct inode *btree_inode = buf->pages[0]->mapping->host; |
651 | u64 transid = btrfs_header_generation(btrfs_buffer_header(bh)); | 619 | return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, |
620 | buf); | ||
621 | } | ||
652 | 622 | ||
653 | WARN_ON(!atomic_read(&bh->b_count)); | 623 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) |
624 | { | ||
625 | struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; | ||
626 | u64 transid = btrfs_header_generation(buf); | ||
627 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
654 | 628 | ||
655 | if (transid != root->fs_info->generation) { | 629 | if (transid != root->fs_info->generation) { |
656 | printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", | 630 | printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", |
657 | (unsigned long long)bh->b_blocknr, | 631 | (unsigned long long)extent_buffer_blocknr(buf), |
658 | transid, root->fs_info->generation); | 632 | transid, root->fs_info->generation); |
659 | WARN_ON(1); | 633 | WARN_ON(1); |
660 | } | 634 | } |
661 | mark_buffer_dirty(bh); | 635 | set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); |
662 | } | ||
663 | |||
664 | void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf) | ||
665 | { | ||
666 | brelse(buf); | ||
667 | } | 636 | } |
668 | 637 | ||
669 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | 638 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index fc6b520c6e0b..70d9413c599f 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -19,68 +19,35 @@ | |||
19 | #ifndef __DISKIO__ | 19 | #ifndef __DISKIO__ |
20 | #define __DISKIO__ | 20 | #define __DISKIO__ |
21 | 21 | ||
22 | #include <linux/buffer_head.h> | ||
23 | |||
24 | #define BTRFS_SUPER_INFO_OFFSET (16 * 1024) | 22 | #define BTRFS_SUPER_INFO_OFFSET (16 * 1024) |
25 | 23 | ||
26 | enum btrfs_bh_state_bits { | 24 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr); |
27 | BH_Checked = BH_PrivateStart, | ||
28 | BH_Defrag, | ||
29 | BH_DefragDone, | ||
30 | }; | ||
31 | BUFFER_FNS(Checked, checked); | ||
32 | BUFFER_FNS(Defrag, defrag); | ||
33 | BUFFER_FNS(DefragDone, defrag_done); | ||
34 | |||
35 | static inline struct btrfs_node *btrfs_buffer_node(struct buffer_head *bh) | ||
36 | { | ||
37 | return (struct btrfs_node *)bh->b_data; | ||
38 | } | ||
39 | |||
40 | static inline struct btrfs_leaf *btrfs_buffer_leaf(struct buffer_head *bh) | ||
41 | { | ||
42 | return (struct btrfs_leaf *)bh->b_data; | ||
43 | } | ||
44 | |||
45 | static inline struct btrfs_header *btrfs_buffer_header(struct buffer_head *bh) | ||
46 | { | ||
47 | return &((struct btrfs_node *)bh->b_data)->header; | ||
48 | } | ||
49 | |||
50 | struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr); | ||
51 | int readahead_tree_block(struct btrfs_root *root, u64 blocknr); | 25 | int readahead_tree_block(struct btrfs_root *root, u64 blocknr); |
52 | struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root, | 26 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, |
53 | u64 blocknr); | 27 | u64 blocknr); |
54 | int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | ||
55 | struct buffer_head *buf); | ||
56 | int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | ||
57 | struct buffer_head *buf); | ||
58 | int clean_tree_block(struct btrfs_trans_handle *trans, | 28 | int clean_tree_block(struct btrfs_trans_handle *trans, |
59 | struct btrfs_root *root, struct buffer_head *buf); | 29 | struct btrfs_root *root, struct extent_buffer *buf); |
60 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | ||
61 | struct btrfs_root *root); | ||
62 | struct btrfs_root *open_ctree(struct super_block *sb); | 30 | struct btrfs_root *open_ctree(struct super_block *sb); |
63 | int close_ctree(struct btrfs_root *root); | 31 | int close_ctree(struct btrfs_root *root); |
64 | void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf); | ||
65 | int write_ctree_super(struct btrfs_trans_handle *trans, | 32 | int write_ctree_super(struct btrfs_trans_handle *trans, |
66 | struct btrfs_root *root); | 33 | struct btrfs_root *root); |
67 | struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr); | 34 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
68 | int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len, | 35 | u64 blocknr); |
69 | char *result); | ||
70 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | 36 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, |
71 | struct btrfs_key *location, | 37 | struct btrfs_key *location, |
72 | const char *name, int namelen); | 38 | const char *name, int namelen); |
73 | struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info, | 39 | struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info, |
74 | struct btrfs_key *location); | 40 | struct btrfs_key *location); |
75 | u64 bh_blocknr(struct buffer_head *bh); | ||
76 | int btrfs_insert_dev_radix(struct btrfs_root *root, | 41 | int btrfs_insert_dev_radix(struct btrfs_root *root, |
77 | struct block_device *bdev, | 42 | struct block_device *bdev, |
78 | u64 device_id, | 43 | u64 device_id, |
79 | u64 block_start, | 44 | u64 block_start, |
80 | u64 num_blocks); | 45 | u64 num_blocks); |
81 | int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh, | ||
82 | u64 logical); | ||
83 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); | 46 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); |
84 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); | 47 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); |
85 | void btrfs_mark_buffer_dirty(struct buffer_head *bh); | 48 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf); |
49 | int btrfs_buffer_uptodate(struct extent_buffer *buf); | ||
50 | int btrfs_set_buffer_uptodate(struct extent_buffer *buf); | ||
51 | int wait_on_tree_block_writeback(struct btrfs_root *root, | ||
52 | struct extent_buffer *buf); | ||
86 | #endif | 53 | #endif |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f261a8326cdf..089c41cbca74 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -33,7 +33,7 @@ static int cache_block_group(struct btrfs_root *root, | |||
33 | struct btrfs_path *path; | 33 | struct btrfs_path *path; |
34 | int ret; | 34 | int ret; |
35 | struct btrfs_key key; | 35 | struct btrfs_key key; |
36 | struct btrfs_leaf *leaf; | 36 | struct extent_buffer *leaf; |
37 | struct radix_tree_root *extent_radix; | 37 | struct radix_tree_root *extent_radix; |
38 | int slot; | 38 | int slot; |
39 | u64 i; | 39 | u64 i; |
@@ -56,7 +56,6 @@ static int cache_block_group(struct btrfs_root *root, | |||
56 | path->reada = 2; | 56 | path->reada = 2; |
57 | first_free = block_group->key.objectid; | 57 | first_free = block_group->key.objectid; |
58 | key.objectid = block_group->key.objectid; | 58 | key.objectid = block_group->key.objectid; |
59 | key.flags = 0; | ||
60 | key.offset = 0; | 59 | key.offset = 0; |
61 | 60 | ||
62 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 61 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
@@ -69,9 +68,9 @@ static int cache_block_group(struct btrfs_root *root, | |||
69 | path->slots[0]--; | 68 | path->slots[0]--; |
70 | 69 | ||
71 | while(1) { | 70 | while(1) { |
72 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 71 | leaf = path->nodes[0]; |
73 | slot = path->slots[0]; | 72 | slot = path->slots[0]; |
74 | if (slot >= btrfs_header_nritems(&leaf->header)) { | 73 | if (slot >= btrfs_header_nritems(leaf)) { |
75 | ret = btrfs_next_leaf(root, path); | 74 | ret = btrfs_next_leaf(root, path); |
76 | if (ret < 0) | 75 | if (ret < 0) |
77 | goto err; | 76 | goto err; |
@@ -82,7 +81,7 @@ static int cache_block_group(struct btrfs_root *root, | |||
82 | } | 81 | } |
83 | } | 82 | } |
84 | 83 | ||
85 | btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); | 84 | btrfs_item_key_to_cpu(leaf, &key, slot); |
86 | if (key.objectid < block_group->key.objectid) { | 85 | if (key.objectid < block_group->key.objectid) { |
87 | if (key.objectid + key.offset > first_free) | 86 | if (key.objectid + key.offset > first_free) |
88 | first_free = key.objectid + key.offset; | 87 | first_free = key.objectid + key.offset; |
@@ -116,8 +115,7 @@ next: | |||
116 | hole_size = block_group->key.objectid + | 115 | hole_size = block_group->key.objectid + |
117 | block_group->key.offset - last; | 116 | block_group->key.offset - last; |
118 | for (i = 0; i < hole_size; i++) { | 117 | for (i = 0; i < hole_size; i++) { |
119 | set_radix_bit(extent_radix, | 118 | set_radix_bit(extent_radix, last + i); |
120 | last + i); | ||
121 | } | 119 | } |
122 | } | 120 | } |
123 | block_group->cached = 1; | 121 | block_group->cached = 1; |
@@ -366,7 +364,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
366 | struct btrfs_path *path; | 364 | struct btrfs_path *path; |
367 | int ret; | 365 | int ret; |
368 | struct btrfs_key key; | 366 | struct btrfs_key key; |
369 | struct btrfs_leaf *l; | 367 | struct extent_buffer *l; |
370 | struct btrfs_extent_item *item; | 368 | struct btrfs_extent_item *item; |
371 | u32 refs; | 369 | u32 refs; |
372 | 370 | ||
@@ -375,7 +373,6 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
375 | return -ENOMEM; | 373 | return -ENOMEM; |
376 | 374 | ||
377 | key.objectid = blocknr; | 375 | key.objectid = blocknr; |
378 | key.flags = 0; | ||
379 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 376 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
380 | key.offset = num_blocks; | 377 | key.offset = num_blocks; |
381 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 378 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
@@ -386,10 +383,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
386 | BUG(); | 383 | BUG(); |
387 | } | 384 | } |
388 | BUG_ON(ret != 0); | 385 | BUG_ON(ret != 0); |
389 | l = btrfs_buffer_leaf(path->nodes[0]); | 386 | l = path->nodes[0]; |
390 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); | 387 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); |
391 | refs = btrfs_extent_refs(item); | 388 | refs = btrfs_extent_refs(l, item); |
392 | btrfs_set_extent_refs(item, refs + 1); | 389 | btrfs_set_extent_refs(l, item, refs + 1); |
393 | btrfs_mark_buffer_dirty(path->nodes[0]); | 390 | btrfs_mark_buffer_dirty(path->nodes[0]); |
394 | 391 | ||
395 | btrfs_release_path(root->fs_info->extent_root, path); | 392 | btrfs_release_path(root->fs_info->extent_root, path); |
@@ -414,23 +411,25 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans, | |||
414 | struct btrfs_path *path; | 411 | struct btrfs_path *path; |
415 | int ret; | 412 | int ret; |
416 | struct btrfs_key key; | 413 | struct btrfs_key key; |
417 | struct btrfs_leaf *l; | 414 | struct extent_buffer *l; |
418 | struct btrfs_extent_item *item; | 415 | struct btrfs_extent_item *item; |
419 | 416 | ||
420 | path = btrfs_alloc_path(); | 417 | path = btrfs_alloc_path(); |
421 | key.objectid = blocknr; | 418 | key.objectid = blocknr; |
422 | key.offset = num_blocks; | 419 | key.offset = num_blocks; |
423 | key.flags = 0; | ||
424 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 420 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
425 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 421 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
426 | 0, 0); | 422 | 0, 0); |
427 | if (ret < 0) | 423 | if (ret < 0) |
428 | goto out; | 424 | goto out; |
429 | if (ret != 0) | 425 | if (ret != 0) { |
426 | btrfs_print_leaf(root, path->nodes[0]); | ||
427 | printk("failed to find block number %Lu\n", blocknr); | ||
430 | BUG(); | 428 | BUG(); |
431 | l = btrfs_buffer_leaf(path->nodes[0]); | 429 | } |
430 | l = path->nodes[0]; | ||
432 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); | 431 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); |
433 | *refs = btrfs_extent_refs(item); | 432 | *refs = btrfs_extent_refs(l, item); |
434 | out: | 433 | out: |
435 | btrfs_free_path(path); | 434 | btrfs_free_path(path); |
436 | return 0; | 435 | return 0; |
@@ -439,16 +438,16 @@ out: | |||
439 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 438 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
440 | struct btrfs_root *root) | 439 | struct btrfs_root *root) |
441 | { | 440 | { |
442 | return btrfs_inc_extent_ref(trans, root, bh_blocknr(root->node), 1); | 441 | return btrfs_inc_extent_ref(trans, root, |
442 | extent_buffer_blocknr(root->node), 1); | ||
443 | } | 443 | } |
444 | 444 | ||
445 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 445 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
446 | struct buffer_head *buf) | 446 | struct extent_buffer *buf) |
447 | { | 447 | { |
448 | u64 blocknr; | 448 | u64 blocknr; |
449 | struct btrfs_node *buf_node; | 449 | u32 nritems; |
450 | struct btrfs_leaf *buf_leaf; | 450 | struct btrfs_key key; |
451 | struct btrfs_disk_key *key; | ||
452 | struct btrfs_file_extent_item *fi; | 451 | struct btrfs_file_extent_item *fi; |
453 | int i; | 452 | int i; |
454 | int leaf; | 453 | int leaf; |
@@ -458,31 +457,31 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
458 | 457 | ||
459 | if (!root->ref_cows) | 458 | if (!root->ref_cows) |
460 | return 0; | 459 | return 0; |
461 | buf_node = btrfs_buffer_node(buf); | 460 | |
462 | leaf = btrfs_is_leaf(buf_node); | 461 | leaf = btrfs_is_leaf(buf); |
463 | buf_leaf = btrfs_buffer_leaf(buf); | 462 | nritems = btrfs_header_nritems(buf); |
464 | for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) { | 463 | for (i = 0; i < nritems; i++) { |
465 | if (leaf) { | 464 | if (leaf) { |
466 | u64 disk_blocknr; | 465 | u64 disk_blocknr; |
467 | key = &buf_leaf->items[i].key; | 466 | btrfs_item_key_to_cpu(buf, &key, i); |
468 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) | 467 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
469 | continue; | 468 | continue; |
470 | fi = btrfs_item_ptr(buf_leaf, i, | 469 | fi = btrfs_item_ptr(buf, i, |
471 | struct btrfs_file_extent_item); | 470 | struct btrfs_file_extent_item); |
472 | if (btrfs_file_extent_type(fi) == | 471 | if (btrfs_file_extent_type(buf, fi) == |
473 | BTRFS_FILE_EXTENT_INLINE) | 472 | BTRFS_FILE_EXTENT_INLINE) |
474 | continue; | 473 | continue; |
475 | disk_blocknr = btrfs_file_extent_disk_blocknr(fi); | 474 | disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); |
476 | if (disk_blocknr == 0) | 475 | if (disk_blocknr == 0) |
477 | continue; | 476 | continue; |
478 | ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, | 477 | ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, |
479 | btrfs_file_extent_disk_num_blocks(fi)); | 478 | btrfs_file_extent_disk_num_blocks(buf, fi)); |
480 | if (ret) { | 479 | if (ret) { |
481 | faili = i; | 480 | faili = i; |
482 | goto fail; | 481 | goto fail; |
483 | } | 482 | } |
484 | } else { | 483 | } else { |
485 | blocknr = btrfs_node_blockptr(buf_node, i); | 484 | blocknr = btrfs_node_blockptr(buf, i); |
486 | ret = btrfs_inc_extent_ref(trans, root, blocknr, 1); | 485 | ret = btrfs_inc_extent_ref(trans, root, blocknr, 1); |
487 | if (ret) { | 486 | if (ret) { |
488 | faili = i; | 487 | faili = i; |
@@ -496,22 +495,23 @@ fail: | |||
496 | for (i =0; i < faili; i++) { | 495 | for (i =0; i < faili; i++) { |
497 | if (leaf) { | 496 | if (leaf) { |
498 | u64 disk_blocknr; | 497 | u64 disk_blocknr; |
499 | key = &buf_leaf->items[i].key; | 498 | btrfs_item_key_to_cpu(buf, &key, i); |
500 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) | 499 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
501 | continue; | 500 | continue; |
502 | fi = btrfs_item_ptr(buf_leaf, i, | 501 | fi = btrfs_item_ptr(buf, i, |
503 | struct btrfs_file_extent_item); | 502 | struct btrfs_file_extent_item); |
504 | if (btrfs_file_extent_type(fi) == | 503 | if (btrfs_file_extent_type(buf, fi) == |
505 | BTRFS_FILE_EXTENT_INLINE) | 504 | BTRFS_FILE_EXTENT_INLINE) |
506 | continue; | 505 | continue; |
507 | disk_blocknr = btrfs_file_extent_disk_blocknr(fi); | 506 | disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); |
508 | if (disk_blocknr == 0) | 507 | if (disk_blocknr == 0) |
509 | continue; | 508 | continue; |
510 | err = btrfs_free_extent(trans, root, disk_blocknr, | 509 | err = btrfs_free_extent(trans, root, disk_blocknr, |
511 | btrfs_file_extent_disk_num_blocks(fi), 0); | 510 | btrfs_file_extent_disk_num_blocks(buf, |
511 | fi), 0); | ||
512 | BUG_ON(err); | 512 | BUG_ON(err); |
513 | } else { | 513 | } else { |
514 | blocknr = btrfs_node_blockptr(buf_node, i); | 514 | blocknr = btrfs_node_blockptr(buf, i); |
515 | err = btrfs_free_extent(trans, root, blocknr, 1, 0); | 515 | err = btrfs_free_extent(trans, root, blocknr, 1, 0); |
516 | BUG_ON(err); | 516 | BUG_ON(err); |
517 | } | 517 | } |
@@ -527,16 +527,18 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
527 | int ret; | 527 | int ret; |
528 | int pending_ret; | 528 | int pending_ret; |
529 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 529 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
530 | struct btrfs_block_group_item *bi; | 530 | unsigned long bi; |
531 | struct extent_buffer *leaf; | ||
531 | 532 | ||
532 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); | 533 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); |
533 | if (ret < 0) | 534 | if (ret < 0) |
534 | goto fail; | 535 | goto fail; |
535 | BUG_ON(ret); | 536 | BUG_ON(ret); |
536 | bi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], | 537 | |
537 | struct btrfs_block_group_item); | 538 | leaf = path->nodes[0]; |
538 | memcpy(bi, &cache->item, sizeof(*bi)); | 539 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); |
539 | btrfs_mark_buffer_dirty(path->nodes[0]); | 540 | write_extent_buffer(leaf, &cache->item, bi, sizeof(cache->item)); |
541 | btrfs_mark_buffer_dirty(leaf); | ||
540 | btrfs_release_path(extent_root, path); | 542 | btrfs_release_path(extent_root, path); |
541 | fail: | 543 | fail: |
542 | finish_current_insert(trans, extent_root); | 544 | finish_current_insert(trans, extent_root); |
@@ -768,11 +770,11 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
768 | unsigned long gang[8]; | 770 | unsigned long gang[8]; |
769 | struct btrfs_fs_info *info = extent_root->fs_info; | 771 | struct btrfs_fs_info *info = extent_root->fs_info; |
770 | 772 | ||
771 | btrfs_set_extent_refs(&extent_item, 1); | 773 | btrfs_set_stack_extent_refs(&extent_item, 1); |
772 | ins.offset = 1; | 774 | ins.offset = 1; |
773 | ins.flags = 0; | ||
774 | btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); | 775 | btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); |
775 | btrfs_set_extent_owner(&extent_item, extent_root->root_key.objectid); | 776 | btrfs_set_stack_extent_owner(&extent_item, |
777 | extent_root->root_key.objectid); | ||
776 | 778 | ||
777 | while(1) { | 779 | while(1) { |
778 | ret = find_first_radix_bit(&info->extent_ins_radix, gang, 0, | 780 | ret = find_first_radix_bit(&info->extent_ins_radix, gang, 0, |
@@ -795,23 +797,20 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
795 | static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | 797 | static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) |
796 | { | 798 | { |
797 | int err; | 799 | int err; |
798 | struct btrfs_header *header; | 800 | struct extent_buffer *buf; |
799 | struct buffer_head *bh; | ||
800 | 801 | ||
801 | if (!pending) { | 802 | if (!pending) { |
802 | bh = btrfs_find_tree_block(root, blocknr); | 803 | buf = btrfs_find_tree_block(root, blocknr); |
803 | if (bh) { | 804 | if (buf) { |
804 | if (buffer_uptodate(bh)) { | 805 | if (btrfs_buffer_uptodate(buf)) { |
805 | u64 transid = | 806 | u64 transid = |
806 | root->fs_info->running_transaction->transid; | 807 | root->fs_info->running_transaction->transid; |
807 | header = btrfs_buffer_header(bh); | 808 | if (btrfs_header_generation(buf) == transid) { |
808 | if (btrfs_header_generation(header) == | 809 | free_extent_buffer(buf); |
809 | transid) { | ||
810 | btrfs_block_release(root, bh); | ||
811 | return 0; | 810 | return 0; |
812 | } | 811 | } |
813 | } | 812 | } |
814 | btrfs_block_release(root, bh); | 813 | free_extent_buffer(buf); |
815 | } | 814 | } |
816 | err = set_radix_bit(&root->fs_info->pinned_radix, blocknr); | 815 | err = set_radix_bit(&root->fs_info->pinned_radix, blocknr); |
817 | if (!err) { | 816 | if (!err) { |
@@ -839,12 +838,12 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
839 | struct btrfs_key key; | 838 | struct btrfs_key key; |
840 | struct btrfs_fs_info *info = root->fs_info; | 839 | struct btrfs_fs_info *info = root->fs_info; |
841 | struct btrfs_root *extent_root = info->extent_root; | 840 | struct btrfs_root *extent_root = info->extent_root; |
841 | struct extent_buffer *leaf; | ||
842 | int ret; | 842 | int ret; |
843 | struct btrfs_extent_item *ei; | 843 | struct btrfs_extent_item *ei; |
844 | u32 refs; | 844 | u32 refs; |
845 | 845 | ||
846 | key.objectid = blocknr; | 846 | key.objectid = blocknr; |
847 | key.flags = 0; | ||
848 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 847 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
849 | key.offset = num_blocks; | 848 | key.offset = num_blocks; |
850 | 849 | ||
@@ -856,12 +855,16 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
856 | if (ret < 0) | 855 | if (ret < 0) |
857 | return ret; | 856 | return ret; |
858 | BUG_ON(ret); | 857 | BUG_ON(ret); |
859 | ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], | 858 | |
859 | leaf = path->nodes[0]; | ||
860 | ei = btrfs_item_ptr(leaf, path->slots[0], | ||
860 | struct btrfs_extent_item); | 861 | struct btrfs_extent_item); |
861 | BUG_ON(ei->refs == 0); | 862 | refs = btrfs_extent_refs(leaf, ei); |
862 | refs = btrfs_extent_refs(ei) - 1; | 863 | BUG_ON(refs == 0); |
863 | btrfs_set_extent_refs(ei, refs); | 864 | refs -= 1; |
864 | btrfs_mark_buffer_dirty(path->nodes[0]); | 865 | btrfs_set_extent_refs(leaf, ei, refs); |
866 | btrfs_mark_buffer_dirty(leaf); | ||
867 | |||
865 | if (refs == 0) { | 868 | if (refs == 0) { |
866 | u64 super_blocks_used, root_blocks_used; | 869 | u64 super_blocks_used, root_blocks_used; |
867 | 870 | ||
@@ -876,8 +879,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
876 | super_blocks_used - num_blocks); | 879 | super_blocks_used - num_blocks); |
877 | 880 | ||
878 | /* block accounting for root item */ | 881 | /* block accounting for root item */ |
879 | root_blocks_used = btrfs_root_blocks_used(&root->root_item); | 882 | root_blocks_used = btrfs_root_used(&root->root_item); |
880 | btrfs_set_root_blocks_used(&root->root_item, | 883 | btrfs_set_root_used(&root->root_item, |
881 | root_blocks_used - num_blocks); | 884 | root_blocks_used - num_blocks); |
882 | 885 | ||
883 | ret = btrfs_del_item(trans, extent_root, path); | 886 | ret = btrfs_del_item(trans, extent_root, path); |
@@ -984,7 +987,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
984 | u64 test_block; | 987 | u64 test_block; |
985 | u64 orig_search_start = search_start; | 988 | u64 orig_search_start = search_start; |
986 | int start_found; | 989 | int start_found; |
987 | struct btrfs_leaf *l; | 990 | struct extent_buffer *l; |
988 | struct btrfs_root * root = orig_root->fs_info->extent_root; | 991 | struct btrfs_root * root = orig_root->fs_info->extent_root; |
989 | struct btrfs_fs_info *info = root->fs_info; | 992 | struct btrfs_fs_info *info = root->fs_info; |
990 | int total_needed = num_blocks; | 993 | int total_needed = num_blocks; |
@@ -994,10 +997,10 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
994 | int wrapped = 0; | 997 | int wrapped = 0; |
995 | 998 | ||
996 | WARN_ON(num_blocks < 1); | 999 | WARN_ON(num_blocks < 1); |
997 | ins->flags = 0; | ||
998 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 1000 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
999 | 1001 | ||
1000 | level = btrfs_header_level(btrfs_buffer_header(root->node)); | 1002 | level = btrfs_header_level(root->node); |
1003 | |||
1001 | if (search_end == (u64)-1) | 1004 | if (search_end == (u64)-1) |
1002 | search_end = btrfs_super_total_blocks(&info->super_copy); | 1005 | search_end = btrfs_super_total_blocks(&info->super_copy); |
1003 | if (hint_block) { | 1006 | if (hint_block) { |
@@ -1034,8 +1037,9 @@ check_failed: | |||
1034 | path->slots[0]--; | 1037 | path->slots[0]--; |
1035 | } | 1038 | } |
1036 | 1039 | ||
1037 | l = btrfs_buffer_leaf(path->nodes[0]); | 1040 | l = path->nodes[0]; |
1038 | btrfs_disk_key_to_cpu(&key, &l->items[path->slots[0]].key); | 1041 | btrfs_item_key_to_cpu(l, &key, path->slots[0]); |
1042 | |||
1039 | /* | 1043 | /* |
1040 | * a rare case, go back one key if we hit a block group item | 1044 | * a rare case, go back one key if we hit a block group item |
1041 | * instead of an extent item | 1045 | * instead of an extent item |
@@ -1055,9 +1059,9 @@ check_failed: | |||
1055 | } | 1059 | } |
1056 | 1060 | ||
1057 | while (1) { | 1061 | while (1) { |
1058 | l = btrfs_buffer_leaf(path->nodes[0]); | 1062 | l = path->nodes[0]; |
1059 | slot = path->slots[0]; | 1063 | slot = path->slots[0]; |
1060 | if (slot >= btrfs_header_nritems(&l->header)) { | 1064 | if (slot >= btrfs_header_nritems(l)) { |
1061 | ret = btrfs_next_leaf(root, path); | 1065 | ret = btrfs_next_leaf(root, path); |
1062 | if (ret == 0) | 1066 | if (ret == 0) |
1063 | continue; | 1067 | continue; |
@@ -1075,7 +1079,7 @@ check_failed: | |||
1075 | goto check_pending; | 1079 | goto check_pending; |
1076 | } | 1080 | } |
1077 | 1081 | ||
1078 | btrfs_disk_key_to_cpu(&key, &l->items[slot].key); | 1082 | btrfs_item_key_to_cpu(l, &key, slot); |
1079 | if (key.objectid >= search_start && key.objectid > last_block && | 1083 | if (key.objectid >= search_start && key.objectid > last_block && |
1080 | start_found) { | 1084 | start_found) { |
1081 | if (last_block < search_start) | 1085 | if (last_block < search_start) |
@@ -1183,8 +1187,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1183 | struct btrfs_root *extent_root = info->extent_root; | 1187 | struct btrfs_root *extent_root = info->extent_root; |
1184 | struct btrfs_extent_item extent_item; | 1188 | struct btrfs_extent_item extent_item; |
1185 | 1189 | ||
1186 | btrfs_set_extent_refs(&extent_item, 1); | 1190 | btrfs_set_stack_extent_refs(&extent_item, 1); |
1187 | btrfs_set_extent_owner(&extent_item, owner); | 1191 | btrfs_set_stack_extent_owner(&extent_item, owner); |
1188 | 1192 | ||
1189 | WARN_ON(num_blocks < 1); | 1193 | WARN_ON(num_blocks < 1); |
1190 | ret = find_free_extent(trans, root, num_blocks, empty_size, | 1194 | ret = find_free_extent(trans, root, num_blocks, empty_size, |
@@ -1201,8 +1205,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1201 | num_blocks); | 1205 | num_blocks); |
1202 | 1206 | ||
1203 | /* block accounting for root item */ | 1207 | /* block accounting for root item */ |
1204 | root_blocks_used = btrfs_root_blocks_used(&root->root_item); | 1208 | root_blocks_used = btrfs_root_used(&root->root_item); |
1205 | btrfs_set_root_blocks_used(&root->root_item, root_blocks_used + | 1209 | btrfs_set_root_used(&root->root_item, root_blocks_used + |
1206 | num_blocks); | 1210 | num_blocks); |
1207 | 1211 | ||
1208 | if (root == extent_root) { | 1212 | if (root == extent_root) { |
@@ -1241,13 +1245,13 @@ update_block: | |||
1241 | * helper function to allocate a block for a given tree | 1245 | * helper function to allocate a block for a given tree |
1242 | * returns the tree buffer or NULL. | 1246 | * returns the tree buffer or NULL. |
1243 | */ | 1247 | */ |
1244 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1248 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1245 | struct btrfs_root *root, u64 hint, | 1249 | struct btrfs_root *root, u64 hint, |
1246 | u64 empty_size) | 1250 | u64 empty_size) |
1247 | { | 1251 | { |
1248 | struct btrfs_key ins; | 1252 | struct btrfs_key ins; |
1249 | int ret; | 1253 | int ret; |
1250 | struct buffer_head *buf; | 1254 | struct extent_buffer *buf; |
1251 | 1255 | ||
1252 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, | 1256 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, |
1253 | 1, empty_size, hint, (u64)-1, &ins, 0); | 1257 | 1, empty_size, hint, (u64)-1, &ins, 0); |
@@ -1260,53 +1264,57 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
1260 | btrfs_free_extent(trans, root, ins.objectid, 1, 0); | 1264 | btrfs_free_extent(trans, root, ins.objectid, 1, 0); |
1261 | return ERR_PTR(-ENOMEM); | 1265 | return ERR_PTR(-ENOMEM); |
1262 | } | 1266 | } |
1263 | WARN_ON(buffer_dirty(buf)); | 1267 | btrfs_set_buffer_uptodate(buf); |
1264 | set_buffer_uptodate(buf); | 1268 | set_extent_dirty(&trans->transaction->dirty_pages, buf->start, |
1269 | buf->start + buf->len - 1, GFP_NOFS); | ||
1270 | /* | ||
1265 | set_buffer_checked(buf); | 1271 | set_buffer_checked(buf); |
1266 | set_buffer_defrag(buf); | 1272 | set_buffer_defrag(buf); |
1267 | set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); | 1273 | */ |
1274 | /* FIXME!!!!!!!!!!!!!!!! | ||
1275 | set_radix_bit(&trans->transaction->dirty_pages, buf->pages[0]->index); | ||
1276 | */ | ||
1268 | trans->blocks_used++; | 1277 | trans->blocks_used++; |
1269 | return buf; | 1278 | return buf; |
1270 | } | 1279 | } |
1271 | 1280 | ||
1272 | static int drop_leaf_ref(struct btrfs_trans_handle *trans, | 1281 | static int drop_leaf_ref(struct btrfs_trans_handle *trans, |
1273 | struct btrfs_root *root, struct buffer_head *cur) | 1282 | struct btrfs_root *root, struct extent_buffer *leaf) |
1274 | { | 1283 | { |
1275 | struct btrfs_disk_key *key; | 1284 | struct btrfs_key key; |
1276 | struct btrfs_leaf *leaf; | ||
1277 | struct btrfs_file_extent_item *fi; | 1285 | struct btrfs_file_extent_item *fi; |
1278 | int i; | 1286 | int i; |
1279 | int nritems; | 1287 | int nritems; |
1280 | int ret; | 1288 | int ret; |
1281 | 1289 | ||
1282 | BUG_ON(!btrfs_is_leaf(btrfs_buffer_node(cur))); | 1290 | BUG_ON(!btrfs_is_leaf(leaf)); |
1283 | leaf = btrfs_buffer_leaf(cur); | 1291 | nritems = btrfs_header_nritems(leaf); |
1284 | nritems = btrfs_header_nritems(&leaf->header); | ||
1285 | for (i = 0; i < nritems; i++) { | 1292 | for (i = 0; i < nritems; i++) { |
1286 | u64 disk_blocknr; | 1293 | u64 disk_blocknr; |
1287 | key = &leaf->items[i].key; | 1294 | |
1288 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) | 1295 | btrfs_item_key_to_cpu(leaf, &key, i); |
1296 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
1289 | continue; | 1297 | continue; |
1290 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); | 1298 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); |
1291 | if (btrfs_file_extent_type(fi) == BTRFS_FILE_EXTENT_INLINE) | 1299 | if (btrfs_file_extent_type(leaf, fi) == |
1300 | BTRFS_FILE_EXTENT_INLINE) | ||
1292 | continue; | 1301 | continue; |
1293 | /* | 1302 | /* |
1294 | * FIXME make sure to insert a trans record that | 1303 | * FIXME make sure to insert a trans record that |
1295 | * repeats the snapshot del on crash | 1304 | * repeats the snapshot del on crash |
1296 | */ | 1305 | */ |
1297 | disk_blocknr = btrfs_file_extent_disk_blocknr(fi); | 1306 | disk_blocknr = btrfs_file_extent_disk_blocknr(leaf, fi); |
1298 | if (disk_blocknr == 0) | 1307 | if (disk_blocknr == 0) |
1299 | continue; | 1308 | continue; |
1300 | ret = btrfs_free_extent(trans, root, disk_blocknr, | 1309 | ret = btrfs_free_extent(trans, root, disk_blocknr, |
1301 | btrfs_file_extent_disk_num_blocks(fi), | 1310 | btrfs_file_extent_disk_num_blocks(leaf, fi), 0); |
1302 | 0); | ||
1303 | BUG_ON(ret); | 1311 | BUG_ON(ret); |
1304 | } | 1312 | } |
1305 | return 0; | 1313 | return 0; |
1306 | } | 1314 | } |
1307 | 1315 | ||
1308 | static void reada_walk_down(struct btrfs_root *root, | 1316 | static void reada_walk_down(struct btrfs_root *root, |
1309 | struct btrfs_node *node) | 1317 | struct extent_buffer *node) |
1310 | { | 1318 | { |
1311 | int i; | 1319 | int i; |
1312 | u32 nritems; | 1320 | u32 nritems; |
@@ -1314,7 +1322,7 @@ static void reada_walk_down(struct btrfs_root *root, | |||
1314 | int ret; | 1322 | int ret; |
1315 | u32 refs; | 1323 | u32 refs; |
1316 | 1324 | ||
1317 | nritems = btrfs_header_nritems(&node->header); | 1325 | nritems = btrfs_header_nritems(node); |
1318 | for (i = 0; i < nritems; i++) { | 1326 | for (i = 0; i < nritems; i++) { |
1319 | blocknr = btrfs_node_blockptr(node, i); | 1327 | blocknr = btrfs_node_blockptr(node, i); |
1320 | ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); | 1328 | ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); |
@@ -1337,16 +1345,17 @@ static void reada_walk_down(struct btrfs_root *root, | |||
1337 | static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | 1345 | static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root |
1338 | *root, struct btrfs_path *path, int *level) | 1346 | *root, struct btrfs_path *path, int *level) |
1339 | { | 1347 | { |
1340 | struct buffer_head *next; | 1348 | struct extent_buffer *next; |
1341 | struct buffer_head *cur; | 1349 | struct extent_buffer *cur; |
1342 | u64 blocknr; | 1350 | u64 blocknr; |
1343 | int ret; | 1351 | int ret; |
1344 | u32 refs; | 1352 | u32 refs; |
1345 | 1353 | ||
1346 | WARN_ON(*level < 0); | 1354 | WARN_ON(*level < 0); |
1347 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1355 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1348 | ret = lookup_extent_ref(trans, root, bh_blocknr(path->nodes[*level]), | 1356 | ret = lookup_extent_ref(trans, root, |
1349 | 1, &refs); | 1357 | extent_buffer_blocknr(path->nodes[*level]), |
1358 | 1, &refs); | ||
1350 | BUG_ON(ret); | 1359 | BUG_ON(ret); |
1351 | if (refs > 1) | 1360 | if (refs > 1) |
1352 | goto out; | 1361 | goto out; |
@@ -1360,21 +1369,20 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1360 | cur = path->nodes[*level]; | 1369 | cur = path->nodes[*level]; |
1361 | 1370 | ||
1362 | if (*level > 0 && path->slots[*level] == 0) | 1371 | if (*level > 0 && path->slots[*level] == 0) |
1363 | reada_walk_down(root, btrfs_buffer_node(cur)); | 1372 | reada_walk_down(root, cur); |
1364 | 1373 | ||
1365 | if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) | 1374 | if (btrfs_header_level(cur) != *level) |
1366 | WARN_ON(1); | 1375 | WARN_ON(1); |
1367 | 1376 | ||
1368 | if (path->slots[*level] >= | 1377 | if (path->slots[*level] >= |
1369 | btrfs_header_nritems(btrfs_buffer_header(cur))) | 1378 | btrfs_header_nritems(cur)) |
1370 | break; | 1379 | break; |
1371 | if (*level == 0) { | 1380 | if (*level == 0) { |
1372 | ret = drop_leaf_ref(trans, root, cur); | 1381 | ret = drop_leaf_ref(trans, root, cur); |
1373 | BUG_ON(ret); | 1382 | BUG_ON(ret); |
1374 | break; | 1383 | break; |
1375 | } | 1384 | } |
1376 | blocknr = btrfs_node_blockptr(btrfs_buffer_node(cur), | 1385 | blocknr = btrfs_node_blockptr(cur, path->slots[*level]); |
1377 | path->slots[*level]); | ||
1378 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1386 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); |
1379 | BUG_ON(ret); | 1387 | BUG_ON(ret); |
1380 | if (refs != 1) { | 1388 | if (refs != 1) { |
@@ -1384,8 +1392,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1384 | continue; | 1392 | continue; |
1385 | } | 1393 | } |
1386 | next = btrfs_find_tree_block(root, blocknr); | 1394 | next = btrfs_find_tree_block(root, blocknr); |
1387 | if (!next || !buffer_uptodate(next)) { | 1395 | if (!next || !btrfs_buffer_uptodate(next)) { |
1388 | brelse(next); | 1396 | free_extent_buffer(next); |
1389 | mutex_unlock(&root->fs_info->fs_mutex); | 1397 | mutex_unlock(&root->fs_info->fs_mutex); |
1390 | next = read_tree_block(root, blocknr); | 1398 | next = read_tree_block(root, blocknr); |
1391 | mutex_lock(&root->fs_info->fs_mutex); | 1399 | mutex_lock(&root->fs_info->fs_mutex); |
@@ -1395,7 +1403,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1395 | BUG_ON(ret); | 1403 | BUG_ON(ret); |
1396 | if (refs != 1) { | 1404 | if (refs != 1) { |
1397 | path->slots[*level]++; | 1405 | path->slots[*level]++; |
1398 | brelse(next); | 1406 | free_extent_buffer(next); |
1399 | ret = btrfs_free_extent(trans, root, | 1407 | ret = btrfs_free_extent(trans, root, |
1400 | blocknr, 1, 1); | 1408 | blocknr, 1, 1); |
1401 | BUG_ON(ret); | 1409 | BUG_ON(ret); |
@@ -1404,17 +1412,17 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1404 | } | 1412 | } |
1405 | WARN_ON(*level <= 0); | 1413 | WARN_ON(*level <= 0); |
1406 | if (path->nodes[*level-1]) | 1414 | if (path->nodes[*level-1]) |
1407 | btrfs_block_release(root, path->nodes[*level-1]); | 1415 | free_extent_buffer(path->nodes[*level-1]); |
1408 | path->nodes[*level-1] = next; | 1416 | path->nodes[*level-1] = next; |
1409 | *level = btrfs_header_level(btrfs_buffer_header(next)); | 1417 | *level = btrfs_header_level(next); |
1410 | path->slots[*level] = 0; | 1418 | path->slots[*level] = 0; |
1411 | } | 1419 | } |
1412 | out: | 1420 | out: |
1413 | WARN_ON(*level < 0); | 1421 | WARN_ON(*level < 0); |
1414 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1422 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1415 | ret = btrfs_free_extent(trans, root, | 1423 | ret = btrfs_free_extent(trans, root, |
1416 | bh_blocknr(path->nodes[*level]), 1, 1); | 1424 | extent_buffer_blocknr(path->nodes[*level]), 1, 1); |
1417 | btrfs_block_release(root, path->nodes[*level]); | 1425 | free_extent_buffer(path->nodes[*level]); |
1418 | path->nodes[*level] = NULL; | 1426 | path->nodes[*level] = NULL; |
1419 | *level += 1; | 1427 | *level += 1; |
1420 | BUG_ON(ret); | 1428 | BUG_ON(ret); |
@@ -1436,24 +1444,24 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1436 | 1444 | ||
1437 | for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { | 1445 | for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { |
1438 | slot = path->slots[i]; | 1446 | slot = path->slots[i]; |
1439 | if (slot < btrfs_header_nritems( | 1447 | if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { |
1440 | btrfs_buffer_header(path->nodes[i])) - 1) { | 1448 | struct extent_buffer *node; |
1441 | struct btrfs_node *node; | 1449 | struct btrfs_disk_key disk_key; |
1442 | node = btrfs_buffer_node(path->nodes[i]); | 1450 | node = path->nodes[i]; |
1443 | path->slots[i]++; | 1451 | path->slots[i]++; |
1444 | *level = i; | 1452 | *level = i; |
1445 | WARN_ON(*level == 0); | 1453 | WARN_ON(*level == 0); |
1454 | btrfs_node_key(node, &disk_key, path->slots[i]); | ||
1446 | memcpy(&root_item->drop_progress, | 1455 | memcpy(&root_item->drop_progress, |
1447 | &node->ptrs[path->slots[i]].key, | 1456 | &disk_key, sizeof(disk_key)); |
1448 | sizeof(root_item->drop_progress)); | ||
1449 | root_item->drop_level = i; | 1457 | root_item->drop_level = i; |
1450 | return 0; | 1458 | return 0; |
1451 | } else { | 1459 | } else { |
1452 | ret = btrfs_free_extent(trans, root, | 1460 | ret = btrfs_free_extent(trans, root, |
1453 | bh_blocknr(path->nodes[*level]), | 1461 | extent_buffer_blocknr(path->nodes[*level]), |
1454 | 1, 1); | 1462 | 1, 1); |
1455 | BUG_ON(ret); | 1463 | BUG_ON(ret); |
1456 | btrfs_block_release(root, path->nodes[*level]); | 1464 | free_extent_buffer(path->nodes[*level]); |
1457 | path->nodes[*level] = NULL; | 1465 | path->nodes[*level] = NULL; |
1458 | *level = i + 1; | 1466 | *level = i + 1; |
1459 | } | 1467 | } |
@@ -1480,15 +1488,15 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1480 | path = btrfs_alloc_path(); | 1488 | path = btrfs_alloc_path(); |
1481 | BUG_ON(!path); | 1489 | BUG_ON(!path); |
1482 | 1490 | ||
1483 | level = btrfs_header_level(btrfs_buffer_header(root->node)); | 1491 | level = btrfs_header_level(root->node); |
1484 | orig_level = level; | 1492 | orig_level = level; |
1485 | if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { | 1493 | if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { |
1486 | path->nodes[level] = root->node; | 1494 | path->nodes[level] = root->node; |
1487 | path->slots[level] = 0; | 1495 | path->slots[level] = 0; |
1488 | } else { | 1496 | } else { |
1489 | struct btrfs_key key; | 1497 | struct btrfs_key key; |
1490 | struct btrfs_disk_key *found_key; | 1498 | struct btrfs_disk_key found_key; |
1491 | struct btrfs_node *node; | 1499 | struct extent_buffer *node; |
1492 | 1500 | ||
1493 | btrfs_disk_key_to_cpu(&key, &root_item->drop_progress); | 1501 | btrfs_disk_key_to_cpu(&key, &root_item->drop_progress); |
1494 | level = root_item->drop_level; | 1502 | level = root_item->drop_level; |
@@ -1498,10 +1506,10 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1498 | ret = wret; | 1506 | ret = wret; |
1499 | goto out; | 1507 | goto out; |
1500 | } | 1508 | } |
1501 | node = btrfs_buffer_node(path->nodes[level]); | 1509 | node = path->nodes[level]; |
1502 | found_key = &node->ptrs[path->slots[level]].key; | 1510 | btrfs_node_key(node, &found_key, path->slots[level]); |
1503 | WARN_ON(memcmp(found_key, &root_item->drop_progress, | 1511 | WARN_ON(memcmp(&found_key, &root_item->drop_progress, |
1504 | sizeof(*found_key))); | 1512 | sizeof(found_key))); |
1505 | } | 1513 | } |
1506 | while(1) { | 1514 | while(1) { |
1507 | wret = walk_down_tree(trans, root, path, &level); | 1515 | wret = walk_down_tree(trans, root, path, &level); |
@@ -1516,12 +1524,12 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1516 | if (wret < 0) | 1524 | if (wret < 0) |
1517 | ret = wret; | 1525 | ret = wret; |
1518 | ret = -EAGAIN; | 1526 | ret = -EAGAIN; |
1519 | get_bh(root->node); | 1527 | extent_buffer_get(root->node); |
1520 | break; | 1528 | break; |
1521 | } | 1529 | } |
1522 | for (i = 0; i <= orig_level; i++) { | 1530 | for (i = 0; i <= orig_level; i++) { |
1523 | if (path->nodes[i]) { | 1531 | if (path->nodes[i]) { |
1524 | btrfs_block_release(root, path->nodes[i]); | 1532 | free_extent_buffer(path->nodes[i]); |
1525 | path->nodes[i] = 0; | 1533 | path->nodes[i] = 0; |
1526 | } | 1534 | } |
1527 | } | 1535 | } |
@@ -1581,13 +1589,12 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1581 | struct btrfs_path *path; | 1589 | struct btrfs_path *path; |
1582 | int ret; | 1590 | int ret; |
1583 | int err = 0; | 1591 | int err = 0; |
1584 | struct btrfs_block_group_item *bi; | ||
1585 | struct btrfs_block_group_cache *cache; | 1592 | struct btrfs_block_group_cache *cache; |
1586 | struct btrfs_fs_info *info = root->fs_info; | 1593 | struct btrfs_fs_info *info = root->fs_info; |
1587 | struct radix_tree_root *radix; | 1594 | struct radix_tree_root *radix; |
1588 | struct btrfs_key key; | 1595 | struct btrfs_key key; |
1589 | struct btrfs_key found_key; | 1596 | struct btrfs_key found_key; |
1590 | struct btrfs_leaf *leaf; | 1597 | struct extent_buffer *leaf; |
1591 | u64 group_size_blocks; | 1598 | u64 group_size_blocks; |
1592 | u64 used; | 1599 | u64 used; |
1593 | 1600 | ||
@@ -1596,7 +1603,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1596 | root = info->extent_root; | 1603 | root = info->extent_root; |
1597 | key.objectid = 0; | 1604 | key.objectid = 0; |
1598 | key.offset = group_size_blocks; | 1605 | key.offset = group_size_blocks; |
1599 | key.flags = 0; | ||
1600 | btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); | 1606 | btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); |
1601 | 1607 | ||
1602 | path = btrfs_alloc_path(); | 1608 | path = btrfs_alloc_path(); |
@@ -1610,18 +1616,18 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1610 | err = ret; | 1616 | err = ret; |
1611 | break; | 1617 | break; |
1612 | } | 1618 | } |
1613 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 1619 | leaf = path->nodes[0]; |
1614 | btrfs_disk_key_to_cpu(&found_key, | 1620 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
1615 | &leaf->items[path->slots[0]].key); | ||
1616 | cache = kmalloc(sizeof(*cache), GFP_NOFS); | 1621 | cache = kmalloc(sizeof(*cache), GFP_NOFS); |
1617 | if (!cache) { | 1622 | if (!cache) { |
1618 | err = -1; | 1623 | err = -1; |
1619 | break; | 1624 | break; |
1620 | } | 1625 | } |
1621 | 1626 | ||
1622 | bi = btrfs_item_ptr(leaf, path->slots[0], | 1627 | read_extent_buffer(leaf, &cache->item, |
1623 | struct btrfs_block_group_item); | 1628 | btrfs_item_ptr_offset(leaf, path->slots[0]), |
1624 | if (bi->flags & BTRFS_BLOCK_GROUP_DATA) { | 1629 | sizeof(cache->item)); |
1630 | if (cache->item.flags & BTRFS_BLOCK_GROUP_DATA) { | ||
1625 | radix = &info->block_group_data_radix; | 1631 | radix = &info->block_group_data_radix; |
1626 | cache->data = 1; | 1632 | cache->data = 1; |
1627 | } else { | 1633 | } else { |
@@ -1629,7 +1635,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1629 | cache->data = 0; | 1635 | cache->data = 0; |
1630 | } | 1636 | } |
1631 | 1637 | ||
1632 | memcpy(&cache->item, bi, sizeof(*bi)); | ||
1633 | memcpy(&cache->key, &found_key, sizeof(found_key)); | 1638 | memcpy(&cache->key, &found_key, sizeof(found_key)); |
1634 | cache->last_alloc = cache->key.objectid; | 1639 | cache->last_alloc = cache->key.objectid; |
1635 | cache->first_free = cache->key.objectid; | 1640 | cache->first_free = cache->key.objectid; |
@@ -1640,11 +1645,12 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1640 | 1645 | ||
1641 | key.objectid = found_key.objectid + found_key.offset; | 1646 | key.objectid = found_key.objectid + found_key.offset; |
1642 | btrfs_release_path(root, path); | 1647 | btrfs_release_path(root, path); |
1648 | |||
1643 | ret = radix_tree_insert(radix, found_key.objectid + | 1649 | ret = radix_tree_insert(radix, found_key.objectid + |
1644 | found_key.offset - 1, | 1650 | found_key.offset - 1, |
1645 | (void *)cache); | 1651 | (void *)cache); |
1646 | BUG_ON(ret); | 1652 | BUG_ON(ret); |
1647 | used = btrfs_block_group_used(bi); | 1653 | used = btrfs_block_group_used(&cache->item); |
1648 | if (used < div_factor(key.offset, 8)) { | 1654 | if (used < div_factor(key.offset, 8)) { |
1649 | radix_tree_tag_set(radix, found_key.objectid + | 1655 | radix_tree_tag_set(radix, found_key.objectid + |
1650 | found_key.offset - 1, | 1656 | found_key.offset - 1, |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 0ab368e091f9..55fefdfab84c 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -26,16 +26,6 @@ struct tree_entry { | |||
26 | struct rb_node rb_node; | 26 | struct rb_node rb_node; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | /* bits for the extent state */ | ||
30 | #define EXTENT_DIRTY 1 | ||
31 | #define EXTENT_WRITEBACK (1 << 1) | ||
32 | #define EXTENT_UPTODATE (1 << 2) | ||
33 | #define EXTENT_LOCKED (1 << 3) | ||
34 | #define EXTENT_NEW (1 << 4) | ||
35 | #define EXTENT_DELALLOC (1 << 5) | ||
36 | |||
37 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) | ||
38 | |||
39 | void __init extent_map_init(void) | 29 | void __init extent_map_init(void) |
40 | { | 30 | { |
41 | extent_map_cache = btrfs_cache_create("extent_map", | 31 | extent_map_cache = btrfs_cache_create("extent_map", |
@@ -223,7 +213,8 @@ int add_extent_mapping(struct extent_map_tree *tree, | |||
223 | if (rb) | 213 | if (rb) |
224 | prev = rb_entry(rb, struct extent_map, rb_node); | 214 | prev = rb_entry(rb, struct extent_map, rb_node); |
225 | if (prev && prev->end + 1 == em->start && | 215 | if (prev && prev->end + 1 == em->start && |
226 | ((em->block_start == 0 && prev->block_start == 0) || | 216 | ((em->block_start == EXTENT_MAP_HOLE && |
217 | prev->block_start == EXTENT_MAP_HOLE) || | ||
227 | (em->block_start == prev->block_end + 1))) { | 218 | (em->block_start == prev->block_end + 1))) { |
228 | em->start = prev->start; | 219 | em->start = prev->start; |
229 | em->block_start = prev->block_start; | 220 | em->block_start = prev->block_start; |
@@ -926,6 +917,40 @@ int set_range_writeback(struct extent_map_tree *tree, u64 start, u64 end) | |||
926 | } | 917 | } |
927 | EXPORT_SYMBOL(set_range_writeback); | 918 | EXPORT_SYMBOL(set_range_writeback); |
928 | 919 | ||
920 | int find_first_extent_bit(struct extent_map_tree *tree, u64 start, | ||
921 | u64 *start_ret, u64 *end_ret, int bits) | ||
922 | { | ||
923 | struct rb_node *node; | ||
924 | struct extent_state *state; | ||
925 | int ret = 1; | ||
926 | |||
927 | write_lock_irq(&tree->lock); | ||
928 | /* | ||
929 | * this search will find all the extents that end after | ||
930 | * our range starts. | ||
931 | */ | ||
932 | node = tree_search(&tree->state, start); | ||
933 | if (!node || IS_ERR(node)) { | ||
934 | goto out; | ||
935 | } | ||
936 | |||
937 | while(1) { | ||
938 | state = rb_entry(node, struct extent_state, rb_node); | ||
939 | if (state->state & bits) { | ||
940 | *start_ret = state->start; | ||
941 | *end_ret = state->end; | ||
942 | ret = 0; | ||
943 | } | ||
944 | node = rb_next(node); | ||
945 | if (!node) | ||
946 | break; | ||
947 | } | ||
948 | out: | ||
949 | write_unlock_irq(&tree->lock); | ||
950 | return ret; | ||
951 | } | ||
952 | EXPORT_SYMBOL(find_first_extent_bit); | ||
953 | |||
929 | u64 find_lock_delalloc_range(struct extent_map_tree *tree, | 954 | u64 find_lock_delalloc_range(struct extent_map_tree *tree, |
930 | u64 start, u64 lock_start, u64 *end, u64 max_bytes) | 955 | u64 start, u64 lock_start, u64 *end, u64 max_bytes) |
931 | { | 956 | { |
@@ -1450,7 +1475,7 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page, | |||
1450 | em = NULL; | 1475 | em = NULL; |
1451 | 1476 | ||
1452 | /* we've found a hole, just zero and go on */ | 1477 | /* we've found a hole, just zero and go on */ |
1453 | if (block_start == 0) { | 1478 | if (block_start == EXTENT_MAP_HOLE) { |
1454 | zero_user_page(page, page_offset, iosize, KM_USER0); | 1479 | zero_user_page(page, page_offset, iosize, KM_USER0); |
1455 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 1480 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
1456 | GFP_NOFS); | 1481 | GFP_NOFS); |
@@ -1593,7 +1618,8 @@ int extent_write_full_page(struct extent_map_tree *tree, struct page *page, | |||
1593 | free_extent_map(em); | 1618 | free_extent_map(em); |
1594 | em = NULL; | 1619 | em = NULL; |
1595 | 1620 | ||
1596 | if (block_start == 0 || block_start == EXTENT_MAP_INLINE) { | 1621 | if (block_start == EXTENT_MAP_HOLE || |
1622 | block_start == EXTENT_MAP_INLINE) { | ||
1597 | clear_extent_dirty(tree, cur, | 1623 | clear_extent_dirty(tree, cur, |
1598 | cur + iosize - 1, GFP_NOFS); | 1624 | cur + iosize - 1, GFP_NOFS); |
1599 | cur = cur + iosize; | 1625 | cur = cur + iosize; |
@@ -1630,7 +1656,6 @@ int extent_write_full_page(struct extent_map_tree *tree, struct page *page, | |||
1630 | nr++; | 1656 | nr++; |
1631 | } | 1657 | } |
1632 | done: | 1658 | done: |
1633 | WARN_ON(test_range_bit(tree, start, page_end, EXTENT_DIRTY, 0)); | ||
1634 | unlock_extent(tree, start, page_end, GFP_NOFS); | 1659 | unlock_extent(tree, start, page_end, GFP_NOFS); |
1635 | unlock_page(page); | 1660 | unlock_page(page); |
1636 | return 0; | 1661 | return 0; |
@@ -1827,8 +1852,623 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | |||
1827 | 1852 | ||
1828 | // XXX(hch): block 0 is valid in some cases, e.g. XFS RT device | 1853 | // XXX(hch): block 0 is valid in some cases, e.g. XFS RT device |
1829 | if (em->block_start == EXTENT_MAP_INLINE || | 1854 | if (em->block_start == EXTENT_MAP_INLINE || |
1830 | em->block_start == 0) | 1855 | em->block_start == EXTENT_MAP_HOLE) |
1831 | return 0; | 1856 | return 0; |
1832 | 1857 | ||
1833 | return (em->block_start + start - em->start) >> inode->i_blkbits; | 1858 | return (em->block_start + start - em->start) >> inode->i_blkbits; |
1834 | } | 1859 | } |
1860 | |||
1861 | struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | ||
1862 | u64 start, unsigned long len, | ||
1863 | gfp_t mask) | ||
1864 | { | ||
1865 | unsigned long num_pages = ((start + len - 1) >> PAGE_CACHE_SHIFT) - | ||
1866 | (start >> PAGE_CACHE_SHIFT) + 1; | ||
1867 | unsigned long i; | ||
1868 | unsigned long index = start >> PAGE_CACHE_SHIFT; | ||
1869 | struct extent_buffer *eb; | ||
1870 | struct page *p; | ||
1871 | struct address_space *mapping = tree->mapping; | ||
1872 | int uptodate = 0; | ||
1873 | |||
1874 | eb = kzalloc(EXTENT_BUFFER_SIZE(num_pages), mask); | ||
1875 | if (!eb || IS_ERR(eb)) | ||
1876 | return NULL; | ||
1877 | |||
1878 | eb->start = start; | ||
1879 | eb->len = len; | ||
1880 | atomic_set(&eb->refs, 1); | ||
1881 | |||
1882 | for (i = 0; i < num_pages; i++, index++) { | ||
1883 | p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM); | ||
1884 | if (!p) | ||
1885 | goto fail; | ||
1886 | eb->pages[i] = p; | ||
1887 | if (!PageUptodate(p)) | ||
1888 | uptodate = 0; | ||
1889 | unlock_page(p); | ||
1890 | } | ||
1891 | if (uptodate) | ||
1892 | eb->flags |= EXTENT_UPTODATE; | ||
1893 | return eb; | ||
1894 | fail: | ||
1895 | free_extent_buffer(eb); | ||
1896 | return NULL; | ||
1897 | } | ||
1898 | EXPORT_SYMBOL(alloc_extent_buffer); | ||
1899 | |||
1900 | struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | ||
1901 | u64 start, unsigned long len, | ||
1902 | gfp_t mask) | ||
1903 | { | ||
1904 | unsigned long num_pages = ((start + len - 1) >> PAGE_CACHE_SHIFT) - | ||
1905 | (start >> PAGE_CACHE_SHIFT) + 1; | ||
1906 | unsigned long i; | ||
1907 | unsigned long index = start >> PAGE_CACHE_SHIFT; | ||
1908 | struct extent_buffer *eb; | ||
1909 | struct page *p; | ||
1910 | struct address_space *mapping = tree->mapping; | ||
1911 | |||
1912 | eb = kzalloc(EXTENT_BUFFER_SIZE(num_pages), mask); | ||
1913 | if (!eb || IS_ERR(eb)) | ||
1914 | return NULL; | ||
1915 | |||
1916 | eb->start = start; | ||
1917 | eb->len = len; | ||
1918 | atomic_set(&eb->refs, 1); | ||
1919 | |||
1920 | for (i = 0; i < num_pages; i++, index++) { | ||
1921 | p = find_get_page(mapping, index); | ||
1922 | if (!p) | ||
1923 | goto fail; | ||
1924 | eb->pages[i] = p; | ||
1925 | } | ||
1926 | return eb; | ||
1927 | fail: | ||
1928 | free_extent_buffer(eb); | ||
1929 | return NULL; | ||
1930 | } | ||
1931 | EXPORT_SYMBOL(find_extent_buffer); | ||
1932 | |||
1933 | void free_extent_buffer(struct extent_buffer *eb) | ||
1934 | { | ||
1935 | unsigned long i; | ||
1936 | unsigned long num_pages; | ||
1937 | |||
1938 | if (!eb) | ||
1939 | return; | ||
1940 | |||
1941 | if (!atomic_dec_and_test(&eb->refs)) | ||
1942 | return; | ||
1943 | |||
1944 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | ||
1945 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
1946 | |||
1947 | for (i = 0; i < num_pages; i++) { | ||
1948 | if (eb->pages[i]) | ||
1949 | page_cache_release(eb->pages[i]); | ||
1950 | } | ||
1951 | kfree(eb); | ||
1952 | } | ||
1953 | EXPORT_SYMBOL(free_extent_buffer); | ||
1954 | |||
1955 | int clear_extent_buffer_dirty(struct extent_map_tree *tree, | ||
1956 | struct extent_buffer *eb) | ||
1957 | { | ||
1958 | int set; | ||
1959 | unsigned long i; | ||
1960 | unsigned long num_pages; | ||
1961 | struct page *page; | ||
1962 | |||
1963 | u64 start = eb->start; | ||
1964 | u64 end = start + eb->len - 1; | ||
1965 | |||
1966 | set = clear_extent_dirty(tree, start, end, GFP_NOFS); | ||
1967 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | ||
1968 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
1969 | |||
1970 | for (i = 0; i < num_pages; i++) { | ||
1971 | page = eb->pages[i]; | ||
1972 | lock_page(page); | ||
1973 | /* | ||
1974 | * if we're on the last page or the first page and the | ||
1975 | * block isn't aligned on a page boundary, do extra checks | ||
1976 | * to make sure we don't clean page that is partially dirty | ||
1977 | */ | ||
1978 | if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || | ||
1979 | ((i == num_pages - 1) && | ||
1980 | ((eb->start + eb->len - 1) & (PAGE_CACHE_SIZE - 1)))) { | ||
1981 | start = page->index << PAGE_CACHE_SHIFT; | ||
1982 | end = start + PAGE_CACHE_SIZE - 1; | ||
1983 | if (test_range_bit(tree, start, end, | ||
1984 | EXTENT_DIRTY, 0)) { | ||
1985 | unlock_page(page); | ||
1986 | continue; | ||
1987 | } | ||
1988 | } | ||
1989 | clear_page_dirty_for_io(page); | ||
1990 | unlock_page(page); | ||
1991 | } | ||
1992 | return 0; | ||
1993 | } | ||
1994 | EXPORT_SYMBOL(clear_extent_buffer_dirty); | ||
1995 | |||
1996 | int wait_on_extent_buffer_writeback(struct extent_map_tree *tree, | ||
1997 | struct extent_buffer *eb) | ||
1998 | { | ||
1999 | return wait_on_extent_writeback(tree, eb->start, | ||
2000 | eb->start + eb->len - 1); | ||
2001 | } | ||
2002 | EXPORT_SYMBOL(wait_on_extent_buffer_writeback); | ||
2003 | |||
2004 | int set_extent_buffer_dirty(struct extent_map_tree *tree, | ||
2005 | struct extent_buffer *eb) | ||
2006 | { | ||
2007 | return set_range_dirty(tree, eb->start, eb->start + eb->len - 1); | ||
2008 | } | ||
2009 | EXPORT_SYMBOL(set_extent_buffer_dirty); | ||
2010 | |||
2011 | int set_extent_buffer_uptodate(struct extent_map_tree *tree, | ||
2012 | struct extent_buffer *eb) | ||
2013 | { | ||
2014 | unsigned long i; | ||
2015 | struct page *page; | ||
2016 | unsigned long num_pages; | ||
2017 | |||
2018 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | ||
2019 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
2020 | |||
2021 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | ||
2022 | GFP_NOFS); | ||
2023 | for (i = 0; i < num_pages; i++) { | ||
2024 | page = eb->pages[i]; | ||
2025 | if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || | ||
2026 | ((i == num_pages - 1) && | ||
2027 | ((eb->start + eb->len - 1) & (PAGE_CACHE_SIZE - 1)))) { | ||
2028 | check_page_uptodate(tree, page); | ||
2029 | continue; | ||
2030 | } | ||
2031 | SetPageUptodate(page); | ||
2032 | } | ||
2033 | return 0; | ||
2034 | } | ||
2035 | EXPORT_SYMBOL(set_extent_buffer_uptodate); | ||
2036 | |||
2037 | int extent_buffer_uptodate(struct extent_map_tree *tree, | ||
2038 | struct extent_buffer *eb) | ||
2039 | { | ||
2040 | if (eb->flags & EXTENT_UPTODATE) | ||
2041 | return 1; | ||
2042 | return test_range_bit(tree, eb->start, eb->start + eb->len - 1, | ||
2043 | EXTENT_UPTODATE, 1); | ||
2044 | } | ||
2045 | EXPORT_SYMBOL(extent_buffer_uptodate); | ||
2046 | |||
2047 | int read_extent_buffer_pages(struct extent_map_tree *tree, | ||
2048 | struct extent_buffer *eb, int wait) | ||
2049 | { | ||
2050 | unsigned long i; | ||
2051 | struct page *page; | ||
2052 | int err; | ||
2053 | int ret = 0; | ||
2054 | unsigned long num_pages; | ||
2055 | |||
2056 | if (eb->flags & EXTENT_UPTODATE) | ||
2057 | return 0; | ||
2058 | |||
2059 | if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, | ||
2060 | EXTENT_UPTODATE, 1)) { | ||
2061 | return 0; | ||
2062 | } | ||
2063 | |||
2064 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | ||
2065 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
2066 | for (i = 0; i < num_pages; i++) { | ||
2067 | page = eb->pages[i]; | ||
2068 | if (PageUptodate(page)) { | ||
2069 | continue; | ||
2070 | } | ||
2071 | if (!wait) { | ||
2072 | if (TestSetPageLocked(page)) { | ||
2073 | continue; | ||
2074 | } | ||
2075 | } else { | ||
2076 | lock_page(page); | ||
2077 | } | ||
2078 | if (!PageUptodate(page)) { | ||
2079 | err = page->mapping->a_ops->readpage(NULL, page); | ||
2080 | if (err) { | ||
2081 | ret = err; | ||
2082 | } | ||
2083 | } else { | ||
2084 | unlock_page(page); | ||
2085 | } | ||
2086 | } | ||
2087 | |||
2088 | if (ret || !wait) { | ||
2089 | return ret; | ||
2090 | } | ||
2091 | |||
2092 | for (i = 0; i < num_pages; i++) { | ||
2093 | page = eb->pages[i]; | ||
2094 | wait_on_page_locked(page); | ||
2095 | if (!PageUptodate(page)) { | ||
2096 | ret = -EIO; | ||
2097 | } | ||
2098 | } | ||
2099 | eb->flags |= EXTENT_UPTODATE; | ||
2100 | return ret; | ||
2101 | } | ||
2102 | EXPORT_SYMBOL(read_extent_buffer_pages); | ||
2103 | |||
2104 | void read_extent_buffer(struct extent_buffer *eb, void *dstv, | ||
2105 | unsigned long start, | ||
2106 | unsigned long len) | ||
2107 | { | ||
2108 | size_t cur; | ||
2109 | size_t offset; | ||
2110 | struct page *page; | ||
2111 | char *kaddr; | ||
2112 | char *dst = (char *)dstv; | ||
2113 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2114 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
2115 | |||
2116 | WARN_ON(start > eb->len); | ||
2117 | WARN_ON(start + len > eb->start + eb->len); | ||
2118 | |||
2119 | page = eb->pages[i]; | ||
2120 | offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2121 | if (i == 0) | ||
2122 | offset += start_offset; | ||
2123 | |||
2124 | while(len > 0) { | ||
2125 | WARN_ON(!PageUptodate(page)); | ||
2126 | |||
2127 | cur = min(len, (PAGE_CACHE_SIZE - offset)); | ||
2128 | // kaddr = kmap_atomic(page, KM_USER0); | ||
2129 | kaddr = page_address(page); | ||
2130 | memcpy(dst, kaddr + offset, cur); | ||
2131 | // kunmap_atomic(kaddr, KM_USER0); | ||
2132 | |||
2133 | dst += cur; | ||
2134 | len -= cur; | ||
2135 | offset = 0; | ||
2136 | i++; | ||
2137 | page = eb->pages[i]; | ||
2138 | } | ||
2139 | } | ||
2140 | EXPORT_SYMBOL(read_extent_buffer); | ||
2141 | |||
2142 | int map_extent_buffer(struct extent_buffer *eb, unsigned long start, | ||
2143 | char **token, char **map, | ||
2144 | unsigned long *map_start, | ||
2145 | unsigned long *map_len, int km) | ||
2146 | { | ||
2147 | size_t offset; | ||
2148 | char *kaddr; | ||
2149 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2150 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
2151 | |||
2152 | WARN_ON(start > eb->len); | ||
2153 | |||
2154 | if (i == 0) { | ||
2155 | offset = start_offset; | ||
2156 | *map_start = 0; | ||
2157 | } else { | ||
2158 | offset = 0; | ||
2159 | *map_start = (i << PAGE_CACHE_SHIFT) - offset; | ||
2160 | } | ||
2161 | |||
2162 | // kaddr = kmap_atomic(eb->pages[i], km); | ||
2163 | kaddr = page_address(eb->pages[i]); | ||
2164 | *token = kaddr; | ||
2165 | *map = kaddr + offset; | ||
2166 | *map_len = PAGE_CACHE_SIZE - offset; | ||
2167 | return 0; | ||
2168 | } | ||
2169 | EXPORT_SYMBOL(map_extent_buffer); | ||
2170 | |||
2171 | void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km) | ||
2172 | { | ||
2173 | // kunmap_atomic(token, km); | ||
2174 | } | ||
2175 | EXPORT_SYMBOL(unmap_extent_buffer); | ||
2176 | |||
2177 | int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, | ||
2178 | unsigned long start, | ||
2179 | unsigned long len) | ||
2180 | { | ||
2181 | size_t cur; | ||
2182 | size_t offset; | ||
2183 | struct page *page; | ||
2184 | char *kaddr; | ||
2185 | char *ptr = (char *)ptrv; | ||
2186 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2187 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
2188 | int ret = 0; | ||
2189 | |||
2190 | WARN_ON(start > eb->len); | ||
2191 | WARN_ON(start + len > eb->start + eb->len); | ||
2192 | |||
2193 | page = eb->pages[i]; | ||
2194 | offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2195 | if (i == 0) | ||
2196 | offset += start_offset; | ||
2197 | |||
2198 | while(len > 0) { | ||
2199 | WARN_ON(!PageUptodate(page)); | ||
2200 | |||
2201 | cur = min(len, (PAGE_CACHE_SIZE - offset)); | ||
2202 | |||
2203 | // kaddr = kmap_atomic(page, KM_USER0); | ||
2204 | kaddr = page_address(page); | ||
2205 | ret = memcmp(ptr, kaddr + offset, cur); | ||
2206 | // kunmap_atomic(kaddr, KM_USER0); | ||
2207 | if (ret) | ||
2208 | break; | ||
2209 | |||
2210 | ptr += cur; | ||
2211 | len -= cur; | ||
2212 | offset = 0; | ||
2213 | i++; | ||
2214 | page = eb->pages[i]; | ||
2215 | } | ||
2216 | return ret; | ||
2217 | } | ||
2218 | EXPORT_SYMBOL(memcmp_extent_buffer); | ||
2219 | |||
2220 | void write_extent_buffer(struct extent_buffer *eb, const void *srcv, | ||
2221 | unsigned long start, unsigned long len) | ||
2222 | { | ||
2223 | size_t cur; | ||
2224 | size_t offset; | ||
2225 | struct page *page; | ||
2226 | char *kaddr; | ||
2227 | char *src = (char *)srcv; | ||
2228 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2229 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
2230 | |||
2231 | WARN_ON(start > eb->len); | ||
2232 | WARN_ON(start + len > eb->start + eb->len); | ||
2233 | |||
2234 | page = eb->pages[i]; | ||
2235 | offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2236 | if (i == 0) | ||
2237 | offset += start_offset; | ||
2238 | |||
2239 | while(len > 0) { | ||
2240 | WARN_ON(!PageUptodate(page)); | ||
2241 | |||
2242 | cur = min(len, PAGE_CACHE_SIZE - offset); | ||
2243 | // kaddr = kmap_atomic(page, KM_USER0); | ||
2244 | kaddr = page_address(page); | ||
2245 | memcpy(kaddr + offset, src, cur); | ||
2246 | // kunmap_atomic(kaddr, KM_USER0); | ||
2247 | |||
2248 | src += cur; | ||
2249 | len -= cur; | ||
2250 | offset = 0; | ||
2251 | i++; | ||
2252 | page = eb->pages[i]; | ||
2253 | } | ||
2254 | } | ||
2255 | EXPORT_SYMBOL(write_extent_buffer); | ||
2256 | |||
2257 | void memset_extent_buffer(struct extent_buffer *eb, char c, | ||
2258 | unsigned long start, unsigned long len) | ||
2259 | { | ||
2260 | size_t cur; | ||
2261 | size_t offset; | ||
2262 | struct page *page; | ||
2263 | char *kaddr; | ||
2264 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2265 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
2266 | |||
2267 | WARN_ON(start > eb->len); | ||
2268 | WARN_ON(start + len > eb->start + eb->len); | ||
2269 | |||
2270 | page = eb->pages[i]; | ||
2271 | offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2272 | if (i == 0) | ||
2273 | offset += start_offset; | ||
2274 | |||
2275 | while(len > 0) { | ||
2276 | WARN_ON(!PageUptodate(page)); | ||
2277 | |||
2278 | cur = min(len, PAGE_CACHE_SIZE - offset); | ||
2279 | // kaddr = kmap_atomic(page, KM_USER0); | ||
2280 | kaddr = page_address(page); | ||
2281 | memset(kaddr + offset, c, cur); | ||
2282 | // kunmap_atomic(kaddr, KM_USER0); | ||
2283 | |||
2284 | len -= cur; | ||
2285 | offset = 0; | ||
2286 | i++; | ||
2287 | page = eb->pages[i]; | ||
2288 | } | ||
2289 | } | ||
2290 | EXPORT_SYMBOL(memset_extent_buffer); | ||
2291 | |||
2292 | void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, | ||
2293 | unsigned long dst_offset, unsigned long src_offset, | ||
2294 | unsigned long len) | ||
2295 | { | ||
2296 | u64 dst_len = dst->len; | ||
2297 | size_t cur; | ||
2298 | size_t offset; | ||
2299 | struct page *page; | ||
2300 | char *kaddr; | ||
2301 | size_t start_offset = dst->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2302 | unsigned long i = (start_offset + dst_offset) >> PAGE_CACHE_SHIFT; | ||
2303 | |||
2304 | WARN_ON(src->len != dst_len); | ||
2305 | |||
2306 | offset = dst_offset & ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2307 | if (i == 0) | ||
2308 | offset += start_offset; | ||
2309 | |||
2310 | while(len > 0) { | ||
2311 | page = dst->pages[i]; | ||
2312 | WARN_ON(!PageUptodate(page)); | ||
2313 | |||
2314 | cur = min(len, (unsigned long)(PAGE_CACHE_SIZE - offset)); | ||
2315 | |||
2316 | // kaddr = kmap_atomic(page, KM_USER1); | ||
2317 | kaddr = page_address(page); | ||
2318 | read_extent_buffer(src, kaddr + offset, src_offset, cur); | ||
2319 | // kunmap_atomic(kaddr, KM_USER1); | ||
2320 | |||
2321 | src_offset += cur; | ||
2322 | len -= cur; | ||
2323 | offset = 0; | ||
2324 | i++; | ||
2325 | } | ||
2326 | } | ||
2327 | EXPORT_SYMBOL(copy_extent_buffer); | ||
2328 | |||
2329 | static void move_pages(struct page *dst_page, struct page *src_page, | ||
2330 | unsigned long dst_off, unsigned long src_off, | ||
2331 | unsigned long len) | ||
2332 | { | ||
2333 | // char *dst_kaddr = kmap_atomic(dst_page, KM_USER0); | ||
2334 | char *dst_kaddr = page_address(dst_page); | ||
2335 | if (dst_page == src_page) { | ||
2336 | memmove(dst_kaddr + dst_off, dst_kaddr + src_off, len); | ||
2337 | } else { | ||
2338 | // char *src_kaddr = kmap_atomic(src_page, KM_USER1); | ||
2339 | char *src_kaddr = page_address(src_page); | ||
2340 | char *p = dst_kaddr + dst_off + len; | ||
2341 | char *s = src_kaddr + src_off + len; | ||
2342 | |||
2343 | while (len--) | ||
2344 | *--p = *--s; | ||
2345 | |||
2346 | // kunmap_atomic(src_kaddr, KM_USER1); | ||
2347 | } | ||
2348 | // kunmap_atomic(dst_kaddr, KM_USER0); | ||
2349 | } | ||
2350 | |||
2351 | static void copy_pages(struct page *dst_page, struct page *src_page, | ||
2352 | unsigned long dst_off, unsigned long src_off, | ||
2353 | unsigned long len) | ||
2354 | { | ||
2355 | //kmap_atomic(dst_page, KM_USER0); | ||
2356 | char *dst_kaddr = page_address(dst_page); | ||
2357 | char *src_kaddr; | ||
2358 | |||
2359 | if (dst_page != src_page) | ||
2360 | src_kaddr = page_address(src_page); // kmap_atomic(src_page, KM_USER1); | ||
2361 | else | ||
2362 | src_kaddr = dst_kaddr; | ||
2363 | |||
2364 | memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); | ||
2365 | /* | ||
2366 | kunmap_atomic(dst_kaddr, KM_USER0); | ||
2367 | if (dst_page != src_page) | ||
2368 | kunmap_atomic(src_kaddr, KM_USER1); | ||
2369 | */ | ||
2370 | } | ||
2371 | |||
2372 | void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | ||
2373 | unsigned long src_offset, unsigned long len) | ||
2374 | { | ||
2375 | size_t cur; | ||
2376 | size_t dst_off_in_page; | ||
2377 | size_t src_off_in_page; | ||
2378 | size_t start_offset = dst->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2379 | unsigned long dst_i; | ||
2380 | unsigned long src_i; | ||
2381 | |||
2382 | if (src_offset + len > dst->len) { | ||
2383 | printk("memmove bogus src_offset %lu move len %lu len %lu\n", | ||
2384 | src_offset, len, dst->len); | ||
2385 | BUG_ON(1); | ||
2386 | } | ||
2387 | if (dst_offset + len > dst->len) { | ||
2388 | printk("memmove bogus dst_offset %lu move len %lu len %lu\n", | ||
2389 | dst_offset, len, dst->len); | ||
2390 | BUG_ON(1); | ||
2391 | } | ||
2392 | |||
2393 | while(len > 0) { | ||
2394 | dst_off_in_page = dst_offset & | ||
2395 | ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2396 | src_off_in_page = src_offset & | ||
2397 | ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2398 | |||
2399 | dst_i = (start_offset + dst_offset) >> PAGE_CACHE_SHIFT; | ||
2400 | src_i = (start_offset + src_offset) >> PAGE_CACHE_SHIFT; | ||
2401 | |||
2402 | if (src_i == 0) | ||
2403 | src_off_in_page += start_offset; | ||
2404 | if (dst_i == 0) | ||
2405 | dst_off_in_page += start_offset; | ||
2406 | |||
2407 | cur = min(len, (unsigned long)(PAGE_CACHE_SIZE - | ||
2408 | src_off_in_page)); | ||
2409 | cur = min(cur, (unsigned long)(PAGE_CACHE_SIZE - | ||
2410 | dst_off_in_page)); | ||
2411 | |||
2412 | copy_pages(dst->pages[dst_i], dst->pages[src_i], | ||
2413 | dst_off_in_page, src_off_in_page, cur); | ||
2414 | |||
2415 | src_offset += cur; | ||
2416 | dst_offset += cur; | ||
2417 | len -= cur; | ||
2418 | } | ||
2419 | } | ||
2420 | EXPORT_SYMBOL(memcpy_extent_buffer); | ||
2421 | |||
2422 | void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | ||
2423 | unsigned long src_offset, unsigned long len) | ||
2424 | { | ||
2425 | size_t cur; | ||
2426 | size_t dst_off_in_page; | ||
2427 | size_t src_off_in_page; | ||
2428 | unsigned long dst_end = dst_offset + len - 1; | ||
2429 | unsigned long src_end = src_offset + len - 1; | ||
2430 | size_t start_offset = dst->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
2431 | unsigned long dst_i; | ||
2432 | unsigned long src_i; | ||
2433 | |||
2434 | if (src_offset + len > dst->len) { | ||
2435 | printk("memmove bogus src_offset %lu move len %lu len %lu\n", | ||
2436 | src_offset, len, dst->len); | ||
2437 | BUG_ON(1); | ||
2438 | } | ||
2439 | if (dst_offset + len > dst->len) { | ||
2440 | printk("memmove bogus dst_offset %lu move len %lu len %lu\n", | ||
2441 | dst_offset, len, dst->len); | ||
2442 | BUG_ON(1); | ||
2443 | } | ||
2444 | if (dst_offset < src_offset) { | ||
2445 | memcpy_extent_buffer(dst, dst_offset, src_offset, len); | ||
2446 | return; | ||
2447 | } | ||
2448 | while(len > 0) { | ||
2449 | dst_i = (start_offset + dst_end) >> PAGE_CACHE_SHIFT; | ||
2450 | src_i = (start_offset + src_end) >> PAGE_CACHE_SHIFT; | ||
2451 | |||
2452 | dst_off_in_page = dst_end & | ||
2453 | ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2454 | src_off_in_page = src_end & | ||
2455 | ((unsigned long)PAGE_CACHE_SIZE - 1); | ||
2456 | |||
2457 | if (src_i == 0) | ||
2458 | src_off_in_page += start_offset; | ||
2459 | if (dst_i == 0) | ||
2460 | dst_off_in_page += start_offset; | ||
2461 | |||
2462 | cur = min(len, src_off_in_page + 1); | ||
2463 | cur = min(cur, dst_off_in_page + 1); | ||
2464 | // printk("move pages orig dst %lu src %lu len %lu, this %lu %lu %lu\n", dst_offset, src_offset, len, dst_off_in_page - cur + 1, src_off_in_page - cur + 1, cur); | ||
2465 | move_pages(dst->pages[dst_i], dst->pages[src_i], | ||
2466 | dst_off_in_page - cur + 1, | ||
2467 | src_off_in_page - cur + 1, cur); | ||
2468 | |||
2469 | dst_end -= cur - 1; | ||
2470 | src_end -= cur - 1; | ||
2471 | len -= cur; | ||
2472 | } | ||
2473 | } | ||
2474 | EXPORT_SYMBOL(memmove_extent_buffer); | ||
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index d913ce01248d..430b997a70f6 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -3,9 +3,20 @@ | |||
3 | 3 | ||
4 | #include <linux/rbtree.h> | 4 | #include <linux/rbtree.h> |
5 | 5 | ||
6 | #define EXTENT_MAP_HOLE (u64)-3 | ||
6 | #define EXTENT_MAP_INLINE (u64)-2 | 7 | #define EXTENT_MAP_INLINE (u64)-2 |
7 | #define EXTENT_MAP_DELALLOC (u64)-1 | 8 | #define EXTENT_MAP_DELALLOC (u64)-1 |
8 | 9 | ||
10 | /* bits for the extent state */ | ||
11 | #define EXTENT_DIRTY 1 | ||
12 | #define EXTENT_WRITEBACK (1 << 1) | ||
13 | #define EXTENT_UPTODATE (1 << 2) | ||
14 | #define EXTENT_LOCKED (1 << 3) | ||
15 | #define EXTENT_NEW (1 << 4) | ||
16 | #define EXTENT_DELALLOC (1 << 5) | ||
17 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) | ||
18 | |||
19 | |||
9 | struct extent_map_ops { | 20 | struct extent_map_ops { |
10 | int (*fill_delalloc)(struct inode *inode, u64 start, u64 end); | 21 | int (*fill_delalloc)(struct inode *inode, u64 start, u64 end); |
11 | int (*writepage_io_hook)(struct page *page, u64 start, u64 end); | 22 | int (*writepage_io_hook)(struct page *page, u64 start, u64 end); |
@@ -51,10 +62,13 @@ struct extent_state { | |||
51 | struct list_head list; | 62 | struct list_head list; |
52 | }; | 63 | }; |
53 | 64 | ||
65 | #define EXTENT_BUFFER_SIZE(nr) (sizeof(struct extent_buffer) + \ | ||
66 | (nr - 1) * sizeof(struct page *)) | ||
54 | struct extent_buffer { | 67 | struct extent_buffer { |
55 | u64 start; | 68 | u64 start; |
56 | u64 end; /* inclusive */ | 69 | unsigned long len; |
57 | char *addr; | 70 | atomic_t refs; |
71 | int flags; | ||
58 | struct page *pages[]; | 72 | struct page *pages[]; |
59 | }; | 73 | }; |
60 | 74 | ||
@@ -87,8 +101,12 @@ int set_extent_new(struct extent_map_tree *tree, u64 start, u64 end, | |||
87 | gfp_t mask); | 101 | gfp_t mask); |
88 | int set_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end, | 102 | int set_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end, |
89 | gfp_t mask); | 103 | gfp_t mask); |
104 | int clear_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end, | ||
105 | gfp_t mask); | ||
90 | int set_extent_delalloc(struct extent_map_tree *tree, u64 start, u64 end, | 106 | int set_extent_delalloc(struct extent_map_tree *tree, u64 start, u64 end, |
91 | gfp_t mask); | 107 | gfp_t mask); |
108 | int find_first_extent_bit(struct extent_map_tree *tree, u64 start, | ||
109 | u64 *start_ret, u64 *end_ret, int bits); | ||
92 | int extent_invalidatepage(struct extent_map_tree *tree, | 110 | int extent_invalidatepage(struct extent_map_tree *tree, |
93 | struct page *page, unsigned long offset); | 111 | struct page *page, unsigned long offset); |
94 | int extent_write_full_page(struct extent_map_tree *tree, struct page *page, | 112 | int extent_write_full_page(struct extent_map_tree *tree, struct page *page, |
@@ -106,4 +124,57 @@ int set_range_dirty(struct extent_map_tree *tree, u64 start, u64 end); | |||
106 | int set_state_private(struct extent_map_tree *tree, u64 start, u64 private); | 124 | int set_state_private(struct extent_map_tree *tree, u64 start, u64 private); |
107 | int get_state_private(struct extent_map_tree *tree, u64 start, u64 *private); | 125 | int get_state_private(struct extent_map_tree *tree, u64 start, u64 *private); |
108 | void set_page_extent_mapped(struct page *page); | 126 | void set_page_extent_mapped(struct page *page); |
127 | |||
128 | struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | ||
129 | u64 start, unsigned long len, | ||
130 | gfp_t mask); | ||
131 | struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | ||
132 | u64 start, unsigned long len, | ||
133 | gfp_t mask); | ||
134 | void free_extent_buffer(struct extent_buffer *eb); | ||
135 | int read_extent_buffer_pages(struct extent_map_tree *tree, | ||
136 | struct extent_buffer *eb, int wait); | ||
137 | |||
138 | static inline void extent_buffer_get(struct extent_buffer *eb) | ||
139 | { | ||
140 | atomic_inc(&eb->refs); | ||
141 | } | ||
142 | |||
143 | static inline u64 extent_buffer_blocknr(struct extent_buffer *eb) | ||
144 | { | ||
145 | return eb->start / 4096; | ||
146 | } | ||
147 | |||
148 | int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, | ||
149 | unsigned long start, | ||
150 | unsigned long len); | ||
151 | void read_extent_buffer(struct extent_buffer *eb, void *dst, | ||
152 | unsigned long start, | ||
153 | unsigned long len); | ||
154 | void write_extent_buffer(struct extent_buffer *eb, const void *src, | ||
155 | unsigned long start, unsigned long len); | ||
156 | void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, | ||
157 | unsigned long dst_offset, unsigned long src_offset, | ||
158 | unsigned long len); | ||
159 | void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | ||
160 | unsigned long src_offset, unsigned long len); | ||
161 | void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | ||
162 | unsigned long src_offset, unsigned long len); | ||
163 | void memset_extent_buffer(struct extent_buffer *eb, char c, | ||
164 | unsigned long start, unsigned long len); | ||
165 | int wait_on_extent_buffer_writeback(struct extent_map_tree *tree, | ||
166 | struct extent_buffer *eb); | ||
167 | int clear_extent_buffer_dirty(struct extent_map_tree *tree, | ||
168 | struct extent_buffer *eb); | ||
169 | int set_extent_buffer_dirty(struct extent_map_tree *tree, | ||
170 | struct extent_buffer *eb); | ||
171 | int set_extent_buffer_uptodate(struct extent_map_tree *tree, | ||
172 | struct extent_buffer *eb); | ||
173 | int extent_buffer_uptodate(struct extent_map_tree *tree, | ||
174 | struct extent_buffer *eb); | ||
175 | int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, | ||
176 | char **token, char **map, | ||
177 | unsigned long *map_start, | ||
178 | unsigned long *map_len, int km); | ||
179 | void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km); | ||
109 | #endif | 180 | #endif |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index ea4dd4c5fce3..226f6d028c3f 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -34,12 +34,12 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | |||
34 | struct btrfs_file_extent_item *item; | 34 | struct btrfs_file_extent_item *item; |
35 | struct btrfs_key file_key; | 35 | struct btrfs_key file_key; |
36 | struct btrfs_path *path; | 36 | struct btrfs_path *path; |
37 | struct extent_buffer *leaf; | ||
37 | 38 | ||
38 | path = btrfs_alloc_path(); | 39 | path = btrfs_alloc_path(); |
39 | BUG_ON(!path); | 40 | BUG_ON(!path); |
40 | file_key.objectid = objectid; | 41 | file_key.objectid = objectid; |
41 | file_key.offset = pos; | 42 | file_key.offset = pos; |
42 | file_key.flags = 0; | ||
43 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); | 43 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); |
44 | 44 | ||
45 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, | 45 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
@@ -47,15 +47,16 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | |||
47 | if (ret < 0) | 47 | if (ret < 0) |
48 | goto out; | 48 | goto out; |
49 | BUG_ON(ret); | 49 | BUG_ON(ret); |
50 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], | 50 | leaf = path->nodes[0]; |
51 | item = btrfs_item_ptr(leaf, path->slots[0], | ||
51 | struct btrfs_file_extent_item); | 52 | struct btrfs_file_extent_item); |
52 | btrfs_set_file_extent_disk_blocknr(item, offset); | 53 | btrfs_set_file_extent_disk_blocknr(leaf, item, offset); |
53 | btrfs_set_file_extent_disk_num_blocks(item, disk_num_blocks); | 54 | btrfs_set_file_extent_disk_num_blocks(leaf, item, disk_num_blocks); |
54 | btrfs_set_file_extent_offset(item, 0); | 55 | btrfs_set_file_extent_offset(leaf, item, 0); |
55 | btrfs_set_file_extent_num_blocks(item, num_blocks); | 56 | btrfs_set_file_extent_num_blocks(leaf, item, num_blocks); |
56 | btrfs_set_file_extent_generation(item, trans->transid); | 57 | btrfs_set_file_extent_generation(leaf, item, trans->transid); |
57 | btrfs_set_file_extent_type(item, BTRFS_FILE_EXTENT_REG); | 58 | btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG); |
58 | btrfs_mark_buffer_dirty(path->nodes[0]); | 59 | btrfs_mark_buffer_dirty(leaf); |
59 | out: | 60 | out: |
60 | btrfs_free_path(path); | 61 | btrfs_free_path(path); |
61 | return ret; | 62 | return ret; |
@@ -71,32 +72,30 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
71 | struct btrfs_key file_key; | 72 | struct btrfs_key file_key; |
72 | struct btrfs_key found_key; | 73 | struct btrfs_key found_key; |
73 | struct btrfs_csum_item *item; | 74 | struct btrfs_csum_item *item; |
74 | struct btrfs_leaf *leaf; | 75 | struct extent_buffer *leaf; |
75 | u64 csum_offset = 0; | 76 | u64 csum_offset = 0; |
76 | int csums_in_item; | 77 | int csums_in_item; |
77 | 78 | ||
78 | file_key.objectid = objectid; | 79 | file_key.objectid = objectid; |
79 | file_key.offset = offset; | 80 | file_key.offset = offset; |
80 | file_key.flags = 0; | ||
81 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); | 81 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); |
82 | ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow); | 82 | ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow); |
83 | if (ret < 0) | 83 | if (ret < 0) |
84 | goto fail; | 84 | goto fail; |
85 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 85 | leaf = path->nodes[0]; |
86 | if (ret > 0) { | 86 | if (ret > 0) { |
87 | ret = 1; | 87 | ret = 1; |
88 | if (path->slots[0] == 0) | 88 | if (path->slots[0] == 0) |
89 | goto fail; | 89 | goto fail; |
90 | path->slots[0]--; | 90 | path->slots[0]--; |
91 | btrfs_disk_key_to_cpu(&found_key, | 91 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
92 | &leaf->items[path->slots[0]].key); | ||
93 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || | 92 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || |
94 | found_key.objectid != objectid) { | 93 | found_key.objectid != objectid) { |
95 | goto fail; | 94 | goto fail; |
96 | } | 95 | } |
97 | csum_offset = (offset - found_key.offset) >> | 96 | csum_offset = (offset - found_key.offset) >> |
98 | root->fs_info->sb->s_blocksize_bits; | 97 | root->fs_info->sb->s_blocksize_bits; |
99 | csums_in_item = btrfs_item_size(leaf->items + path->slots[0]); | 98 | csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]); |
100 | csums_in_item /= BTRFS_CRC32_SIZE; | 99 | csums_in_item /= BTRFS_CRC32_SIZE; |
101 | 100 | ||
102 | if (csum_offset >= csums_in_item) { | 101 | if (csum_offset >= csums_in_item) { |
@@ -127,7 +126,6 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, | |||
127 | 126 | ||
128 | file_key.objectid = objectid; | 127 | file_key.objectid = objectid; |
129 | file_key.offset = offset; | 128 | file_key.offset = offset; |
130 | file_key.flags = 0; | ||
131 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); | 129 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); |
132 | ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow); | 130 | ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow); |
133 | return ret; | 131 | return ret; |
@@ -138,12 +136,14 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
138 | u64 objectid, u64 offset, | 136 | u64 objectid, u64 offset, |
139 | char *data, size_t len) | 137 | char *data, size_t len) |
140 | { | 138 | { |
139 | return 0; | ||
140 | #if 0 | ||
141 | int ret; | 141 | int ret; |
142 | struct btrfs_key file_key; | 142 | struct btrfs_key file_key; |
143 | struct btrfs_key found_key; | 143 | struct btrfs_key found_key; |
144 | struct btrfs_path *path; | 144 | struct btrfs_path *path; |
145 | struct btrfs_csum_item *item; | 145 | struct btrfs_csum_item *item; |
146 | struct btrfs_leaf *leaf; | 146 | struct extent_buffer *leaf; |
147 | u64 csum_offset; | 147 | u64 csum_offset; |
148 | 148 | ||
149 | path = btrfs_alloc_path(); | 149 | path = btrfs_alloc_path(); |
@@ -161,8 +161,8 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
161 | if (ret == -EFBIG) { | 161 | if (ret == -EFBIG) { |
162 | u32 item_size; | 162 | u32 item_size; |
163 | /* we found one, but it isn't big enough yet */ | 163 | /* we found one, but it isn't big enough yet */ |
164 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 164 | leaf = path->nodes[0]; |
165 | item_size = btrfs_item_size(leaf->items + path->slots[0]); | 165 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
166 | if ((item_size / BTRFS_CRC32_SIZE) >= MAX_CSUM_ITEMS(root)) { | 166 | if ((item_size / BTRFS_CRC32_SIZE) >= MAX_CSUM_ITEMS(root)) { |
167 | /* already at max size, make a new one */ | 167 | /* already at max size, make a new one */ |
168 | goto insert; | 168 | goto insert; |
@@ -188,8 +188,8 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
188 | goto insert; | 188 | goto insert; |
189 | } | 189 | } |
190 | path->slots[0]--; | 190 | path->slots[0]--; |
191 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 191 | leaf = path->nodes[0]; |
192 | btrfs_disk_key_to_cpu(&found_key, &leaf->items[path->slots[0]].key); | 192 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
193 | csum_offset = (offset - found_key.offset) >> | 193 | csum_offset = (offset - found_key.offset) >> |
194 | root->fs_info->sb->s_blocksize_bits; | 194 | root->fs_info->sb->s_blocksize_bits; |
195 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || | 195 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || |
@@ -197,10 +197,10 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
197 | csum_offset >= MAX_CSUM_ITEMS(root)) { | 197 | csum_offset >= MAX_CSUM_ITEMS(root)) { |
198 | goto insert; | 198 | goto insert; |
199 | } | 199 | } |
200 | if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) / | 200 | if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) / |
201 | BTRFS_CRC32_SIZE) { | 201 | BTRFS_CRC32_SIZE) { |
202 | u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE; | 202 | u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE; |
203 | diff = diff - btrfs_item_size(leaf->items + path->slots[0]); | 203 | diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); |
204 | if (diff != BTRFS_CRC32_SIZE) | 204 | if (diff != BTRFS_CRC32_SIZE) |
205 | goto insert; | 205 | goto insert; |
206 | ret = btrfs_extend_item(trans, root, path, diff); | 206 | ret = btrfs_extend_item(trans, root, path, diff); |
@@ -220,21 +220,20 @@ insert: | |||
220 | goto fail; | 220 | goto fail; |
221 | } | 221 | } |
222 | csum: | 222 | csum: |
223 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], | 223 | leaf = path->nodes[0]; |
224 | struct btrfs_csum_item); | 224 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
225 | ret = 0; | 225 | ret = 0; |
226 | item = (struct btrfs_csum_item *)((unsigned char *)item + | 226 | item = (struct btrfs_csum_item *)((unsigned char *)item + |
227 | csum_offset * BTRFS_CRC32_SIZE); | 227 | csum_offset * BTRFS_CRC32_SIZE); |
228 | found: | 228 | found: |
229 | btrfs_check_bounds(&item->csum, BTRFS_CRC32_SIZE, | 229 | /* FIXME!!!!!!!!!!!! */ |
230 | path->nodes[0]->b_data, | ||
231 | root->fs_info->sb->s_blocksize); | ||
232 | ret = btrfs_csum_data(root, data, len, &item->csum); | 230 | ret = btrfs_csum_data(root, data, len, &item->csum); |
233 | btrfs_mark_buffer_dirty(path->nodes[0]); | 231 | btrfs_mark_buffer_dirty(path->nodes[0]); |
234 | fail: | 232 | fail: |
235 | btrfs_release_path(root, path); | 233 | btrfs_release_path(root, path); |
236 | btrfs_free_path(path); | 234 | btrfs_free_path(path); |
237 | return ret; | 235 | return ret; |
236 | #endif | ||
238 | } | 237 | } |
239 | 238 | ||
240 | int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | 239 | int btrfs_csum_truncate(struct btrfs_trans_handle *trans, |
@@ -242,21 +241,21 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | |||
242 | u64 isize) | 241 | u64 isize) |
243 | { | 242 | { |
244 | struct btrfs_key key; | 243 | struct btrfs_key key; |
245 | struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[0]); | 244 | struct extent_buffer *leaf = path->nodes[0]; |
246 | int slot = path->slots[0]; | 245 | int slot = path->slots[0]; |
247 | int ret; | 246 | int ret; |
248 | u32 new_item_size; | 247 | u32 new_item_size; |
249 | u64 new_item_span; | 248 | u64 new_item_span; |
250 | u64 blocks; | 249 | u64 blocks; |
251 | 250 | ||
252 | btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); | 251 | btrfs_item_key_to_cpu(leaf, &key, slot); |
253 | if (isize <= key.offset) | 252 | if (isize <= key.offset) |
254 | return 0; | 253 | return 0; |
255 | new_item_span = isize - key.offset; | 254 | new_item_span = isize - key.offset; |
256 | blocks = (new_item_span + root->blocksize - 1) >> | 255 | blocks = (new_item_span + root->sectorsize - 1) >> |
257 | root->fs_info->sb->s_blocksize_bits; | 256 | root->fs_info->sb->s_blocksize_bits; |
258 | new_item_size = blocks * BTRFS_CRC32_SIZE; | 257 | new_item_size = blocks * BTRFS_CRC32_SIZE; |
259 | if (new_item_size >= btrfs_item_size(leaf->items + slot)) | 258 | if (new_item_size >= btrfs_item_size_nr(leaf, slot)) |
260 | return 0; | 259 | return 0; |
261 | ret = btrfs_truncate_item(trans, root, path, new_item_size); | 260 | ret = btrfs_truncate_item(trans, root, path, new_item_size); |
262 | BUG_ON(ret); | 261 | BUG_ON(ret); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 4cc459c943ec..1734ca695555 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/buffer_head.h> | ||
20 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
21 | #include <linux/pagemap.h> | 20 | #include <linux/pagemap.h> |
22 | #include <linux/highmem.h> | 21 | #include <linux/highmem.h> |
@@ -88,7 +87,9 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
88 | { | 87 | { |
89 | struct btrfs_key key; | 88 | struct btrfs_key key; |
90 | struct btrfs_path *path; | 89 | struct btrfs_path *path; |
91 | char *ptr, *kaddr; | 90 | struct extent_buffer *leaf; |
91 | char *kaddr; | ||
92 | unsigned long ptr; | ||
92 | struct btrfs_file_extent_item *ei; | 93 | struct btrfs_file_extent_item *ei; |
93 | u32 datasize; | 94 | u32 datasize; |
94 | int err = 0; | 95 | int err = 0; |
@@ -102,7 +103,6 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
102 | 103 | ||
103 | key.objectid = inode->i_ino; | 104 | key.objectid = inode->i_ino; |
104 | key.offset = offset; | 105 | key.offset = offset; |
105 | key.flags = 0; | ||
106 | btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); | 106 | btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); |
107 | BUG_ON(size >= PAGE_CACHE_SIZE); | 107 | BUG_ON(size >= PAGE_CACHE_SIZE); |
108 | datasize = btrfs_file_extent_calc_inline_size(size); | 108 | datasize = btrfs_file_extent_calc_inline_size(size); |
@@ -113,18 +113,17 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
113 | err = ret; | 113 | err = ret; |
114 | goto fail; | 114 | goto fail; |
115 | } | 115 | } |
116 | ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 116 | leaf = path->nodes[0]; |
117 | path->slots[0], struct btrfs_file_extent_item); | 117 | ei = btrfs_item_ptr(leaf, path->slots[0], |
118 | btrfs_set_file_extent_generation(ei, trans->transid); | 118 | struct btrfs_file_extent_item); |
119 | btrfs_set_file_extent_type(ei, | 119 | btrfs_set_file_extent_generation(leaf, ei, trans->transid); |
120 | BTRFS_FILE_EXTENT_INLINE); | 120 | btrfs_set_file_extent_type(leaf, ei, BTRFS_FILE_EXTENT_INLINE); |
121 | ptr = btrfs_file_extent_inline_start(ei); | 121 | ptr = btrfs_file_extent_inline_start(ei); |
122 | 122 | ||
123 | kaddr = kmap_atomic(page, KM_USER0); | 123 | kaddr = kmap_atomic(page, KM_USER0); |
124 | btrfs_memcpy(root, path->nodes[0]->b_data, | 124 | write_extent_buffer(leaf, kaddr + page_offset, ptr, size); |
125 | ptr, kaddr + page_offset, size); | ||
126 | kunmap_atomic(kaddr, KM_USER0); | 125 | kunmap_atomic(kaddr, KM_USER0); |
127 | btrfs_mark_buffer_dirty(path->nodes[0]); | 126 | btrfs_mark_buffer_dirty(leaf); |
128 | fail: | 127 | fail: |
129 | btrfs_free_path(path); | 128 | btrfs_free_path(path); |
130 | return err; | 129 | return err; |
@@ -156,8 +155,8 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
156 | 155 | ||
157 | em->bdev = inode->i_sb->s_bdev; | 156 | em->bdev = inode->i_sb->s_bdev; |
158 | 157 | ||
159 | start_pos = pos & ~((u64)root->blocksize - 1); | 158 | start_pos = pos & ~((u64)root->sectorsize - 1); |
160 | num_blocks = (write_bytes + pos - start_pos + root->blocksize - 1) >> | 159 | num_blocks = (write_bytes + pos - start_pos + root->sectorsize - 1) >> |
161 | inode->i_blkbits; | 160 | inode->i_blkbits; |
162 | 161 | ||
163 | down_read(&BTRFS_I(inode)->root->snap_sem); | 162 | down_read(&BTRFS_I(inode)->root->snap_sem); |
@@ -184,7 +183,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
184 | if (inode->i_size < start_pos) { | 183 | if (inode->i_size < start_pos) { |
185 | u64 last_pos_in_file; | 184 | u64 last_pos_in_file; |
186 | u64 hole_size; | 185 | u64 hole_size; |
187 | u64 mask = root->blocksize - 1; | 186 | u64 mask = root->sectorsize - 1; |
188 | last_pos_in_file = (isize + mask) & ~mask; | 187 | last_pos_in_file = (isize + mask) & ~mask; |
189 | hole_size = (start_pos - last_pos_in_file + mask) & ~mask; | 188 | hole_size = (start_pos - last_pos_in_file + mask) & ~mask; |
190 | 189 | ||
@@ -227,8 +226,8 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
227 | /* step one, delete the existing extents in this range */ | 226 | /* step one, delete the existing extents in this range */ |
228 | /* FIXME blocksize != pagesize */ | 227 | /* FIXME blocksize != pagesize */ |
229 | err = btrfs_drop_extents(trans, root, inode, start_pos, | 228 | err = btrfs_drop_extents(trans, root, inode, start_pos, |
230 | (pos + write_bytes + root->blocksize -1) & | 229 | (pos + write_bytes + root->sectorsize -1) & |
231 | ~((u64)root->blocksize - 1), &hint_block); | 230 | ~((u64)root->sectorsize - 1), &hint_block); |
232 | if (err) | 231 | if (err) |
233 | goto failed; | 232 | goto failed; |
234 | 233 | ||
@@ -288,7 +287,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
288 | { | 287 | { |
289 | int ret; | 288 | int ret; |
290 | struct btrfs_key key; | 289 | struct btrfs_key key; |
291 | struct btrfs_leaf *leaf; | 290 | struct extent_buffer *leaf; |
292 | int slot; | 291 | int slot; |
293 | struct btrfs_file_extent_item *extent; | 292 | struct btrfs_file_extent_item *extent; |
294 | u64 extent_end = 0; | 293 | u64 extent_end = 0; |
@@ -327,10 +326,10 @@ next_slot: | |||
327 | found_extent = 0; | 326 | found_extent = 0; |
328 | found_inline = 0; | 327 | found_inline = 0; |
329 | extent = NULL; | 328 | extent = NULL; |
330 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 329 | leaf = path->nodes[0]; |
331 | slot = path->slots[0]; | 330 | slot = path->slots[0]; |
332 | ret = 0; | 331 | ret = 0; |
333 | btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); | 332 | btrfs_item_key_to_cpu(leaf, &key, slot); |
334 | if (key.offset >= end || key.objectid != inode->i_ino) { | 333 | if (key.offset >= end || key.objectid != inode->i_ino) { |
335 | goto out; | 334 | goto out; |
336 | } | 335 | } |
@@ -344,17 +343,18 @@ next_slot: | |||
344 | if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { | 343 | if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { |
345 | extent = btrfs_item_ptr(leaf, slot, | 344 | extent = btrfs_item_ptr(leaf, slot, |
346 | struct btrfs_file_extent_item); | 345 | struct btrfs_file_extent_item); |
347 | found_type = btrfs_file_extent_type(extent); | 346 | found_type = btrfs_file_extent_type(leaf, extent); |
348 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 347 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
349 | extent_end = key.offset + | 348 | extent_end = key.offset + |
350 | (btrfs_file_extent_num_blocks(extent) << | 349 | (btrfs_file_extent_num_blocks(leaf, extent) << |
351 | inode->i_blkbits); | 350 | inode->i_blkbits); |
352 | found_extent = 1; | 351 | found_extent = 1; |
353 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 352 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
353 | struct btrfs_item *item; | ||
354 | item = btrfs_item_nr(leaf, slot); | ||
354 | found_inline = 1; | 355 | found_inline = 1; |
355 | extent_end = key.offset + | 356 | extent_end = key.offset + |
356 | btrfs_file_extent_inline_len(leaf->items + | 357 | btrfs_file_extent_inline_len(leaf, item); |
357 | slot); | ||
358 | } | 358 | } |
359 | } else { | 359 | } else { |
360 | extent_end = search_start; | 360 | extent_end = search_start; |
@@ -365,8 +365,7 @@ next_slot: | |||
365 | search_start >= extent_end) { | 365 | search_start >= extent_end) { |
366 | int nextret; | 366 | int nextret; |
367 | u32 nritems; | 367 | u32 nritems; |
368 | nritems = btrfs_header_nritems( | 368 | nritems = btrfs_header_nritems(leaf); |
369 | btrfs_buffer_header(path->nodes[0])); | ||
370 | if (slot >= nritems - 1) { | 369 | if (slot >= nritems - 1) { |
371 | nextret = btrfs_next_leaf(root, path); | 370 | nextret = btrfs_next_leaf(root, path); |
372 | if (nextret) | 371 | if (nextret) |
@@ -380,7 +379,7 @@ next_slot: | |||
380 | 379 | ||
381 | /* FIXME, there's only one inline extent allowed right now */ | 380 | /* FIXME, there's only one inline extent allowed right now */ |
382 | if (found_inline) { | 381 | if (found_inline) { |
383 | u64 mask = root->blocksize - 1; | 382 | u64 mask = root->sectorsize - 1; |
384 | search_start = (extent_end + mask) & ~mask; | 383 | search_start = (extent_end + mask) & ~mask; |
385 | } else | 384 | } else |
386 | search_start = extent_end; | 385 | search_start = extent_end; |
@@ -388,10 +387,13 @@ next_slot: | |||
388 | if (end < extent_end && end >= key.offset) { | 387 | if (end < extent_end && end >= key.offset) { |
389 | if (found_extent) { | 388 | if (found_extent) { |
390 | u64 disk_blocknr = | 389 | u64 disk_blocknr = |
391 | btrfs_file_extent_disk_blocknr(extent); | 390 | btrfs_file_extent_disk_blocknr(leaf,extent); |
392 | u64 disk_num_blocks = | 391 | u64 disk_num_blocks = |
393 | btrfs_file_extent_disk_num_blocks(extent); | 392 | btrfs_file_extent_disk_num_blocks(leaf, |
394 | memcpy(&old, extent, sizeof(old)); | 393 | extent); |
394 | read_extent_buffer(leaf, &old, | ||
395 | (unsigned long)extent, | ||
396 | sizeof(old)); | ||
395 | if (disk_blocknr != 0) { | 397 | if (disk_blocknr != 0) { |
396 | ret = btrfs_inc_extent_ref(trans, root, | 398 | ret = btrfs_inc_extent_ref(trans, root, |
397 | disk_blocknr, disk_num_blocks); | 399 | disk_blocknr, disk_num_blocks); |
@@ -406,20 +408,24 @@ next_slot: | |||
406 | u64 new_num; | 408 | u64 new_num; |
407 | u64 old_num; | 409 | u64 old_num; |
408 | keep = 1; | 410 | keep = 1; |
409 | WARN_ON(start & (root->blocksize - 1)); | 411 | WARN_ON(start & (root->sectorsize - 1)); |
410 | if (found_extent) { | 412 | if (found_extent) { |
411 | new_num = (start - key.offset) >> | 413 | new_num = (start - key.offset) >> |
412 | inode->i_blkbits; | 414 | inode->i_blkbits; |
413 | old_num = btrfs_file_extent_num_blocks(extent); | 415 | old_num = btrfs_file_extent_num_blocks(leaf, |
416 | extent); | ||
414 | *hint_block = | 417 | *hint_block = |
415 | btrfs_file_extent_disk_blocknr(extent); | 418 | btrfs_file_extent_disk_blocknr(leaf, |
416 | if (btrfs_file_extent_disk_blocknr(extent)) { | 419 | extent); |
420 | if (btrfs_file_extent_disk_blocknr(leaf, | ||
421 | extent)) { | ||
417 | inode->i_blocks -= | 422 | inode->i_blocks -= |
418 | (old_num - new_num) << 3; | 423 | (old_num - new_num) << 3; |
419 | } | 424 | } |
420 | btrfs_set_file_extent_num_blocks(extent, | 425 | btrfs_set_file_extent_num_blocks(leaf, |
426 | extent, | ||
421 | new_num); | 427 | new_num); |
422 | btrfs_mark_buffer_dirty(path->nodes[0]); | 428 | btrfs_mark_buffer_dirty(leaf); |
423 | } else { | 429 | } else { |
424 | WARN_ON(1); | 430 | WARN_ON(1); |
425 | } | 431 | } |
@@ -431,13 +437,17 @@ next_slot: | |||
431 | u64 extent_num_blocks = 0; | 437 | u64 extent_num_blocks = 0; |
432 | if (found_extent) { | 438 | if (found_extent) { |
433 | disk_blocknr = | 439 | disk_blocknr = |
434 | btrfs_file_extent_disk_blocknr(extent); | 440 | btrfs_file_extent_disk_blocknr(leaf, |
441 | extent); | ||
435 | disk_num_blocks = | 442 | disk_num_blocks = |
436 | btrfs_file_extent_disk_num_blocks(extent); | 443 | btrfs_file_extent_disk_num_blocks(leaf, |
444 | extent); | ||
437 | extent_num_blocks = | 445 | extent_num_blocks = |
438 | btrfs_file_extent_num_blocks(extent); | 446 | btrfs_file_extent_num_blocks(leaf, |
447 | extent); | ||
439 | *hint_block = | 448 | *hint_block = |
440 | btrfs_file_extent_disk_blocknr(extent); | 449 | btrfs_file_extent_disk_blocknr(leaf, |
450 | extent); | ||
441 | } | 451 | } |
442 | ret = btrfs_del_item(trans, root, path); | 452 | ret = btrfs_del_item(trans, root, path); |
443 | /* TODO update progress marker and return */ | 453 | /* TODO update progress marker and return */ |
@@ -464,42 +474,37 @@ next_slot: | |||
464 | struct btrfs_key ins; | 474 | struct btrfs_key ins; |
465 | ins.objectid = inode->i_ino; | 475 | ins.objectid = inode->i_ino; |
466 | ins.offset = end; | 476 | ins.offset = end; |
467 | ins.flags = 0; | ||
468 | btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); | 477 | btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); |
469 | btrfs_release_path(root, path); | 478 | btrfs_release_path(root, path); |
470 | ret = btrfs_insert_empty_item(trans, root, path, &ins, | 479 | ret = btrfs_insert_empty_item(trans, root, path, &ins, |
471 | sizeof(*extent)); | 480 | sizeof(*extent)); |
472 | 481 | ||
482 | leaf = path->nodes[0]; | ||
473 | if (ret) { | 483 | if (ret) { |
474 | btrfs_print_leaf(root, btrfs_buffer_leaf(path->nodes[0])); | 484 | btrfs_print_leaf(root, leaf); |
475 | printk("got %d on inserting %Lu %u %Lu start %Lu end %Lu found %Lu %Lu keep was %d\n", ret , ins.objectid, ins.flags, ins.offset, start, end, key.offset, extent_end, keep); | 485 | printk("got %d on inserting %Lu %u %Lu start %Lu end %Lu found %Lu %Lu keep was %d\n", ret , ins.objectid, ins.type, ins.offset, start, end, key.offset, extent_end, keep); |
476 | } | 486 | } |
477 | BUG_ON(ret); | 487 | BUG_ON(ret); |
478 | extent = btrfs_item_ptr( | 488 | extent = btrfs_item_ptr(leaf, path->slots[0], |
479 | btrfs_buffer_leaf(path->nodes[0]), | 489 | struct btrfs_file_extent_item); |
480 | path->slots[0], | 490 | write_extent_buffer(leaf, &old, |
481 | struct btrfs_file_extent_item); | 491 | (unsigned long)extent, sizeof(old)); |
482 | btrfs_set_file_extent_disk_blocknr(extent, | 492 | |
483 | btrfs_file_extent_disk_blocknr(&old)); | 493 | btrfs_set_file_extent_offset(leaf, extent, |
484 | btrfs_set_file_extent_disk_num_blocks(extent, | 494 | le64_to_cpu(old.offset) + |
485 | btrfs_file_extent_disk_num_blocks(&old)); | ||
486 | |||
487 | btrfs_set_file_extent_offset(extent, | ||
488 | btrfs_file_extent_offset(&old) + | ||
489 | ((end - key.offset) >> inode->i_blkbits)); | 495 | ((end - key.offset) >> inode->i_blkbits)); |
490 | WARN_ON(btrfs_file_extent_num_blocks(&old) < | 496 | WARN_ON(le64_to_cpu(old.num_blocks) < |
491 | (extent_end - end) >> inode->i_blkbits); | 497 | (extent_end - end) >> inode->i_blkbits); |
492 | btrfs_set_file_extent_num_blocks(extent, | 498 | btrfs_set_file_extent_num_blocks(leaf, extent, |
493 | (extent_end - end) >> inode->i_blkbits); | 499 | (extent_end - end) >> inode->i_blkbits); |
494 | 500 | ||
495 | btrfs_set_file_extent_type(extent, | 501 | btrfs_set_file_extent_type(leaf, extent, |
496 | BTRFS_FILE_EXTENT_REG); | 502 | BTRFS_FILE_EXTENT_REG); |
497 | btrfs_set_file_extent_generation(extent, | ||
498 | btrfs_file_extent_generation(&old)); | ||
499 | btrfs_mark_buffer_dirty(path->nodes[0]); | 503 | btrfs_mark_buffer_dirty(path->nodes[0]); |
500 | if (btrfs_file_extent_disk_blocknr(&old) != 0) { | 504 | if (le64_to_cpu(old.disk_blocknr) != 0) { |
501 | inode->i_blocks += | 505 | inode->i_blocks += |
502 | btrfs_file_extent_num_blocks(extent) << 3; | 506 | btrfs_file_extent_num_blocks(leaf, |
507 | extent) << 3; | ||
503 | } | 508 | } |
504 | ret = 0; | 509 | ret = 0; |
505 | goto out; | 510 | goto out; |
@@ -529,8 +534,8 @@ static int prepare_pages(struct btrfs_root *root, | |||
529 | u64 num_blocks; | 534 | u64 num_blocks; |
530 | u64 start_pos; | 535 | u64 start_pos; |
531 | 536 | ||
532 | start_pos = pos & ~((u64)root->blocksize - 1); | 537 | start_pos = pos & ~((u64)root->sectorsize - 1); |
533 | num_blocks = (write_bytes + pos - start_pos + root->blocksize - 1) >> | 538 | num_blocks = (write_bytes + pos - start_pos + root->sectorsize - 1) >> |
534 | inode->i_blkbits; | 539 | inode->i_blkbits; |
535 | 540 | ||
536 | memset(pages, 0, num_pages * sizeof(struct page *)); | 541 | memset(pages, 0, num_pages * sizeof(struct page *)); |
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index b78346177539..35d2608f8918 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c | |||
@@ -20,24 +20,18 @@ | |||
20 | #include "disk-io.h" | 20 | #include "disk-io.h" |
21 | #include "transaction.h" | 21 | #include "transaction.h" |
22 | 22 | ||
23 | int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root | 23 | int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans, |
24 | *root, u64 objectid, struct btrfs_inode_item | 24 | struct btrfs_root *root, |
25 | *inode_item) | 25 | struct btrfs_path *path, u64 objectid) |
26 | { | 26 | { |
27 | struct btrfs_path *path; | ||
28 | struct btrfs_key key; | 27 | struct btrfs_key key; |
29 | int ret; | 28 | int ret; |
30 | key.objectid = objectid; | 29 | key.objectid = objectid; |
31 | key.flags = 0; | ||
32 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 30 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
33 | key.offset = 0; | 31 | key.offset = 0; |
34 | 32 | ||
35 | path = btrfs_alloc_path(); | 33 | ret = btrfs_insert_empty_item(trans, root, path, &key, |
36 | BUG_ON(!path); | 34 | sizeof(struct btrfs_inode_item)); |
37 | ret = btrfs_insert_item(trans, root, &key, inode_item, | ||
38 | sizeof(*inode_item)); | ||
39 | btrfs_release_path(root, path); | ||
40 | btrfs_free_path(path); | ||
41 | if (ret == 0 && objectid > root->highest_inode) | 35 | if (ret == 0 && objectid > root->highest_inode) |
42 | root->highest_inode = objectid; | 36 | root->highest_inode = objectid; |
43 | return ret; | 37 | return ret; |
@@ -51,15 +45,15 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root | |||
51 | int cow = mod != 0; | 45 | int cow = mod != 0; |
52 | int ret; | 46 | int ret; |
53 | int slot; | 47 | int slot; |
54 | struct btrfs_leaf *leaf; | 48 | struct extent_buffer *leaf; |
55 | struct btrfs_key found_key; | 49 | struct btrfs_key found_key; |
56 | 50 | ||
57 | ret = btrfs_search_slot(trans, root, location, path, ins_len, cow); | 51 | ret = btrfs_search_slot(trans, root, location, path, ins_len, cow); |
58 | if (ret > 0 && btrfs_key_type(location) == BTRFS_ROOT_ITEM_KEY && | 52 | if (ret > 0 && btrfs_key_type(location) == BTRFS_ROOT_ITEM_KEY && |
59 | location->offset == (u64)-1 && path->slots[0] != 0) { | 53 | location->offset == (u64)-1 && path->slots[0] != 0) { |
60 | slot = path->slots[0] - 1; | 54 | slot = path->slots[0] - 1; |
61 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 55 | leaf = path->nodes[0]; |
62 | btrfs_disk_key_to_cpu(&found_key, &leaf->items[slot].key); | 56 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
63 | if (found_key.objectid == location->objectid && | 57 | if (found_key.objectid == location->objectid && |
64 | btrfs_key_type(&found_key) == btrfs_key_type(location)) { | 58 | btrfs_key_type(&found_key) == btrfs_key_type(location)) { |
65 | path->slots[0]--; | 59 | path->slots[0]--; |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 405470866254..ab74977adf5c 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -24,8 +24,9 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid) | |||
24 | { | 24 | { |
25 | struct btrfs_path *path; | 25 | struct btrfs_path *path; |
26 | int ret; | 26 | int ret; |
27 | struct btrfs_leaf *l; | 27 | struct extent_buffer *l; |
28 | struct btrfs_key search_key; | 28 | struct btrfs_key search_key; |
29 | struct btrfs_key found_key; | ||
29 | int slot; | 30 | int slot; |
30 | 31 | ||
31 | path = btrfs_alloc_path(); | 32 | path = btrfs_alloc_path(); |
@@ -39,8 +40,9 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid) | |||
39 | BUG_ON(ret == 0); | 40 | BUG_ON(ret == 0); |
40 | if (path->slots[0] > 0) { | 41 | if (path->slots[0] > 0) { |
41 | slot = path->slots[0] - 1; | 42 | slot = path->slots[0] - 1; |
42 | l = btrfs_buffer_leaf(path->nodes[0]); | 43 | l = path->nodes[0]; |
43 | *objectid = btrfs_disk_key_objectid(&l->items[slot].key); | 44 | btrfs_item_key_to_cpu(l, &found_key, slot); |
45 | *objectid = found_key.objectid; | ||
44 | } else { | 46 | } else { |
45 | *objectid = BTRFS_FIRST_FREE_OBJECTID; | 47 | *objectid = BTRFS_FIRST_FREE_OBJECTID; |
46 | } | 48 | } |
@@ -64,13 +66,12 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, | |||
64 | int slot = 0; | 66 | int slot = 0; |
65 | u64 last_ino = 0; | 67 | u64 last_ino = 0; |
66 | int start_found; | 68 | int start_found; |
67 | struct btrfs_leaf *l; | 69 | struct extent_buffer *l; |
68 | struct btrfs_key search_key; | 70 | struct btrfs_key search_key; |
69 | u64 search_start = dirid; | 71 | u64 search_start = dirid; |
70 | 72 | ||
71 | path = btrfs_alloc_path(); | 73 | path = btrfs_alloc_path(); |
72 | BUG_ON(!path); | 74 | BUG_ON(!path); |
73 | search_key.flags = 0; | ||
74 | search_start = root->last_inode_alloc; | 75 | search_start = root->last_inode_alloc; |
75 | search_start = max(search_start, BTRFS_FIRST_FREE_OBJECTID); | 76 | search_start = max(search_start, BTRFS_FIRST_FREE_OBJECTID); |
76 | search_key.objectid = search_start; | 77 | search_key.objectid = search_start; |
@@ -86,9 +87,9 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, | |||
86 | path->slots[0]--; | 87 | path->slots[0]--; |
87 | 88 | ||
88 | while (1) { | 89 | while (1) { |
89 | l = btrfs_buffer_leaf(path->nodes[0]); | 90 | l = path->nodes[0]; |
90 | slot = path->slots[0]; | 91 | slot = path->slots[0]; |
91 | if (slot >= btrfs_header_nritems(&l->header)) { | 92 | if (slot >= btrfs_header_nritems(l)) { |
92 | ret = btrfs_next_leaf(root, path); | 93 | ret = btrfs_next_leaf(root, path); |
93 | if (ret == 0) | 94 | if (ret == 0) |
94 | continue; | 95 | continue; |
@@ -103,7 +104,7 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, | |||
103 | last_ino : search_start; | 104 | last_ino : search_start; |
104 | goto found; | 105 | goto found; |
105 | } | 106 | } |
106 | btrfs_disk_key_to_cpu(&key, &l->items[slot].key); | 107 | btrfs_item_key_to_cpu(l, &key, slot); |
107 | if (key.objectid >= search_start) { | 108 | if (key.objectid >= search_start) { |
108 | if (start_found) { | 109 | if (start_found) { |
109 | if (last_ino < search_start) | 110 | if (last_ino < search_start) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b03d40a907ca..fbe2836364e0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -159,10 +159,8 @@ out: | |||
159 | 159 | ||
160 | int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end) | 160 | int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end) |
161 | { | 161 | { |
162 | char csum[BTRFS_CRC32_SIZE]; | ||
163 | size_t offset = start - (page->index << PAGE_CACHE_SHIFT); | 162 | size_t offset = start - (page->index << PAGE_CACHE_SHIFT); |
164 | struct inode *inode = page->mapping->host; | 163 | struct inode *inode = page->mapping->host; |
165 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
166 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 164 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
167 | char *kaddr; | 165 | char *kaddr; |
168 | u64 private; | 166 | u64 private; |
@@ -173,11 +171,15 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end) | |||
173 | if (ret) { | 171 | if (ret) { |
174 | goto zeroit; | 172 | goto zeroit; |
175 | } | 173 | } |
174 | /* | ||
175 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
176 | char csum[BTRFS_CRC32_SIZE]; | ||
176 | ret = btrfs_csum_data(root, kaddr + offset, end - start + 1, csum); | 177 | ret = btrfs_csum_data(root, kaddr + offset, end - start + 1, csum); |
177 | BUG_ON(ret); | 178 | BUG_ON(ret); |
178 | if (memcmp(csum, &private, BTRFS_CRC32_SIZE)) { | 179 | if (memcmp(csum, &private, BTRFS_CRC32_SIZE)) { |
179 | goto zeroit; | 180 | goto zeroit; |
180 | } | 181 | } |
182 | */ | ||
181 | kunmap_atomic(kaddr, KM_IRQ0); | 183 | kunmap_atomic(kaddr, KM_IRQ0); |
182 | return 0; | 184 | return 0; |
183 | 185 | ||
@@ -192,7 +194,9 @@ zeroit: | |||
192 | void btrfs_read_locked_inode(struct inode *inode) | 194 | void btrfs_read_locked_inode(struct inode *inode) |
193 | { | 195 | { |
194 | struct btrfs_path *path; | 196 | struct btrfs_path *path; |
197 | struct extent_buffer *leaf; | ||
195 | struct btrfs_inode_item *inode_item; | 198 | struct btrfs_inode_item *inode_item; |
199 | struct btrfs_inode_timespec *tspec; | ||
196 | struct btrfs_root *root = BTRFS_I(inode)->root; | 200 | struct btrfs_root *root = BTRFS_I(inode)->root; |
197 | struct btrfs_key location; | 201 | struct btrfs_key location; |
198 | u64 alloc_group_block; | 202 | u64 alloc_group_block; |
@@ -205,29 +209,37 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
205 | 209 | ||
206 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); | 210 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); |
207 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); | 211 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); |
208 | if (ret) { | 212 | if (ret) |
209 | goto make_bad; | 213 | goto make_bad; |
210 | } | ||
211 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | ||
212 | path->slots[0], | ||
213 | struct btrfs_inode_item); | ||
214 | 214 | ||
215 | inode->i_mode = btrfs_inode_mode(inode_item); | 215 | leaf = path->nodes[0]; |
216 | inode->i_nlink = btrfs_inode_nlink(inode_item); | 216 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
217 | inode->i_uid = btrfs_inode_uid(inode_item); | 217 | struct btrfs_inode_item); |
218 | inode->i_gid = btrfs_inode_gid(inode_item); | 218 | |
219 | inode->i_size = btrfs_inode_size(inode_item); | 219 | inode->i_mode = btrfs_inode_mode(leaf, inode_item); |
220 | inode->i_atime.tv_sec = btrfs_timespec_sec(&inode_item->atime); | 220 | inode->i_nlink = btrfs_inode_nlink(leaf, inode_item); |
221 | inode->i_atime.tv_nsec = btrfs_timespec_nsec(&inode_item->atime); | 221 | inode->i_uid = btrfs_inode_uid(leaf, inode_item); |
222 | inode->i_mtime.tv_sec = btrfs_timespec_sec(&inode_item->mtime); | 222 | inode->i_gid = btrfs_inode_gid(leaf, inode_item); |
223 | inode->i_mtime.tv_nsec = btrfs_timespec_nsec(&inode_item->mtime); | 223 | inode->i_size = btrfs_inode_size(leaf, inode_item); |
224 | inode->i_ctime.tv_sec = btrfs_timespec_sec(&inode_item->ctime); | 224 | |
225 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); | 225 | tspec = btrfs_inode_atime(inode_item); |
226 | inode->i_blocks = btrfs_inode_nblocks(inode_item); | 226 | inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, tspec); |
227 | inode->i_generation = btrfs_inode_generation(inode_item); | 227 | inode->i_atime.tv_nsec = btrfs_timespec_nsec(leaf, tspec); |
228 | |||
229 | tspec = btrfs_inode_mtime(inode_item); | ||
230 | inode->i_mtime.tv_sec = btrfs_timespec_sec(leaf, tspec); | ||
231 | inode->i_mtime.tv_nsec = btrfs_timespec_nsec(leaf, tspec); | ||
232 | |||
233 | tspec = btrfs_inode_ctime(inode_item); | ||
234 | inode->i_ctime.tv_sec = btrfs_timespec_sec(leaf, tspec); | ||
235 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(leaf, tspec); | ||
236 | |||
237 | inode->i_blocks = btrfs_inode_nblocks(leaf, inode_item); | ||
238 | inode->i_generation = btrfs_inode_generation(leaf, inode_item); | ||
228 | inode->i_rdev = 0; | 239 | inode->i_rdev = 0; |
229 | rdev = btrfs_inode_rdev(inode_item); | 240 | rdev = btrfs_inode_rdev(leaf, inode_item); |
230 | alloc_group_block = btrfs_inode_block_group(inode_item); | 241 | |
242 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); | ||
231 | BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info, | 243 | BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info, |
232 | alloc_group_block); | 244 | alloc_group_block); |
233 | 245 | ||
@@ -267,24 +279,35 @@ make_bad: | |||
267 | make_bad_inode(inode); | 279 | make_bad_inode(inode); |
268 | } | 280 | } |
269 | 281 | ||
270 | static void fill_inode_item(struct btrfs_inode_item *item, | 282 | static void fill_inode_item(struct extent_buffer *leaf, |
283 | struct btrfs_inode_item *item, | ||
271 | struct inode *inode) | 284 | struct inode *inode) |
272 | { | 285 | { |
273 | btrfs_set_inode_uid(item, inode->i_uid); | 286 | btrfs_set_inode_uid(leaf, item, inode->i_uid); |
274 | btrfs_set_inode_gid(item, inode->i_gid); | 287 | btrfs_set_inode_gid(leaf, item, inode->i_gid); |
275 | btrfs_set_inode_size(item, inode->i_size); | 288 | btrfs_set_inode_size(leaf, item, inode->i_size); |
276 | btrfs_set_inode_mode(item, inode->i_mode); | 289 | btrfs_set_inode_mode(leaf, item, inode->i_mode); |
277 | btrfs_set_inode_nlink(item, inode->i_nlink); | 290 | btrfs_set_inode_nlink(leaf, item, inode->i_nlink); |
278 | btrfs_set_timespec_sec(&item->atime, inode->i_atime.tv_sec); | 291 | |
279 | btrfs_set_timespec_nsec(&item->atime, inode->i_atime.tv_nsec); | 292 | btrfs_set_timespec_sec(leaf, btrfs_inode_atime(item), |
280 | btrfs_set_timespec_sec(&item->mtime, inode->i_mtime.tv_sec); | 293 | inode->i_atime.tv_sec); |
281 | btrfs_set_timespec_nsec(&item->mtime, inode->i_mtime.tv_nsec); | 294 | btrfs_set_timespec_nsec(leaf, btrfs_inode_atime(item), |
282 | btrfs_set_timespec_sec(&item->ctime, inode->i_ctime.tv_sec); | 295 | inode->i_atime.tv_nsec); |
283 | btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec); | 296 | |
284 | btrfs_set_inode_nblocks(item, inode->i_blocks); | 297 | btrfs_set_timespec_sec(leaf, btrfs_inode_mtime(item), |
285 | btrfs_set_inode_generation(item, inode->i_generation); | 298 | inode->i_mtime.tv_sec); |
286 | btrfs_set_inode_rdev(item, inode->i_rdev); | 299 | btrfs_set_timespec_nsec(leaf, btrfs_inode_mtime(item), |
287 | btrfs_set_inode_block_group(item, | 300 | inode->i_mtime.tv_nsec); |
301 | |||
302 | btrfs_set_timespec_sec(leaf, btrfs_inode_ctime(item), | ||
303 | inode->i_ctime.tv_sec); | ||
304 | btrfs_set_timespec_nsec(leaf, btrfs_inode_ctime(item), | ||
305 | inode->i_ctime.tv_nsec); | ||
306 | |||
307 | btrfs_set_inode_nblocks(leaf, item, inode->i_blocks); | ||
308 | btrfs_set_inode_generation(leaf, item, inode->i_generation); | ||
309 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); | ||
310 | btrfs_set_inode_block_group(leaf, item, | ||
288 | BTRFS_I(inode)->block_group->key.objectid); | 311 | BTRFS_I(inode)->block_group->key.objectid); |
289 | } | 312 | } |
290 | 313 | ||
@@ -294,6 +317,7 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
294 | { | 317 | { |
295 | struct btrfs_inode_item *inode_item; | 318 | struct btrfs_inode_item *inode_item; |
296 | struct btrfs_path *path; | 319 | struct btrfs_path *path; |
320 | struct extent_buffer *leaf; | ||
297 | int ret; | 321 | int ret; |
298 | 322 | ||
299 | path = btrfs_alloc_path(); | 323 | path = btrfs_alloc_path(); |
@@ -306,12 +330,12 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
306 | goto failed; | 330 | goto failed; |
307 | } | 331 | } |
308 | 332 | ||
309 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 333 | leaf = path->nodes[0]; |
310 | path->slots[0], | 334 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
311 | struct btrfs_inode_item); | 335 | struct btrfs_inode_item); |
312 | 336 | ||
313 | fill_inode_item(inode_item, inode); | 337 | fill_inode_item(leaf, inode_item, inode); |
314 | btrfs_mark_buffer_dirty(path->nodes[0]); | 338 | btrfs_mark_buffer_dirty(leaf); |
315 | btrfs_set_inode_last_trans(trans, inode); | 339 | btrfs_set_inode_last_trans(trans, inode); |
316 | ret = 0; | 340 | ret = 0; |
317 | failed: | 341 | failed: |
@@ -330,8 +354,9 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
330 | const char *name = dentry->d_name.name; | 354 | const char *name = dentry->d_name.name; |
331 | int name_len = dentry->d_name.len; | 355 | int name_len = dentry->d_name.len; |
332 | int ret = 0; | 356 | int ret = 0; |
333 | u64 objectid; | 357 | struct extent_buffer *leaf; |
334 | struct btrfs_dir_item *di; | 358 | struct btrfs_dir_item *di; |
359 | struct btrfs_key key; | ||
335 | 360 | ||
336 | path = btrfs_alloc_path(); | 361 | path = btrfs_alloc_path(); |
337 | if (!path) { | 362 | if (!path) { |
@@ -349,14 +374,15 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
349 | ret = -ENOENT; | 374 | ret = -ENOENT; |
350 | goto err; | 375 | goto err; |
351 | } | 376 | } |
352 | objectid = btrfs_disk_key_objectid(&di->location); | 377 | leaf = path->nodes[0]; |
378 | btrfs_dir_item_key_to_cpu(leaf, di, &key); | ||
353 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | 379 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
354 | if (ret) | 380 | if (ret) |
355 | goto err; | 381 | goto err; |
356 | btrfs_release_path(root, path); | 382 | btrfs_release_path(root, path); |
357 | 383 | ||
358 | di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, | 384 | di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, |
359 | objectid, name, name_len, -1); | 385 | key.objectid, name, name_len, -1); |
360 | if (IS_ERR(di)) { | 386 | if (IS_ERR(di)) { |
361 | ret = PTR_ERR(di); | 387 | ret = PTR_ERR(di); |
362 | goto err; | 388 | goto err; |
@@ -391,12 +417,15 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
391 | root = BTRFS_I(dir)->root; | 417 | root = BTRFS_I(dir)->root; |
392 | mutex_lock(&root->fs_info->fs_mutex); | 418 | mutex_lock(&root->fs_info->fs_mutex); |
393 | trans = btrfs_start_transaction(root, 1); | 419 | trans = btrfs_start_transaction(root, 1); |
420 | |||
394 | btrfs_set_trans_block_group(trans, dir); | 421 | btrfs_set_trans_block_group(trans, dir); |
395 | ret = btrfs_unlink_trans(trans, root, dir, dentry); | 422 | ret = btrfs_unlink_trans(trans, root, dir, dentry); |
396 | nr = trans->blocks_used; | 423 | nr = trans->blocks_used; |
424 | |||
397 | btrfs_end_transaction(trans, root); | 425 | btrfs_end_transaction(trans, root); |
398 | mutex_unlock(&root->fs_info->fs_mutex); | 426 | mutex_unlock(&root->fs_info->fs_mutex); |
399 | btrfs_btree_balance_dirty(root, nr); | 427 | btrfs_btree_balance_dirty(root, nr); |
428 | |||
400 | return ret; | 429 | return ret; |
401 | } | 430 | } |
402 | 431 | ||
@@ -411,7 +440,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
411 | struct btrfs_trans_handle *trans; | 440 | struct btrfs_trans_handle *trans; |
412 | struct btrfs_key found_key; | 441 | struct btrfs_key found_key; |
413 | int found_type; | 442 | int found_type; |
414 | struct btrfs_leaf *leaf; | 443 | struct extent_buffer *leaf; |
415 | char *goodnames = ".."; | 444 | char *goodnames = ".."; |
416 | unsigned long nr; | 445 | unsigned long nr; |
417 | 446 | ||
@@ -419,10 +448,11 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
419 | BUG_ON(!path); | 448 | BUG_ON(!path); |
420 | mutex_lock(&root->fs_info->fs_mutex); | 449 | mutex_lock(&root->fs_info->fs_mutex); |
421 | trans = btrfs_start_transaction(root, 1); | 450 | trans = btrfs_start_transaction(root, 1); |
451 | |||
422 | btrfs_set_trans_block_group(trans, dir); | 452 | btrfs_set_trans_block_group(trans, dir); |
423 | key.objectid = inode->i_ino; | 453 | key.objectid = inode->i_ino; |
424 | key.offset = (u64)-1; | 454 | key.offset = (u64)-1; |
425 | key.flags = (u32)-1; | 455 | key.type = (u8)-1; |
426 | while(1) { | 456 | while(1) { |
427 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 457 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
428 | if (ret < 0) { | 458 | if (ret < 0) { |
@@ -435,9 +465,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
435 | goto out; | 465 | goto out; |
436 | } | 466 | } |
437 | path->slots[0]--; | 467 | path->slots[0]--; |
438 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 468 | leaf = path->nodes[0]; |
439 | btrfs_disk_key_to_cpu(&found_key, | 469 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
440 | &leaf->items[path->slots[0]].key); | ||
441 | found_type = btrfs_key_type(&found_key); | 470 | found_type = btrfs_key_type(&found_key); |
442 | if (found_key.objectid != inode->i_ino) { | 471 | if (found_key.objectid != inode->i_ino) { |
443 | err = -ENOENT; | 472 | err = -ENOENT; |
@@ -513,9 +542,9 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
513 | int ret; | 542 | int ret; |
514 | struct btrfs_path *path; | 543 | struct btrfs_path *path; |
515 | struct btrfs_key key; | 544 | struct btrfs_key key; |
516 | struct btrfs_disk_key *found_key; | 545 | struct btrfs_key found_key; |
517 | u32 found_type; | 546 | u32 found_type; |
518 | struct btrfs_leaf *leaf; | 547 | struct extent_buffer *leaf; |
519 | struct btrfs_file_extent_item *fi; | 548 | struct btrfs_file_extent_item *fi; |
520 | u64 extent_start = 0; | 549 | u64 extent_start = 0; |
521 | u64 extent_num_blocks = 0; | 550 | u64 extent_num_blocks = 0; |
@@ -527,10 +556,12 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
527 | path = btrfs_alloc_path(); | 556 | path = btrfs_alloc_path(); |
528 | path->reada = -1; | 557 | path->reada = -1; |
529 | BUG_ON(!path); | 558 | BUG_ON(!path); |
559 | |||
530 | /* FIXME, add redo link to tree so we don't leak on crash */ | 560 | /* FIXME, add redo link to tree so we don't leak on crash */ |
531 | key.objectid = inode->i_ino; | 561 | key.objectid = inode->i_ino; |
532 | key.offset = (u64)-1; | 562 | key.offset = (u64)-1; |
533 | key.flags = (u32)-1; | 563 | key.type = (u8)-1; |
564 | |||
534 | while(1) { | 565 | while(1) { |
535 | btrfs_init_path(path); | 566 | btrfs_init_path(path); |
536 | fi = NULL; | 567 | fi = NULL; |
@@ -542,27 +573,28 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
542 | BUG_ON(path->slots[0] == 0); | 573 | BUG_ON(path->slots[0] == 0); |
543 | path->slots[0]--; | 574 | path->slots[0]--; |
544 | } | 575 | } |
545 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 576 | leaf = path->nodes[0]; |
546 | found_key = &leaf->items[path->slots[0]].key; | 577 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
547 | found_type = btrfs_disk_key_type(found_key); | 578 | found_type = btrfs_key_type(&found_key); |
548 | 579 | ||
549 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) | 580 | if (found_key.objectid != inode->i_ino) |
550 | break; | 581 | break; |
582 | |||
551 | if (found_type != BTRFS_CSUM_ITEM_KEY && | 583 | if (found_type != BTRFS_CSUM_ITEM_KEY && |
552 | found_type != BTRFS_DIR_ITEM_KEY && | 584 | found_type != BTRFS_DIR_ITEM_KEY && |
553 | found_type != BTRFS_DIR_INDEX_KEY && | 585 | found_type != BTRFS_DIR_INDEX_KEY && |
554 | found_type != BTRFS_EXTENT_DATA_KEY) | 586 | found_type != BTRFS_EXTENT_DATA_KEY) |
555 | break; | 587 | break; |
556 | 588 | ||
557 | item_end = btrfs_disk_key_offset(found_key); | 589 | item_end = found_key.offset; |
558 | if (found_type == BTRFS_EXTENT_DATA_KEY) { | 590 | if (found_type == BTRFS_EXTENT_DATA_KEY) { |
559 | fi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 591 | fi = btrfs_item_ptr(leaf, path->slots[0], |
560 | path->slots[0], | ||
561 | struct btrfs_file_extent_item); | 592 | struct btrfs_file_extent_item); |
562 | if (btrfs_file_extent_type(fi) != | 593 | if (btrfs_file_extent_type(leaf, fi) != |
563 | BTRFS_FILE_EXTENT_INLINE) { | 594 | BTRFS_FILE_EXTENT_INLINE) { |
564 | item_end += btrfs_file_extent_num_blocks(fi) << | 595 | item_end += |
565 | inode->i_blkbits; | 596 | btrfs_file_extent_num_blocks(leaf, fi) << |
597 | inode->i_blkbits; | ||
566 | } | 598 | } |
567 | } | 599 | } |
568 | if (found_type == BTRFS_CSUM_ITEM_KEY) { | 600 | if (found_type == BTRFS_CSUM_ITEM_KEY) { |
@@ -583,7 +615,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
583 | btrfs_set_key_type(&key, found_type); | 615 | btrfs_set_key_type(&key, found_type); |
584 | continue; | 616 | continue; |
585 | } | 617 | } |
586 | if (btrfs_disk_key_offset(found_key) >= inode->i_size) | 618 | if (found_key.offset >= inode->i_size) |
587 | del_item = 1; | 619 | del_item = 1; |
588 | else | 620 | else |
589 | del_item = 0; | 621 | del_item = 0; |
@@ -591,30 +623,31 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
591 | 623 | ||
592 | /* FIXME, shrink the extent if the ref count is only 1 */ | 624 | /* FIXME, shrink the extent if the ref count is only 1 */ |
593 | if (found_type == BTRFS_EXTENT_DATA_KEY && | 625 | if (found_type == BTRFS_EXTENT_DATA_KEY && |
594 | btrfs_file_extent_type(fi) != | 626 | btrfs_file_extent_type(leaf, fi) != |
595 | BTRFS_FILE_EXTENT_INLINE) { | 627 | BTRFS_FILE_EXTENT_INLINE) { |
596 | u64 num_dec; | 628 | u64 num_dec; |
597 | extent_start = btrfs_file_extent_disk_blocknr(fi); | 629 | extent_start = btrfs_file_extent_disk_blocknr(leaf, fi); |
598 | if (!del_item) { | 630 | if (!del_item) { |
599 | u64 orig_num_blocks = | 631 | u64 orig_num_blocks = |
600 | btrfs_file_extent_num_blocks(fi); | 632 | btrfs_file_extent_num_blocks(leaf, fi); |
601 | extent_num_blocks = inode->i_size - | 633 | extent_num_blocks = inode->i_size - |
602 | btrfs_disk_key_offset(found_key) + | 634 | found_key.offset + root->sectorsize - 1; |
603 | root->blocksize - 1; | ||
604 | extent_num_blocks >>= inode->i_blkbits; | 635 | extent_num_blocks >>= inode->i_blkbits; |
605 | btrfs_set_file_extent_num_blocks(fi, | 636 | btrfs_set_file_extent_num_blocks(leaf, fi, |
606 | extent_num_blocks); | 637 | extent_num_blocks); |
607 | num_dec = (orig_num_blocks - | 638 | num_dec = (orig_num_blocks - |
608 | extent_num_blocks) << 3; | 639 | extent_num_blocks) << 3; |
609 | if (extent_start != 0) { | 640 | if (extent_start != 0) { |
610 | inode->i_blocks -= num_dec; | 641 | inode->i_blocks -= num_dec; |
611 | } | 642 | } |
612 | btrfs_mark_buffer_dirty(path->nodes[0]); | 643 | btrfs_mark_buffer_dirty(leaf); |
613 | } else { | 644 | } else { |
614 | extent_num_blocks = | 645 | extent_num_blocks = |
615 | btrfs_file_extent_disk_num_blocks(fi); | 646 | btrfs_file_extent_disk_num_blocks(leaf, |
647 | fi); | ||
616 | /* FIXME blocksize != 4096 */ | 648 | /* FIXME blocksize != 4096 */ |
617 | num_dec = btrfs_file_extent_num_blocks(fi) << 3; | 649 | num_dec = btrfs_file_extent_num_blocks(leaf, |
650 | fi) << 3; | ||
618 | if (extent_start != 0) { | 651 | if (extent_start != 0) { |
619 | found_extent = 1; | 652 | found_extent = 1; |
620 | inode->i_blocks -= num_dec; | 653 | inode->i_blocks -= num_dec; |
@@ -725,7 +758,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
725 | struct btrfs_root *root = BTRFS_I(inode)->root; | 758 | struct btrfs_root *root = BTRFS_I(inode)->root; |
726 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 759 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
727 | 760 | ||
728 | u64 mask = root->blocksize - 1; | 761 | u64 mask = root->sectorsize - 1; |
729 | u64 pos = (inode->i_size + mask) & ~mask; | 762 | u64 pos = (inode->i_size + mask) & ~mask; |
730 | u64 block_end = attr->ia_size | mask; | 763 | u64 block_end = attr->ia_size | mask; |
731 | u64 hole_size; | 764 | u64 hole_size; |
@@ -771,9 +804,11 @@ void btrfs_delete_inode(struct inode *inode) | |||
771 | if (is_bad_inode(inode)) { | 804 | if (is_bad_inode(inode)) { |
772 | goto no_delete; | 805 | goto no_delete; |
773 | } | 806 | } |
807 | |||
774 | inode->i_size = 0; | 808 | inode->i_size = 0; |
775 | mutex_lock(&root->fs_info->fs_mutex); | 809 | mutex_lock(&root->fs_info->fs_mutex); |
776 | trans = btrfs_start_transaction(root, 1); | 810 | trans = btrfs_start_transaction(root, 1); |
811 | |||
777 | btrfs_set_trans_block_group(trans, inode); | 812 | btrfs_set_trans_block_group(trans, inode); |
778 | ret = btrfs_truncate_in_trans(trans, root, inode); | 813 | ret = btrfs_truncate_in_trans(trans, root, inode); |
779 | if (ret) | 814 | if (ret) |
@@ -782,6 +817,7 @@ void btrfs_delete_inode(struct inode *inode) | |||
782 | if (ret) | 817 | if (ret) |
783 | goto no_delete_lock; | 818 | goto no_delete_lock; |
784 | nr = trans->blocks_used; | 819 | nr = trans->blocks_used; |
820 | |||
785 | btrfs_end_transaction(trans, root); | 821 | btrfs_end_transaction(trans, root); |
786 | mutex_unlock(&root->fs_info->fs_mutex); | 822 | mutex_unlock(&root->fs_info->fs_mutex); |
787 | btrfs_btree_balance_dirty(root, nr); | 823 | btrfs_btree_balance_dirty(root, nr); |
@@ -819,7 +855,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, | |||
819 | ret = 0; | 855 | ret = 0; |
820 | goto out; | 856 | goto out; |
821 | } | 857 | } |
822 | btrfs_disk_key_to_cpu(location, &di->location); | 858 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, location); |
823 | out: | 859 | out: |
824 | btrfs_release_path(root, path); | 860 | btrfs_release_path(root, path); |
825 | btrfs_free_path(path); | 861 | btrfs_free_path(path); |
@@ -856,7 +892,6 @@ static int fixup_tree_root_location(struct btrfs_root *root, | |||
856 | 892 | ||
857 | ri = &(*sub_root)->root_item; | 893 | ri = &(*sub_root)->root_item; |
858 | location->objectid = btrfs_root_dirid(ri); | 894 | location->objectid = btrfs_root_dirid(ri); |
859 | location->flags = 0; | ||
860 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | 895 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); |
861 | location->offset = 0; | 896 | location->offset = 0; |
862 | 897 | ||
@@ -908,11 +943,14 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | |||
908 | 943 | ||
909 | if (dentry->d_name.len > BTRFS_NAME_LEN) | 944 | if (dentry->d_name.len > BTRFS_NAME_LEN) |
910 | return ERR_PTR(-ENAMETOOLONG); | 945 | return ERR_PTR(-ENAMETOOLONG); |
946 | |||
911 | mutex_lock(&root->fs_info->fs_mutex); | 947 | mutex_lock(&root->fs_info->fs_mutex); |
912 | ret = btrfs_inode_by_name(dir, dentry, &location); | 948 | ret = btrfs_inode_by_name(dir, dentry, &location); |
913 | mutex_unlock(&root->fs_info->fs_mutex); | 949 | mutex_unlock(&root->fs_info->fs_mutex); |
950 | |||
914 | if (ret < 0) | 951 | if (ret < 0) |
915 | return ERR_PTR(ret); | 952 | return ERR_PTR(ret); |
953 | |||
916 | inode = NULL; | 954 | inode = NULL; |
917 | if (location.objectid) { | 955 | if (location.objectid) { |
918 | ret = fixup_tree_root_location(root, &location, &sub_root, | 956 | ret = fixup_tree_root_location(root, &location, &sub_root, |
@@ -952,10 +990,11 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
952 | struct btrfs_item *item; | 990 | struct btrfs_item *item; |
953 | struct btrfs_dir_item *di; | 991 | struct btrfs_dir_item *di; |
954 | struct btrfs_key key; | 992 | struct btrfs_key key; |
993 | struct btrfs_key found_key; | ||
955 | struct btrfs_path *path; | 994 | struct btrfs_path *path; |
956 | int ret; | 995 | int ret; |
957 | u32 nritems; | 996 | u32 nritems; |
958 | struct btrfs_leaf *leaf; | 997 | struct extent_buffer *leaf; |
959 | int slot; | 998 | int slot; |
960 | int advance; | 999 | int advance; |
961 | unsigned char d_type; | 1000 | unsigned char d_type; |
@@ -964,15 +1003,19 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
964 | u32 di_total; | 1003 | u32 di_total; |
965 | u32 di_len; | 1004 | u32 di_len; |
966 | int key_type = BTRFS_DIR_INDEX_KEY; | 1005 | int key_type = BTRFS_DIR_INDEX_KEY; |
1006 | char tmp_name[32]; | ||
1007 | char *name_ptr; | ||
1008 | int name_len; | ||
967 | 1009 | ||
968 | /* FIXME, use a real flag for deciding about the key type */ | 1010 | /* FIXME, use a real flag for deciding about the key type */ |
969 | if (root->fs_info->tree_root == root) | 1011 | if (root->fs_info->tree_root == root) |
970 | key_type = BTRFS_DIR_ITEM_KEY; | 1012 | key_type = BTRFS_DIR_ITEM_KEY; |
1013 | |||
971 | mutex_lock(&root->fs_info->fs_mutex); | 1014 | mutex_lock(&root->fs_info->fs_mutex); |
972 | key.objectid = inode->i_ino; | 1015 | key.objectid = inode->i_ino; |
973 | key.flags = 0; | ||
974 | btrfs_set_key_type(&key, key_type); | 1016 | btrfs_set_key_type(&key, key_type); |
975 | key.offset = filp->f_pos; | 1017 | key.offset = filp->f_pos; |
1018 | |||
976 | path = btrfs_alloc_path(); | 1019 | path = btrfs_alloc_path(); |
977 | path->reada = 2; | 1020 | path->reada = 2; |
978 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 1021 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
@@ -980,16 +1023,16 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
980 | goto err; | 1023 | goto err; |
981 | advance = 0; | 1024 | advance = 0; |
982 | while(1) { | 1025 | while(1) { |
983 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 1026 | leaf = path->nodes[0]; |
984 | nritems = btrfs_header_nritems(&leaf->header); | 1027 | nritems = btrfs_header_nritems(leaf); |
985 | slot = path->slots[0]; | 1028 | slot = path->slots[0]; |
986 | if (advance || slot >= nritems) { | 1029 | if (advance || slot >= nritems) { |
987 | if (slot >= nritems -1) { | 1030 | if (slot >= nritems -1) { |
988 | ret = btrfs_next_leaf(root, path); | 1031 | ret = btrfs_next_leaf(root, path); |
989 | if (ret) | 1032 | if (ret) |
990 | break; | 1033 | break; |
991 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 1034 | leaf = path->nodes[0]; |
992 | nritems = btrfs_header_nritems(&leaf->header); | 1035 | nritems = btrfs_header_nritems(leaf); |
993 | slot = path->slots[0]; | 1036 | slot = path->slots[0]; |
994 | } else { | 1037 | } else { |
995 | slot++; | 1038 | slot++; |
@@ -997,28 +1040,48 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
997 | } | 1040 | } |
998 | } | 1041 | } |
999 | advance = 1; | 1042 | advance = 1; |
1000 | item = leaf->items + slot; | 1043 | item = btrfs_item_nr(leaf, slot); |
1001 | if (btrfs_disk_key_objectid(&item->key) != key.objectid) | 1044 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
1045 | |||
1046 | if (found_key.objectid != key.objectid) | ||
1002 | break; | 1047 | break; |
1003 | if (btrfs_disk_key_type(&item->key) != key_type) | 1048 | if (btrfs_key_type(&found_key) != key_type) |
1004 | break; | 1049 | break; |
1005 | if (btrfs_disk_key_offset(&item->key) < filp->f_pos) | 1050 | if (found_key.offset < filp->f_pos) |
1006 | continue; | 1051 | continue; |
1007 | filp->f_pos = btrfs_disk_key_offset(&item->key); | 1052 | |
1053 | filp->f_pos = found_key.offset; | ||
1008 | advance = 1; | 1054 | advance = 1; |
1009 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); | 1055 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); |
1010 | di_cur = 0; | 1056 | di_cur = 0; |
1011 | di_total = btrfs_item_size(leaf->items + slot); | 1057 | di_total = btrfs_item_size(leaf, item); |
1012 | while(di_cur < di_total) { | 1058 | while(di_cur < di_total) { |
1013 | d_type = btrfs_filetype_table[btrfs_dir_type(di)]; | 1059 | struct btrfs_key location; |
1014 | over = filldir(dirent, (const char *)(di + 1), | 1060 | |
1015 | btrfs_dir_name_len(di), | 1061 | name_len = btrfs_dir_name_len(leaf, di); |
1016 | btrfs_disk_key_offset(&item->key), | 1062 | if (name_len < 32) { |
1017 | btrfs_disk_key_objectid(&di->location), | 1063 | name_ptr = tmp_name; |
1064 | } else { | ||
1065 | name_ptr = kmalloc(name_len, GFP_NOFS); | ||
1066 | BUG_ON(!name_ptr); | ||
1067 | } | ||
1068 | read_extent_buffer(leaf, name_ptr, | ||
1069 | (unsigned long)(di + 1), name_len); | ||
1070 | |||
1071 | d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; | ||
1072 | btrfs_dir_item_key_to_cpu(leaf, di, &location); | ||
1073 | |||
1074 | over = filldir(dirent, name_ptr, name_len, | ||
1075 | found_key.offset, | ||
1076 | location.objectid, | ||
1018 | d_type); | 1077 | d_type); |
1078 | |||
1079 | if (name_ptr != tmp_name) | ||
1080 | kfree(name_ptr); | ||
1081 | |||
1019 | if (over) | 1082 | if (over) |
1020 | goto nopos; | 1083 | goto nopos; |
1021 | di_len = btrfs_dir_name_len(di) + sizeof(*di); | 1084 | di_len = btrfs_dir_name_len(leaf, di) + sizeof(*di); |
1022 | di_cur += di_len; | 1085 | di_cur += di_len; |
1023 | di = (struct btrfs_dir_item *)((char *)di + di_len); | 1086 | di = (struct btrfs_dir_item *)((char *)di + di_len); |
1024 | } | 1087 | } |
@@ -1075,11 +1138,15 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
1075 | int mode) | 1138 | int mode) |
1076 | { | 1139 | { |
1077 | struct inode *inode; | 1140 | struct inode *inode; |
1078 | struct btrfs_inode_item inode_item; | 1141 | struct btrfs_inode_item *inode_item; |
1079 | struct btrfs_key *location; | 1142 | struct btrfs_key *location; |
1143 | struct btrfs_path *path; | ||
1080 | int ret; | 1144 | int ret; |
1081 | int owner; | 1145 | int owner; |
1082 | 1146 | ||
1147 | path = btrfs_alloc_path(); | ||
1148 | BUG_ON(!path); | ||
1149 | |||
1083 | inode = new_inode(root->fs_info->sb); | 1150 | inode = new_inode(root->fs_info->sb); |
1084 | if (!inode) | 1151 | if (!inode) |
1085 | return ERR_PTR(-ENOMEM); | 1152 | return ERR_PTR(-ENOMEM); |
@@ -1095,24 +1162,32 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
1095 | group = btrfs_find_block_group(root, group, 0, 0, owner); | 1162 | group = btrfs_find_block_group(root, group, 0, 0, owner); |
1096 | BTRFS_I(inode)->block_group = group; | 1163 | BTRFS_I(inode)->block_group = group; |
1097 | 1164 | ||
1165 | ret = btrfs_insert_empty_inode(trans, root, path, objectid); | ||
1166 | if (ret) | ||
1167 | goto fail; | ||
1168 | |||
1098 | inode->i_uid = current->fsuid; | 1169 | inode->i_uid = current->fsuid; |
1099 | inode->i_gid = current->fsgid; | 1170 | inode->i_gid = current->fsgid; |
1100 | inode->i_mode = mode; | 1171 | inode->i_mode = mode; |
1101 | inode->i_ino = objectid; | 1172 | inode->i_ino = objectid; |
1102 | inode->i_blocks = 0; | 1173 | inode->i_blocks = 0; |
1103 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 1174 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
1104 | fill_inode_item(&inode_item, inode); | 1175 | inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], |
1176 | struct btrfs_inode_item); | ||
1177 | fill_inode_item(path->nodes[0], inode_item, inode); | ||
1178 | btrfs_mark_buffer_dirty(path->nodes[0]); | ||
1179 | btrfs_free_path(path); | ||
1180 | |||
1105 | location = &BTRFS_I(inode)->location; | 1181 | location = &BTRFS_I(inode)->location; |
1106 | location->objectid = objectid; | 1182 | location->objectid = objectid; |
1107 | location->flags = 0; | ||
1108 | location->offset = 0; | 1183 | location->offset = 0; |
1109 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | 1184 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); |
1110 | 1185 | ||
1111 | ret = btrfs_insert_inode(trans, root, objectid, &inode_item); | ||
1112 | if (ret) | ||
1113 | return ERR_PTR(ret); | ||
1114 | insert_inode_hash(inode); | 1186 | insert_inode_hash(inode); |
1115 | return inode; | 1187 | return inode; |
1188 | fail: | ||
1189 | btrfs_free_path(path); | ||
1190 | return ERR_PTR(ret); | ||
1116 | } | 1191 | } |
1117 | 1192 | ||
1118 | static inline u8 btrfs_inode_type(struct inode *inode) | 1193 | static inline u8 btrfs_inode_type(struct inode *inode) |
@@ -1127,8 +1202,8 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
1127 | struct btrfs_key key; | 1202 | struct btrfs_key key; |
1128 | struct btrfs_root *root = BTRFS_I(dentry->d_parent->d_inode)->root; | 1203 | struct btrfs_root *root = BTRFS_I(dentry->d_parent->d_inode)->root; |
1129 | struct inode *parent_inode; | 1204 | struct inode *parent_inode; |
1205 | |||
1130 | key.objectid = inode->i_ino; | 1206 | key.objectid = inode->i_ino; |
1131 | key.flags = 0; | ||
1132 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 1207 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
1133 | key.offset = 0; | 1208 | key.offset = 0; |
1134 | 1209 | ||
@@ -1285,14 +1360,18 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1285 | inc_nlink(inode); | 1360 | inc_nlink(inode); |
1286 | mutex_lock(&root->fs_info->fs_mutex); | 1361 | mutex_lock(&root->fs_info->fs_mutex); |
1287 | trans = btrfs_start_transaction(root, 1); | 1362 | trans = btrfs_start_transaction(root, 1); |
1363 | |||
1288 | btrfs_set_trans_block_group(trans, dir); | 1364 | btrfs_set_trans_block_group(trans, dir); |
1289 | atomic_inc(&inode->i_count); | 1365 | atomic_inc(&inode->i_count); |
1290 | err = btrfs_add_nondir(trans, dentry, inode); | 1366 | err = btrfs_add_nondir(trans, dentry, inode); |
1367 | |||
1291 | if (err) | 1368 | if (err) |
1292 | drop_inode = 1; | 1369 | drop_inode = 1; |
1370 | |||
1293 | dir->i_sb->s_dirt = 1; | 1371 | dir->i_sb->s_dirt = 1; |
1294 | btrfs_update_inode_block_group(trans, dir); | 1372 | btrfs_update_inode_block_group(trans, dir); |
1295 | err = btrfs_update_inode(trans, root, inode); | 1373 | err = btrfs_update_inode(trans, root, inode); |
1374 | |||
1296 | if (err) | 1375 | if (err) |
1297 | drop_inode = 1; | 1376 | drop_inode = 1; |
1298 | 1377 | ||
@@ -1321,13 +1400,13 @@ static int btrfs_make_empty_dir(struct btrfs_trans_handle *trans, | |||
1321 | 1400 | ||
1322 | key.objectid = objectid; | 1401 | key.objectid = objectid; |
1323 | key.offset = 0; | 1402 | key.offset = 0; |
1324 | key.flags = 0; | ||
1325 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 1403 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
1326 | 1404 | ||
1327 | ret = btrfs_insert_dir_item(trans, root, buf, 1, objectid, | 1405 | ret = btrfs_insert_dir_item(trans, root, buf, 1, objectid, |
1328 | &key, BTRFS_FT_DIR); | 1406 | &key, BTRFS_FT_DIR); |
1329 | if (ret) | 1407 | if (ret) |
1330 | goto error; | 1408 | goto error; |
1409 | |||
1331 | key.objectid = dirid; | 1410 | key.objectid = dirid; |
1332 | ret = btrfs_insert_dir_item(trans, root, buf, 2, objectid, | 1411 | ret = btrfs_insert_dir_item(trans, root, buf, 2, objectid, |
1333 | &key, BTRFS_FT_DIR); | 1412 | &key, BTRFS_FT_DIR); |
@@ -1350,6 +1429,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1350 | mutex_lock(&root->fs_info->fs_mutex); | 1429 | mutex_lock(&root->fs_info->fs_mutex); |
1351 | trans = btrfs_start_transaction(root, 1); | 1430 | trans = btrfs_start_transaction(root, 1); |
1352 | btrfs_set_trans_block_group(trans, dir); | 1431 | btrfs_set_trans_block_group(trans, dir); |
1432 | |||
1353 | if (IS_ERR(trans)) { | 1433 | if (IS_ERR(trans)) { |
1354 | err = PTR_ERR(trans); | 1434 | err = PTR_ERR(trans); |
1355 | goto out_unlock; | 1435 | goto out_unlock; |
@@ -1367,6 +1447,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1367 | err = PTR_ERR(inode); | 1447 | err = PTR_ERR(inode); |
1368 | goto out_fail; | 1448 | goto out_fail; |
1369 | } | 1449 | } |
1450 | |||
1370 | drop_on_err = 1; | 1451 | drop_on_err = 1; |
1371 | inode->i_op = &btrfs_dir_inode_operations; | 1452 | inode->i_op = &btrfs_dir_inode_operations; |
1372 | inode->i_fop = &btrfs_dir_file_operations; | 1453 | inode->i_fop = &btrfs_dir_file_operations; |
@@ -1380,9 +1461,11 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1380 | err = btrfs_update_inode(trans, root, inode); | 1461 | err = btrfs_update_inode(trans, root, inode); |
1381 | if (err) | 1462 | if (err) |
1382 | goto out_fail; | 1463 | goto out_fail; |
1464 | |||
1383 | err = btrfs_add_link(trans, dentry, inode); | 1465 | err = btrfs_add_link(trans, dentry, inode); |
1384 | if (err) | 1466 | if (err) |
1385 | goto out_fail; | 1467 | goto out_fail; |
1468 | |||
1386 | d_instantiate(dentry, inode); | 1469 | d_instantiate(dentry, inode); |
1387 | drop_on_err = 0; | 1470 | drop_on_err = 0; |
1388 | dir->i_sb->s_dirt = 1; | 1471 | dir->i_sb->s_dirt = 1; |
@@ -1392,6 +1475,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1392 | out_fail: | 1475 | out_fail: |
1393 | nr = trans->blocks_used; | 1476 | nr = trans->blocks_used; |
1394 | btrfs_end_transaction(trans, root); | 1477 | btrfs_end_transaction(trans, root); |
1478 | |||
1395 | out_unlock: | 1479 | out_unlock: |
1396 | mutex_unlock(&root->fs_info->fs_mutex); | 1480 | mutex_unlock(&root->fs_info->fs_mutex); |
1397 | if (drop_on_err) | 1481 | if (drop_on_err) |
@@ -1415,8 +1499,8 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
1415 | struct btrfs_path *path; | 1499 | struct btrfs_path *path; |
1416 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1500 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1417 | struct btrfs_file_extent_item *item; | 1501 | struct btrfs_file_extent_item *item; |
1418 | struct btrfs_leaf *leaf; | 1502 | struct extent_buffer *leaf; |
1419 | struct btrfs_disk_key *found_key; | 1503 | struct btrfs_key found_key; |
1420 | struct extent_map *em = NULL; | 1504 | struct extent_map *em = NULL; |
1421 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 1505 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
1422 | struct btrfs_trans_handle *trans = NULL; | 1506 | struct btrfs_trans_handle *trans = NULL; |
@@ -1436,8 +1520,8 @@ again: | |||
1436 | err = -ENOMEM; | 1520 | err = -ENOMEM; |
1437 | goto out; | 1521 | goto out; |
1438 | } | 1522 | } |
1439 | em->start = 0; | 1523 | em->start = EXTENT_MAP_HOLE; |
1440 | em->end = 0; | 1524 | em->end = EXTENT_MAP_HOLE; |
1441 | } | 1525 | } |
1442 | em->bdev = inode->i_sb->s_bdev; | 1526 | em->bdev = inode->i_sb->s_bdev; |
1443 | ret = btrfs_lookup_file_extent(NULL, root, path, | 1527 | ret = btrfs_lookup_file_extent(NULL, root, path, |
@@ -1453,25 +1537,27 @@ again: | |||
1453 | path->slots[0]--; | 1537 | path->slots[0]--; |
1454 | } | 1538 | } |
1455 | 1539 | ||
1456 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], | 1540 | leaf = path->nodes[0]; |
1541 | item = btrfs_item_ptr(leaf, path->slots[0], | ||
1457 | struct btrfs_file_extent_item); | 1542 | struct btrfs_file_extent_item); |
1458 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 1543 | |
1459 | blocknr = btrfs_file_extent_disk_blocknr(item); | 1544 | blocknr = btrfs_file_extent_disk_blocknr(leaf, item); |
1460 | blocknr += btrfs_file_extent_offset(item); | 1545 | blocknr += btrfs_file_extent_offset(leaf, item); |
1461 | 1546 | ||
1462 | /* are we inside the extent that was found? */ | 1547 | /* are we inside the extent that was found? */ |
1463 | found_key = &leaf->items[path->slots[0]].key; | 1548 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
1464 | found_type = btrfs_disk_key_type(found_key); | 1549 | found_type = btrfs_key_type(&found_key); |
1465 | if (btrfs_disk_key_objectid(found_key) != objectid || | 1550 | if (found_key.objectid != objectid || |
1466 | found_type != BTRFS_EXTENT_DATA_KEY) { | 1551 | found_type != BTRFS_EXTENT_DATA_KEY) { |
1467 | goto not_found; | 1552 | goto not_found; |
1468 | } | 1553 | } |
1469 | 1554 | ||
1470 | found_type = btrfs_file_extent_type(item); | 1555 | found_type = btrfs_file_extent_type(leaf, item); |
1471 | extent_start = btrfs_disk_key_offset(&leaf->items[path->slots[0]].key); | 1556 | extent_start = found_key.offset; |
1472 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 1557 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
1473 | extent_end = extent_start + | 1558 | extent_end = extent_start + |
1474 | (btrfs_file_extent_num_blocks(item) << inode->i_blkbits); | 1559 | (btrfs_file_extent_num_blocks(leaf, item) << |
1560 | inode->i_blkbits); | ||
1475 | err = 0; | 1561 | err = 0; |
1476 | if (start < extent_start || start >= extent_end) { | 1562 | if (start < extent_start || start >= extent_end) { |
1477 | em->start = start; | 1563 | em->start = start; |
@@ -1484,28 +1570,29 @@ again: | |||
1484 | } | 1570 | } |
1485 | goto not_found_em; | 1571 | goto not_found_em; |
1486 | } | 1572 | } |
1487 | if (btrfs_file_extent_disk_blocknr(item) == 0) { | 1573 | if (btrfs_file_extent_disk_blocknr(leaf, item) == 0) { |
1488 | em->start = extent_start; | 1574 | em->start = extent_start; |
1489 | em->end = extent_end - 1; | 1575 | em->end = extent_end - 1; |
1490 | em->block_start = 0; | 1576 | em->block_start = EXTENT_MAP_HOLE; |
1491 | em->block_end = 0; | 1577 | em->block_end = EXTENT_MAP_HOLE; |
1492 | goto insert; | 1578 | goto insert; |
1493 | } | 1579 | } |
1494 | em->block_start = blocknr << inode->i_blkbits; | 1580 | em->block_start = blocknr << inode->i_blkbits; |
1495 | em->block_end = em->block_start + | 1581 | em->block_end = em->block_start + |
1496 | (btrfs_file_extent_num_blocks(item) << | 1582 | (btrfs_file_extent_num_blocks(leaf, item) << |
1497 | inode->i_blkbits) - 1; | 1583 | inode->i_blkbits) - 1; |
1498 | em->start = extent_start; | 1584 | em->start = extent_start; |
1499 | em->end = extent_end - 1; | 1585 | em->end = extent_end - 1; |
1500 | goto insert; | 1586 | goto insert; |
1501 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 1587 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
1502 | char *ptr; | 1588 | unsigned long ptr; |
1503 | char *map; | 1589 | char *map; |
1504 | u32 size; | 1590 | u32 size; |
1505 | 1591 | ||
1506 | size = btrfs_file_extent_inline_len(leaf->items + | 1592 | size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf, |
1507 | path->slots[0]); | 1593 | path->slots[0])); |
1508 | extent_end = extent_start | ((u64)root->blocksize - 1); | 1594 | |
1595 | extent_end = extent_start | ((u64)root->sectorsize - 1); | ||
1509 | if (start < extent_start || start >= extent_end) { | 1596 | if (start < extent_start || start >= extent_end) { |
1510 | em->start = start; | 1597 | em->start = start; |
1511 | if (start < extent_start) { | 1598 | if (start < extent_start) { |
@@ -1517,18 +1604,21 @@ again: | |||
1517 | } | 1604 | } |
1518 | goto not_found_em; | 1605 | goto not_found_em; |
1519 | } | 1606 | } |
1607 | |||
1520 | em->block_start = EXTENT_MAP_INLINE; | 1608 | em->block_start = EXTENT_MAP_INLINE; |
1521 | em->block_end = EXTENT_MAP_INLINE; | 1609 | em->block_end = EXTENT_MAP_INLINE; |
1522 | em->start = extent_start; | 1610 | em->start = extent_start; |
1523 | em->end = extent_end; | 1611 | em->end = extent_end; |
1612 | |||
1524 | if (!page) { | 1613 | if (!page) { |
1525 | goto insert; | 1614 | goto insert; |
1526 | } | 1615 | } |
1616 | |||
1527 | ptr = btrfs_file_extent_inline_start(item); | 1617 | ptr = btrfs_file_extent_inline_start(item); |
1528 | map = kmap(page); | 1618 | map = kmap(page); |
1529 | memcpy(map + page_offset, ptr, size); | 1619 | read_extent_buffer(leaf, map + page_offset, ptr, size); |
1530 | memset(map + page_offset + size, 0, | 1620 | memset(map + page_offset + size, 0, |
1531 | root->blocksize - (page_offset + size)); | 1621 | root->sectorsize - (page_offset + size)); |
1532 | flush_dcache_page(page); | 1622 | flush_dcache_page(page); |
1533 | kunmap(page); | 1623 | kunmap(page); |
1534 | set_extent_uptodate(em_tree, extent_start, | 1624 | set_extent_uptodate(em_tree, extent_start, |
@@ -1542,8 +1632,8 @@ not_found: | |||
1542 | em->start = start; | 1632 | em->start = start; |
1543 | em->end = end; | 1633 | em->end = end; |
1544 | not_found_em: | 1634 | not_found_em: |
1545 | em->block_start = 0; | 1635 | em->block_start = EXTENT_MAP_HOLE; |
1546 | em->block_end = 0; | 1636 | em->block_end = EXTENT_MAP_HOLE; |
1547 | insert: | 1637 | insert: |
1548 | btrfs_release_path(root, path); | 1638 | btrfs_release_path(root, path); |
1549 | if (em->start > start || em->end < start) { | 1639 | if (em->start > start || em->end < start) { |
@@ -1712,6 +1802,7 @@ static void btrfs_truncate(struct inode *inode) | |||
1712 | ret = btrfs_truncate_in_trans(trans, root, inode); | 1802 | ret = btrfs_truncate_in_trans(trans, root, inode); |
1713 | btrfs_update_inode(trans, root, inode); | 1803 | btrfs_update_inode(trans, root, inode); |
1714 | nr = trans->blocks_used; | 1804 | nr = trans->blocks_used; |
1805 | |||
1715 | ret = btrfs_end_transaction(trans, root); | 1806 | ret = btrfs_end_transaction(trans, root); |
1716 | BUG_ON(ret); | 1807 | BUG_ON(ret); |
1717 | mutex_unlock(&root->fs_info->fs_mutex); | 1808 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -1731,8 +1822,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1731 | struct btrfs_key key; | 1822 | struct btrfs_key key; |
1732 | struct btrfs_root_item root_item; | 1823 | struct btrfs_root_item root_item; |
1733 | struct btrfs_inode_item *inode_item; | 1824 | struct btrfs_inode_item *inode_item; |
1734 | struct buffer_head *subvol; | 1825 | struct extent_buffer *leaf; |
1735 | struct btrfs_leaf *leaf; | ||
1736 | struct btrfs_root *new_root; | 1826 | struct btrfs_root *new_root; |
1737 | struct inode *inode; | 1827 | struct inode *inode; |
1738 | struct inode *dir; | 1828 | struct inode *dir; |
@@ -1746,34 +1836,37 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1746 | trans = btrfs_start_transaction(root, 1); | 1836 | trans = btrfs_start_transaction(root, 1); |
1747 | BUG_ON(!trans); | 1837 | BUG_ON(!trans); |
1748 | 1838 | ||
1749 | subvol = btrfs_alloc_free_block(trans, root, 0, 0); | 1839 | leaf = btrfs_alloc_free_block(trans, root, 0, 0); |
1750 | if (IS_ERR(subvol)) | 1840 | if (IS_ERR(leaf)) |
1751 | return PTR_ERR(subvol); | 1841 | return PTR_ERR(leaf); |
1752 | leaf = btrfs_buffer_leaf(subvol); | 1842 | |
1753 | btrfs_set_header_nritems(&leaf->header, 0); | 1843 | btrfs_set_header_nritems(leaf, 0); |
1754 | btrfs_set_header_level(&leaf->header, 0); | 1844 | btrfs_set_header_level(leaf, 0); |
1755 | btrfs_set_header_blocknr(&leaf->header, bh_blocknr(subvol)); | 1845 | btrfs_set_header_blocknr(leaf, extent_buffer_blocknr(leaf)); |
1756 | btrfs_set_header_generation(&leaf->header, trans->transid); | 1846 | btrfs_set_header_generation(leaf, trans->transid); |
1757 | btrfs_set_header_owner(&leaf->header, root->root_key.objectid); | 1847 | btrfs_set_header_owner(leaf, root->root_key.objectid); |
1758 | memcpy(leaf->header.fsid, root->fs_info->disk_super->fsid, | 1848 | write_extent_buffer(leaf, root->fs_info->fsid, |
1759 | sizeof(leaf->header.fsid)); | 1849 | (unsigned long)btrfs_header_fsid(leaf), |
1760 | btrfs_mark_buffer_dirty(subvol); | 1850 | BTRFS_FSID_SIZE); |
1851 | btrfs_mark_buffer_dirty(leaf); | ||
1761 | 1852 | ||
1762 | inode_item = &root_item.inode; | 1853 | inode_item = &root_item.inode; |
1763 | memset(inode_item, 0, sizeof(*inode_item)); | 1854 | memset(inode_item, 0, sizeof(*inode_item)); |
1764 | btrfs_set_inode_generation(inode_item, 1); | 1855 | inode_item->generation = cpu_to_le64(1); |
1765 | btrfs_set_inode_size(inode_item, 3); | 1856 | inode_item->size = cpu_to_le64(3); |
1766 | btrfs_set_inode_nlink(inode_item, 1); | 1857 | inode_item->nlink = cpu_to_le32(1); |
1767 | btrfs_set_inode_nblocks(inode_item, 1); | 1858 | inode_item->nblocks = cpu_to_le64(1); |
1768 | btrfs_set_inode_mode(inode_item, S_IFDIR | 0755); | 1859 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); |
1769 | 1860 | ||
1770 | btrfs_set_root_blocknr(&root_item, bh_blocknr(subvol)); | 1861 | btrfs_set_root_blocknr(&root_item, extent_buffer_blocknr(leaf)); |
1771 | btrfs_set_root_refs(&root_item, 1); | 1862 | btrfs_set_root_refs(&root_item, 1); |
1772 | btrfs_set_root_blocks_used(&root_item, 0); | 1863 | btrfs_set_root_used(&root_item, 0); |
1864 | |||
1773 | memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); | 1865 | memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); |
1774 | root_item.drop_level = 0; | 1866 | root_item.drop_level = 0; |
1775 | brelse(subvol); | 1867 | |
1776 | subvol = NULL; | 1868 | free_extent_buffer(leaf); |
1869 | leaf = NULL; | ||
1777 | 1870 | ||
1778 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | 1871 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, |
1779 | 0, &objectid); | 1872 | 0, &objectid); |
@@ -1784,7 +1877,6 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1784 | 1877 | ||
1785 | key.objectid = objectid; | 1878 | key.objectid = objectid; |
1786 | key.offset = 1; | 1879 | key.offset = 1; |
1787 | key.flags = 0; | ||
1788 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 1880 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
1789 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 1881 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
1790 | &root_item); | 1882 | &root_item); |
@@ -1845,7 +1937,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
1845 | struct btrfs_trans_handle *trans; | 1937 | struct btrfs_trans_handle *trans; |
1846 | struct btrfs_key key; | 1938 | struct btrfs_key key; |
1847 | struct btrfs_root_item new_root_item; | 1939 | struct btrfs_root_item new_root_item; |
1848 | struct buffer_head *tmp; | 1940 | struct extent_buffer *tmp; |
1849 | int ret; | 1941 | int ret; |
1850 | int err; | 1942 | int err; |
1851 | u64 objectid; | 1943 | u64 objectid; |
@@ -1876,10 +1968,11 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
1876 | 1968 | ||
1877 | key.objectid = objectid; | 1969 | key.objectid = objectid; |
1878 | key.offset = 1; | 1970 | key.offset = 1; |
1879 | key.flags = 0; | ||
1880 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 1971 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
1972 | |||
1881 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); | 1973 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); |
1882 | btrfs_set_root_blocknr(&new_root_item, bh_blocknr(root->node)); | 1974 | btrfs_set_root_blocknr(&new_root_item, |
1975 | extent_buffer_blocknr(root->node)); | ||
1883 | 1976 | ||
1884 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 1977 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
1885 | &new_root_item); | 1978 | &new_root_item); |
@@ -1904,8 +1997,10 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
1904 | fail: | 1997 | fail: |
1905 | nr = trans->blocks_used; | 1998 | nr = trans->blocks_used; |
1906 | err = btrfs_commit_transaction(trans, root); | 1999 | err = btrfs_commit_transaction(trans, root); |
2000 | |||
1907 | if (err && !ret) | 2001 | if (err && !ret) |
1908 | ret = err; | 2002 | ret = err; |
2003 | |||
1909 | mutex_unlock(&root->fs_info->fs_mutex); | 2004 | mutex_unlock(&root->fs_info->fs_mutex); |
1910 | up_write(&root->snap_sem); | 2005 | up_write(&root->snap_sem); |
1911 | btrfs_btree_balance_dirty(root, nr); | 2006 | btrfs_btree_balance_dirty(root, nr); |
@@ -1986,7 +2081,7 @@ static int btrfs_ioctl_snap_create(struct btrfs_root *root, void __user *arg) | |||
1986 | 2081 | ||
1987 | if (copy_from_user(&vol_args, arg, sizeof(vol_args))) | 2082 | if (copy_from_user(&vol_args, arg, sizeof(vol_args))) |
1988 | return -EFAULT; | 2083 | return -EFAULT; |
1989 | 2084 | ||
1990 | namelen = strlen(vol_args.name); | 2085 | namelen = strlen(vol_args.name); |
1991 | if (namelen > BTRFS_VOL_NAME_MAX) | 2086 | if (namelen > BTRFS_VOL_NAME_MAX) |
1992 | return -EINVAL; | 2087 | return -EINVAL; |
@@ -2164,8 +2259,10 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2164 | new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) { | 2259 | new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) { |
2165 | return -ENOTEMPTY; | 2260 | return -ENOTEMPTY; |
2166 | } | 2261 | } |
2262 | |||
2167 | mutex_lock(&root->fs_info->fs_mutex); | 2263 | mutex_lock(&root->fs_info->fs_mutex); |
2168 | trans = btrfs_start_transaction(root, 1); | 2264 | trans = btrfs_start_transaction(root, 1); |
2265 | |||
2169 | btrfs_set_trans_block_group(trans, new_dir); | 2266 | btrfs_set_trans_block_group(trans, new_dir); |
2170 | path = btrfs_alloc_path(); | 2267 | path = btrfs_alloc_path(); |
2171 | if (!path) { | 2268 | if (!path) { |
@@ -2177,9 +2274,10 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2177 | old_dir->i_ctime = old_dir->i_mtime = ctime; | 2274 | old_dir->i_ctime = old_dir->i_mtime = ctime; |
2178 | new_dir->i_ctime = new_dir->i_mtime = ctime; | 2275 | new_dir->i_ctime = new_dir->i_mtime = ctime; |
2179 | old_inode->i_ctime = ctime; | 2276 | old_inode->i_ctime = ctime; |
2277 | |||
2180 | if (S_ISDIR(old_inode->i_mode) && old_dir != new_dir) { | 2278 | if (S_ISDIR(old_inode->i_mode) && old_dir != new_dir) { |
2181 | struct btrfs_key *location = &BTRFS_I(new_dir)->location; | 2279 | struct btrfs_key *location = &BTRFS_I(new_dir)->location; |
2182 | u64 old_parent_oid; | 2280 | struct btrfs_key old_parent_key; |
2183 | di = btrfs_lookup_dir_item(trans, root, path, old_inode->i_ino, | 2281 | di = btrfs_lookup_dir_item(trans, root, path, old_inode->i_ino, |
2184 | "..", 2, -1); | 2282 | "..", 2, -1); |
2185 | if (IS_ERR(di)) { | 2283 | if (IS_ERR(di)) { |
@@ -2190,7 +2288,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2190 | ret = -ENOENT; | 2288 | ret = -ENOENT; |
2191 | goto out_fail; | 2289 | goto out_fail; |
2192 | } | 2290 | } |
2193 | old_parent_oid = btrfs_disk_key_objectid(&di->location); | 2291 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, &old_parent_key); |
2194 | ret = btrfs_del_item(trans, root, path); | 2292 | ret = btrfs_del_item(trans, root, path); |
2195 | if (ret) { | 2293 | if (ret) { |
2196 | goto out_fail; | 2294 | goto out_fail; |
@@ -2199,7 +2297,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2199 | 2297 | ||
2200 | di = btrfs_lookup_dir_index_item(trans, root, path, | 2298 | di = btrfs_lookup_dir_index_item(trans, root, path, |
2201 | old_inode->i_ino, | 2299 | old_inode->i_ino, |
2202 | old_parent_oid, | 2300 | old_parent_key.objectid, |
2203 | "..", 2, -1); | 2301 | "..", 2, -1); |
2204 | if (IS_ERR(di)) { | 2302 | if (IS_ERR(di)) { |
2205 | ret = PTR_ERR(di); | 2303 | ret = PTR_ERR(di); |
@@ -2257,8 +2355,9 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2257 | u64 objectid; | 2355 | u64 objectid; |
2258 | int name_len; | 2356 | int name_len; |
2259 | int datasize; | 2357 | int datasize; |
2260 | char *ptr; | 2358 | unsigned long ptr; |
2261 | struct btrfs_file_extent_item *ei; | 2359 | struct btrfs_file_extent_item *ei; |
2360 | struct extent_buffer *leaf; | ||
2262 | unsigned long nr; | 2361 | unsigned long nr; |
2263 | 2362 | ||
2264 | name_len = strlen(symname) + 1; | 2363 | name_len = strlen(symname) + 1; |
@@ -2302,7 +2401,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2302 | BUG_ON(!path); | 2401 | BUG_ON(!path); |
2303 | key.objectid = inode->i_ino; | 2402 | key.objectid = inode->i_ino; |
2304 | key.offset = 0; | 2403 | key.offset = 0; |
2305 | key.flags = 0; | ||
2306 | btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); | 2404 | btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); |
2307 | datasize = btrfs_file_extent_calc_inline_size(name_len); | 2405 | datasize = btrfs_file_extent_calc_inline_size(name_len); |
2308 | err = btrfs_insert_empty_item(trans, root, path, &key, | 2406 | err = btrfs_insert_empty_item(trans, root, path, &key, |
@@ -2311,16 +2409,17 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2311 | drop_inode = 1; | 2409 | drop_inode = 1; |
2312 | goto out_unlock; | 2410 | goto out_unlock; |
2313 | } | 2411 | } |
2314 | ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 2412 | leaf = path->nodes[0]; |
2315 | path->slots[0], struct btrfs_file_extent_item); | 2413 | ei = btrfs_item_ptr(leaf, path->slots[0], |
2316 | btrfs_set_file_extent_generation(ei, trans->transid); | 2414 | struct btrfs_file_extent_item); |
2317 | btrfs_set_file_extent_type(ei, | 2415 | btrfs_set_file_extent_generation(leaf, ei, trans->transid); |
2416 | btrfs_set_file_extent_type(leaf, ei, | ||
2318 | BTRFS_FILE_EXTENT_INLINE); | 2417 | BTRFS_FILE_EXTENT_INLINE); |
2319 | ptr = btrfs_file_extent_inline_start(ei); | 2418 | ptr = btrfs_file_extent_inline_start(ei); |
2320 | btrfs_memcpy(root, path->nodes[0]->b_data, | 2419 | write_extent_buffer(leaf, symname, ptr, name_len); |
2321 | ptr, symname, name_len); | 2420 | btrfs_mark_buffer_dirty(leaf); |
2322 | btrfs_mark_buffer_dirty(path->nodes[0]); | ||
2323 | btrfs_free_path(path); | 2421 | btrfs_free_path(path); |
2422 | |||
2324 | inode->i_op = &btrfs_symlink_inode_operations; | 2423 | inode->i_op = &btrfs_symlink_inode_operations; |
2325 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 2424 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
2326 | inode->i_size = name_len - 1; | 2425 | inode->i_size = name_len - 1; |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index bafa78603bd2..a825ce078a54 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -20,10 +20,10 @@ | |||
20 | #include "disk-io.h" | 20 | #include "disk-io.h" |
21 | #include "print-tree.h" | 21 | #include "print-tree.h" |
22 | 22 | ||
23 | void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) | 23 | void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) |
24 | { | 24 | { |
25 | int i; | 25 | int i; |
26 | u32 nr = btrfs_header_nritems(&l->header); | 26 | u32 nr = btrfs_header_nritems(l); |
27 | struct btrfs_item *item; | 27 | struct btrfs_item *item; |
28 | struct btrfs_extent_item *ei; | 28 | struct btrfs_extent_item *ei; |
29 | struct btrfs_root_item *ri; | 29 | struct btrfs_root_item *ri; |
@@ -31,119 +31,113 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) | |||
31 | struct btrfs_inode_item *ii; | 31 | struct btrfs_inode_item *ii; |
32 | struct btrfs_block_group_item *bi; | 32 | struct btrfs_block_group_item *bi; |
33 | struct btrfs_file_extent_item *fi; | 33 | struct btrfs_file_extent_item *fi; |
34 | struct btrfs_key key; | ||
35 | struct btrfs_key found_key; | ||
34 | u32 type; | 36 | u32 type; |
35 | 37 | ||
36 | printk("leaf %llu total ptrs %d free space %d\n", | 38 | printk("leaf %llu total ptrs %d free space %d\n", |
37 | (unsigned long long)btrfs_header_blocknr(&l->header), nr, | 39 | (unsigned long long)btrfs_header_blocknr(l), nr, |
38 | btrfs_leaf_free_space(root, l)); | 40 | btrfs_leaf_free_space(root, l)); |
39 | for (i = 0 ; i < nr ; i++) { | 41 | for (i = 0 ; i < nr ; i++) { |
40 | item = l->items + i; | 42 | item = btrfs_item_nr(l, i); |
41 | type = btrfs_disk_key_type(&item->key); | 43 | btrfs_item_key_to_cpu(l, &key, i); |
44 | type = btrfs_key_type(&key); | ||
42 | printk("\titem %d key (%llu %x %llu) itemoff %d itemsize %d\n", | 45 | printk("\titem %d key (%llu %x %llu) itemoff %d itemsize %d\n", |
43 | i, | 46 | i, |
44 | (unsigned long long)btrfs_disk_key_objectid(&item->key), | 47 | (unsigned long long)key.objectid, type, |
45 | btrfs_disk_key_flags(&item->key), | 48 | (unsigned long long)key.offset, |
46 | (unsigned long long)btrfs_disk_key_offset(&item->key), | 49 | btrfs_item_offset(l, item), btrfs_item_size(l, item)); |
47 | btrfs_item_offset(item), | ||
48 | btrfs_item_size(item)); | ||
49 | switch (type) { | 50 | switch (type) { |
50 | case BTRFS_INODE_ITEM_KEY: | 51 | case BTRFS_INODE_ITEM_KEY: |
51 | ii = btrfs_item_ptr(l, i, struct btrfs_inode_item); | 52 | ii = btrfs_item_ptr(l, i, struct btrfs_inode_item); |
52 | printk("\t\tinode generation %llu size %llu mode %o\n", | 53 | printk("\t\tinode generation %llu size %llu mode %o\n", |
53 | (unsigned long long)btrfs_inode_generation(ii), | 54 | (unsigned long long)btrfs_inode_generation(l, ii), |
54 | (unsigned long long)btrfs_inode_size(ii), | 55 | (unsigned long long)btrfs_inode_size(l, ii), |
55 | btrfs_inode_mode(ii)); | 56 | btrfs_inode_mode(l, ii)); |
56 | break; | 57 | break; |
57 | case BTRFS_DIR_ITEM_KEY: | 58 | case BTRFS_DIR_ITEM_KEY: |
58 | di = btrfs_item_ptr(l, i, struct btrfs_dir_item); | 59 | di = btrfs_item_ptr(l, i, struct btrfs_dir_item); |
60 | btrfs_dir_item_key_to_cpu(l, di, &found_key); | ||
59 | printk("\t\tdir oid %llu flags %u type %u\n", | 61 | printk("\t\tdir oid %llu flags %u type %u\n", |
60 | (unsigned long long)btrfs_disk_key_objectid( | 62 | (unsigned long long)found_key.objectid, |
61 | &di->location), | 63 | btrfs_dir_flags(l, di), |
62 | btrfs_dir_flags(di), | 64 | btrfs_dir_type(l, di)); |
63 | btrfs_dir_type(di)); | ||
64 | printk("\t\tname %.*s\n", | ||
65 | btrfs_dir_name_len(di),(char *)(di + 1)); | ||
66 | break; | 65 | break; |
67 | case BTRFS_ROOT_ITEM_KEY: | 66 | case BTRFS_ROOT_ITEM_KEY: |
68 | ri = btrfs_item_ptr(l, i, struct btrfs_root_item); | 67 | ri = btrfs_item_ptr(l, i, struct btrfs_root_item); |
69 | printk("\t\troot data blocknr %llu refs %u\n", | 68 | printk("\t\troot data blocknr %llu refs %u\n", |
70 | (unsigned long long)btrfs_root_blocknr(ri), | 69 | (unsigned long long)btrfs_disk_root_blocknr(l, ri), |
71 | btrfs_root_refs(ri)); | 70 | btrfs_disk_root_refs(l, ri)); |
72 | break; | 71 | break; |
73 | case BTRFS_EXTENT_ITEM_KEY: | 72 | case BTRFS_EXTENT_ITEM_KEY: |
74 | ei = btrfs_item_ptr(l, i, struct btrfs_extent_item); | 73 | ei = btrfs_item_ptr(l, i, struct btrfs_extent_item); |
75 | printk("\t\textent data refs %u\n", | 74 | printk("\t\textent data refs %u\n", |
76 | btrfs_extent_refs(ei)); | 75 | btrfs_extent_refs(l, ei)); |
77 | break; | 76 | break; |
78 | 77 | ||
79 | case BTRFS_EXTENT_DATA_KEY: | 78 | case BTRFS_EXTENT_DATA_KEY: |
80 | fi = btrfs_item_ptr(l, i, | 79 | fi = btrfs_item_ptr(l, i, |
81 | struct btrfs_file_extent_item); | 80 | struct btrfs_file_extent_item); |
82 | if (btrfs_file_extent_type(fi) == | 81 | if (btrfs_file_extent_type(l, fi) == |
83 | BTRFS_FILE_EXTENT_INLINE) { | 82 | BTRFS_FILE_EXTENT_INLINE) { |
84 | printk("\t\tinline extent data size %u\n", | 83 | printk("\t\tinline extent data size %u\n", |
85 | btrfs_file_extent_inline_len(l->items + i)); | 84 | btrfs_file_extent_inline_len(l, item)); |
86 | break; | 85 | break; |
87 | } | 86 | } |
88 | printk("\t\textent data disk block %llu nr %llu\n", | 87 | printk("\t\textent data disk block %llu nr %llu\n", |
89 | (unsigned long long)btrfs_file_extent_disk_blocknr(fi), | 88 | (unsigned long long)btrfs_file_extent_disk_blocknr(l, fi), |
90 | (unsigned long long)btrfs_file_extent_disk_num_blocks(fi)); | 89 | (unsigned long long)btrfs_file_extent_disk_num_blocks(l, fi)); |
91 | printk("\t\textent data offset %llu nr %llu\n", | 90 | printk("\t\textent data offset %llu nr %llu\n", |
92 | (unsigned long long)btrfs_file_extent_offset(fi), | 91 | (unsigned long long)btrfs_file_extent_offset(l, fi), |
93 | (unsigned long long)btrfs_file_extent_num_blocks(fi)); | 92 | (unsigned long long)btrfs_file_extent_num_blocks(l, fi)); |
94 | break; | 93 | break; |
95 | case BTRFS_BLOCK_GROUP_ITEM_KEY: | 94 | case BTRFS_BLOCK_GROUP_ITEM_KEY: |
96 | bi = btrfs_item_ptr(l, i, | 95 | bi = btrfs_item_ptr(l, i, |
97 | struct btrfs_block_group_item); | 96 | struct btrfs_block_group_item); |
98 | printk("\t\tblock group used %llu\n", | 97 | printk("\t\tblock group used %llu\n", |
99 | (unsigned long long)btrfs_block_group_used(bi)); | 98 | (unsigned long long)btrfs_disk_block_group_used(l, bi)); |
100 | break; | ||
101 | case BTRFS_STRING_ITEM_KEY: | ||
102 | printk("\t\titem data %.*s\n", btrfs_item_size(item), | ||
103 | btrfs_leaf_data(l) + btrfs_item_offset(item)); | ||
104 | break; | 99 | break; |
105 | }; | 100 | }; |
106 | } | 101 | } |
107 | } | 102 | } |
108 | 103 | ||
109 | void btrfs_print_tree(struct btrfs_root *root, struct buffer_head *t) | 104 | void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c) |
110 | { | 105 | { |
111 | int i; | 106 | int i; |
112 | u32 nr; | 107 | u32 nr; |
113 | struct btrfs_node *c; | 108 | struct btrfs_key key; |
114 | 109 | ||
115 | if (!t) | 110 | if (!c) |
116 | return; | 111 | return; |
117 | c = btrfs_buffer_node(t); | 112 | nr = btrfs_header_nritems(c); |
118 | nr = btrfs_header_nritems(&c->header); | ||
119 | if (btrfs_is_leaf(c)) { | 113 | if (btrfs_is_leaf(c)) { |
120 | btrfs_print_leaf(root, (struct btrfs_leaf *)c); | 114 | btrfs_print_leaf(root, c); |
121 | return; | 115 | return; |
122 | } | 116 | } |
123 | printk("node %llu level %d total ptrs %d free spc %u\n", | 117 | printk("node %llu level %d total ptrs %d free spc %u\n", |
124 | (unsigned long long)btrfs_header_blocknr(&c->header), | 118 | (unsigned long long)btrfs_header_blocknr(c), |
125 | btrfs_header_level(&c->header), nr, | 119 | btrfs_header_level(c), nr, |
126 | (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr); | 120 | (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr); |
127 | for (i = 0; i < nr; i++) { | 121 | for (i = 0; i < nr; i++) { |
122 | btrfs_node_key_to_cpu(c, &key, i); | ||
128 | printk("\tkey %d (%llu %u %llu) block %llu\n", | 123 | printk("\tkey %d (%llu %u %llu) block %llu\n", |
129 | i, | 124 | i, |
130 | (unsigned long long)c->ptrs[i].key.objectid, | 125 | (unsigned long long)key.objectid, |
131 | c->ptrs[i].key.flags, | 126 | key.type, |
132 | (unsigned long long)c->ptrs[i].key.offset, | 127 | (unsigned long long)key.offset, |
133 | (unsigned long long)btrfs_node_blockptr(c, i)); | 128 | (unsigned long long)btrfs_node_blockptr(c, i)); |
134 | } | 129 | } |
135 | for (i = 0; i < nr; i++) { | 130 | for (i = 0; i < nr; i++) { |
136 | struct buffer_head *next_buf = read_tree_block(root, | 131 | struct extent_buffer *next = read_tree_block(root, |
137 | btrfs_node_blockptr(c, i)); | 132 | btrfs_node_blockptr(c, i)); |
138 | struct btrfs_node *next = btrfs_buffer_node(next_buf); | ||
139 | if (btrfs_is_leaf(next) && | 133 | if (btrfs_is_leaf(next) && |
140 | btrfs_header_level(&c->header) != 1) | 134 | btrfs_header_level(c) != 1) |
141 | BUG(); | 135 | BUG(); |
142 | if (btrfs_header_level(&next->header) != | 136 | if (btrfs_header_level(next) != |
143 | btrfs_header_level(&c->header) - 1) | 137 | btrfs_header_level(c) - 1) |
144 | BUG(); | 138 | BUG(); |
145 | btrfs_print_tree(root, next_buf); | 139 | btrfs_print_tree(root, next); |
146 | btrfs_block_release(root, next_buf); | 140 | free_extent_buffer(next); |
147 | } | 141 | } |
148 | } | 142 | } |
149 | 143 | ||
diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h index 205cd03601ab..da75efe534d5 100644 --- a/fs/btrfs/print-tree.h +++ b/fs/btrfs/print-tree.h | |||
@@ -18,6 +18,6 @@ | |||
18 | 18 | ||
19 | #ifndef __PRINT_TREE_ | 19 | #ifndef __PRINT_TREE_ |
20 | #define __PRINT_TREE_ | 20 | #define __PRINT_TREE_ |
21 | void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l); | 21 | void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l); |
22 | void btrfs_print_tree(struct btrfs_root *root, struct buffer_head *t); | 22 | void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *t); |
23 | #endif | 23 | #endif |
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 3b5926dfbeba..88bcdd33f56e 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -26,12 +26,13 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
26 | { | 26 | { |
27 | struct btrfs_path *path; | 27 | struct btrfs_path *path; |
28 | struct btrfs_key search_key; | 28 | struct btrfs_key search_key; |
29 | struct btrfs_leaf *l; | 29 | struct btrfs_key found_key; |
30 | struct extent_buffer *l; | ||
30 | int ret; | 31 | int ret; |
31 | int slot; | 32 | int slot; |
32 | 33 | ||
33 | search_key.objectid = objectid; | 34 | search_key.objectid = objectid; |
34 | search_key.flags = (u32)-1; | 35 | search_key.type = (u8)-1; |
35 | search_key.offset = (u64)-1; | 36 | search_key.offset = (u64)-1; |
36 | 37 | ||
37 | path = btrfs_alloc_path(); | 38 | path = btrfs_alloc_path(); |
@@ -39,17 +40,19 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
39 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | 40 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); |
40 | if (ret < 0) | 41 | if (ret < 0) |
41 | goto out; | 42 | goto out; |
43 | |||
42 | BUG_ON(ret == 0); | 44 | BUG_ON(ret == 0); |
43 | l = btrfs_buffer_leaf(path->nodes[0]); | 45 | l = path->nodes[0]; |
44 | BUG_ON(path->slots[0] == 0); | 46 | BUG_ON(path->slots[0] == 0); |
45 | slot = path->slots[0] - 1; | 47 | slot = path->slots[0] - 1; |
46 | if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) { | 48 | btrfs_item_key_to_cpu(l, &found_key, slot); |
49 | if (found_key.objectid != objectid) { | ||
47 | ret = 1; | 50 | ret = 1; |
48 | goto out; | 51 | goto out; |
49 | } | 52 | } |
50 | memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item), | 53 | read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), |
51 | sizeof(*item)); | 54 | sizeof(*item)); |
52 | btrfs_disk_key_to_cpu(key, &l->items[slot].key); | 55 | memcpy(key, &found_key, sizeof(found_key)); |
53 | ret = 0; | 56 | ret = 0; |
54 | out: | 57 | out: |
55 | btrfs_release_path(root, path); | 58 | btrfs_release_path(root, path); |
@@ -62,10 +65,10 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
62 | *item) | 65 | *item) |
63 | { | 66 | { |
64 | struct btrfs_path *path; | 67 | struct btrfs_path *path; |
65 | struct btrfs_leaf *l; | 68 | struct extent_buffer *l; |
66 | int ret; | 69 | int ret; |
67 | int slot; | 70 | int slot; |
68 | struct btrfs_root_item *update_item; | 71 | unsigned long ptr; |
69 | 72 | ||
70 | path = btrfs_alloc_path(); | 73 | path = btrfs_alloc_path(); |
71 | BUG_ON(!path); | 74 | BUG_ON(!path); |
@@ -73,10 +76,10 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
73 | if (ret < 0) | 76 | if (ret < 0) |
74 | goto out; | 77 | goto out; |
75 | BUG_ON(ret != 0); | 78 | BUG_ON(ret != 0); |
76 | l = btrfs_buffer_leaf(path->nodes[0]); | 79 | l = path->nodes[0]; |
77 | slot = path->slots[0]; | 80 | slot = path->slots[0]; |
78 | update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item); | 81 | ptr = btrfs_item_ptr_offset(l, slot); |
79 | btrfs_memcpy(root, l, update_item, item, sizeof(*item)); | 82 | write_extent_buffer(l, item, ptr, sizeof(*item)); |
80 | btrfs_mark_buffer_dirty(path->nodes[0]); | 83 | btrfs_mark_buffer_dirty(path->nodes[0]); |
81 | out: | 84 | out: |
82 | btrfs_release_path(root, path); | 85 | btrfs_release_path(root, path); |
@@ -103,11 +106,10 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid, | |||
103 | struct btrfs_path *path; | 106 | struct btrfs_path *path; |
104 | int ret; | 107 | int ret; |
105 | u32 nritems; | 108 | u32 nritems; |
106 | struct btrfs_leaf *leaf; | 109 | struct extent_buffer *leaf; |
107 | int slot; | 110 | int slot; |
108 | 111 | ||
109 | key.objectid = objectid; | 112 | key.objectid = objectid; |
110 | key.flags = 0; | ||
111 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 113 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
112 | key.offset = 0; | 114 | key.offset = 0; |
113 | path = btrfs_alloc_path(); | 115 | path = btrfs_alloc_path(); |
@@ -117,19 +119,19 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid, | |||
117 | if (ret < 0) | 119 | if (ret < 0) |
118 | goto err; | 120 | goto err; |
119 | while(1) { | 121 | while(1) { |
120 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 122 | leaf = path->nodes[0]; |
121 | nritems = btrfs_header_nritems(&leaf->header); | 123 | nritems = btrfs_header_nritems(leaf); |
122 | slot = path->slots[0]; | 124 | slot = path->slots[0]; |
123 | if (slot >= nritems) { | 125 | if (slot >= nritems) { |
124 | ret = btrfs_next_leaf(root, path); | 126 | ret = btrfs_next_leaf(root, path); |
125 | if (ret) | 127 | if (ret) |
126 | break; | 128 | break; |
127 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 129 | leaf = path->nodes[0]; |
128 | nritems = btrfs_header_nritems(&leaf->header); | 130 | nritems = btrfs_header_nritems(leaf); |
129 | slot = path->slots[0]; | 131 | slot = path->slots[0]; |
130 | } | 132 | } |
131 | item = leaf->items + slot; | 133 | item = btrfs_item_nr(leaf, slot); |
132 | btrfs_disk_key_to_cpu(&key, &item->key); | 134 | btrfs_item_key_to_cpu(leaf, &key, slot); |
133 | if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY) | 135 | if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY) |
134 | goto next; | 136 | goto next; |
135 | 137 | ||
@@ -140,7 +142,7 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid, | |||
140 | break; | 142 | break; |
141 | 143 | ||
142 | ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item); | 144 | ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item); |
143 | if (btrfs_root_refs(ri) != 0) | 145 | if (btrfs_disk_root_refs(leaf, ri) != 0) |
144 | goto next; | 146 | goto next; |
145 | 147 | ||
146 | dead_root = btrfs_read_fs_root_no_radix(root->fs_info, &key); | 148 | dead_root = btrfs_read_fs_root_no_radix(root->fs_info, &key); |
@@ -170,6 +172,7 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
170 | int ret; | 172 | int ret; |
171 | u32 refs; | 173 | u32 refs; |
172 | struct btrfs_root_item *ri; | 174 | struct btrfs_root_item *ri; |
175 | struct extent_buffer *leaf; | ||
173 | 176 | ||
174 | path = btrfs_alloc_path(); | 177 | path = btrfs_alloc_path(); |
175 | BUG_ON(!path); | 178 | BUG_ON(!path); |
@@ -177,10 +180,10 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
177 | if (ret < 0) | 180 | if (ret < 0) |
178 | goto out; | 181 | goto out; |
179 | BUG_ON(ret != 0); | 182 | BUG_ON(ret != 0); |
180 | ri = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 183 | leaf = path->nodes[0]; |
181 | path->slots[0], struct btrfs_root_item); | 184 | ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item); |
182 | 185 | ||
183 | refs = btrfs_root_refs(ri); | 186 | refs = btrfs_disk_root_refs(leaf, ri); |
184 | BUG_ON(refs != 0); | 187 | BUG_ON(refs != 0); |
185 | ret = btrfs_del_item(trans, root, path); | 188 | ret = btrfs_del_item(trans, root, path); |
186 | out: | 189 | out: |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 66a01cbbbea1..39a1435c68f1 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include "ioctl.h" | 41 | #include "ioctl.h" |
42 | #include "print-tree.h" | 42 | #include "print-tree.h" |
43 | 43 | ||
44 | #define BTRFS_SUPER_MAGIC 0x9123682E | 44 | #define BTRFS_SUPER_MAGIC 0x9123683E |
45 | 45 | ||
46 | static struct super_operations btrfs_super_ops; | 46 | static struct super_operations btrfs_super_ops; |
47 | 47 | ||
@@ -115,13 +115,12 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | |||
115 | return -EIO; | 115 | return -EIO; |
116 | } | 116 | } |
117 | sb->s_fs_info = tree_root; | 117 | sb->s_fs_info = tree_root; |
118 | disk_super = tree_root->fs_info->disk_super; | 118 | disk_super = &tree_root->fs_info->super_copy; |
119 | inode = btrfs_iget_locked(sb, btrfs_super_root_dir(disk_super), | 119 | inode = btrfs_iget_locked(sb, btrfs_super_root_dir(disk_super), |
120 | tree_root); | 120 | tree_root); |
121 | bi = BTRFS_I(inode); | 121 | bi = BTRFS_I(inode); |
122 | bi->location.objectid = inode->i_ino; | 122 | bi->location.objectid = inode->i_ino; |
123 | bi->location.offset = 0; | 123 | bi->location.offset = 0; |
124 | bi->location.flags = 0; | ||
125 | bi->root = tree_root; | 124 | bi->root = tree_root; |
126 | 125 | ||
127 | btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY); | 126 | btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY); |
@@ -281,6 +280,7 @@ error_s: | |||
281 | error_bdev: | 280 | error_bdev: |
282 | close_bdev_excl(bdev); | 281 | close_bdev_excl(bdev); |
283 | error: | 282 | error: |
283 | printk("get_sb failed\n"); | ||
284 | return error; | 284 | return error; |
285 | } | 285 | } |
286 | /* end copy & paste */ | 286 | /* end copy & paste */ |
@@ -295,6 +295,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, | |||
295 | ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, | 295 | ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, |
296 | btrfs_fill_super, mnt, | 296 | btrfs_fill_super, mnt, |
297 | subvol_name ? subvol_name : "default"); | 297 | subvol_name ? subvol_name : "default"); |
298 | printk("btrfs_get_sb returns %d\n", ret); | ||
298 | return ret; | 299 | return ret; |
299 | } | 300 | } |
300 | 301 | ||
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 2058783373eb..9654e90eec89 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c | |||
@@ -31,31 +31,31 @@ | |||
31 | static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf) | 31 | static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf) |
32 | { | 32 | { |
33 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 33 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
34 | (unsigned long long)btrfs_root_blocks_used(&root->root_item)); | 34 | (unsigned long long)btrfs_root_used(&root->root_item)); |
35 | } | 35 | } |
36 | 36 | ||
37 | static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf) | 37 | static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf) |
38 | { | 38 | { |
39 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 39 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
40 | (unsigned long long)btrfs_root_block_limit(&root->root_item)); | 40 | (unsigned long long)btrfs_root_limit(&root->root_item)); |
41 | } | 41 | } |
42 | 42 | ||
43 | static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf) | 43 | static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf) |
44 | { | 44 | { |
45 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 45 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
46 | (unsigned long long)btrfs_super_blocks_used(fs->disk_super)); | 46 | (unsigned long long)btrfs_super_blocks_used(&fs->super_copy)); |
47 | } | 47 | } |
48 | 48 | ||
49 | static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf) | 49 | static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf) |
50 | { | 50 | { |
51 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 51 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
52 | (unsigned long long)btrfs_super_total_blocks(fs->disk_super)); | 52 | (unsigned long long)btrfs_super_total_blocks(&fs->super_copy)); |
53 | } | 53 | } |
54 | 54 | ||
55 | static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf) | 55 | static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf) |
56 | { | 56 | { |
57 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 57 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
58 | (unsigned long long)btrfs_super_blocksize(fs->disk_super)); | 58 | (unsigned long long)btrfs_super_sectorsize(&fs->super_copy)); |
59 | } | 59 | } |
60 | 60 | ||
61 | /* this is for root attrs (subvols/snapshots) */ | 61 | /* this is for root attrs (subvols/snapshots) */ |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 087074db0bd5..750f35a37aae 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/writeback.h> | 21 | #include <linux/writeback.h> |
22 | #include <linux/pagemap.h> | ||
22 | #include "ctree.h" | 23 | #include "ctree.h" |
23 | #include "disk-io.h" | 24 | #include "disk-io.h" |
24 | #include "transaction.h" | 25 | #include "transaction.h" |
@@ -66,7 +67,9 @@ static int join_transaction(struct btrfs_root *root) | |||
66 | cur_trans->commit_done = 0; | 67 | cur_trans->commit_done = 0; |
67 | cur_trans->start_time = get_seconds(); | 68 | cur_trans->start_time = get_seconds(); |
68 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | 69 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); |
69 | init_bit_radix(&cur_trans->dirty_pages); | 70 | extent_map_tree_init(&cur_trans->dirty_pages, |
71 | root->fs_info->btree_inode->i_mapping, | ||
72 | GFP_NOFS); | ||
70 | } else { | 73 | } else { |
71 | cur_trans->num_writers++; | 74 | cur_trans->num_writers++; |
72 | cur_trans->num_joined++; | 75 | cur_trans->num_joined++; |
@@ -88,7 +91,7 @@ static int record_root_in_trans(struct btrfs_root *root) | |||
88 | (unsigned long)root->root_key.objectid, | 91 | (unsigned long)root->root_key.objectid, |
89 | BTRFS_ROOT_DEFRAG_TAG); | 92 | BTRFS_ROOT_DEFRAG_TAG); |
90 | root->commit_root = root->node; | 93 | root->commit_root = root->node; |
91 | get_bh(root->node); | 94 | extent_buffer_get(root->node); |
92 | } else { | 95 | } else { |
93 | WARN_ON(1); | 96 | WARN_ON(1); |
94 | } | 97 | } |
@@ -144,29 +147,30 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
144 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 147 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
145 | struct btrfs_root *root) | 148 | struct btrfs_root *root) |
146 | { | 149 | { |
147 | unsigned long gang[16]; | ||
148 | int ret; | 150 | int ret; |
149 | int i; | ||
150 | int err; | 151 | int err; |
151 | int werr = 0; | 152 | int werr = 0; |
153 | struct extent_map_tree *dirty_pages; | ||
152 | struct page *page; | 154 | struct page *page; |
153 | struct radix_tree_root *dirty_pages; | ||
154 | struct inode *btree_inode = root->fs_info->btree_inode; | 155 | struct inode *btree_inode = root->fs_info->btree_inode; |
156 | u64 start; | ||
157 | u64 end; | ||
158 | unsigned long index; | ||
155 | 159 | ||
156 | if (!trans || !trans->transaction) { | 160 | if (!trans || !trans->transaction) { |
157 | return filemap_write_and_wait(btree_inode->i_mapping); | 161 | return filemap_write_and_wait(btree_inode->i_mapping); |
158 | } | 162 | } |
159 | dirty_pages = &trans->transaction->dirty_pages; | 163 | dirty_pages = &trans->transaction->dirty_pages; |
160 | while(1) { | 164 | while(1) { |
161 | ret = find_first_radix_bit(dirty_pages, gang, | 165 | ret = find_first_extent_bit(dirty_pages, 0, &start, &end, |
162 | 0, ARRAY_SIZE(gang)); | 166 | EXTENT_DIRTY); |
163 | if (!ret) | 167 | if (ret) |
164 | break; | 168 | break; |
165 | for (i = 0; i < ret; i++) { | 169 | clear_extent_dirty(dirty_pages, start, end, GFP_NOFS); |
166 | /* FIXME EIO */ | 170 | while(start <= end) { |
167 | clear_radix_bit(dirty_pages, gang[i]); | 171 | index = start >> PAGE_CACHE_SHIFT; |
168 | page = find_lock_page(btree_inode->i_mapping, | 172 | start = (index + 1) << PAGE_CACHE_SHIFT; |
169 | gang[i]); | 173 | page = find_lock_page(btree_inode->i_mapping, index); |
170 | if (!page) | 174 | if (!page) |
171 | continue; | 175 | continue; |
172 | if (PageWriteback(page)) { | 176 | if (PageWriteback(page)) { |
@@ -202,10 +206,11 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
202 | btrfs_write_dirty_block_groups(trans, extent_root); | 206 | btrfs_write_dirty_block_groups(trans, extent_root); |
203 | while(1) { | 207 | while(1) { |
204 | old_extent_block = btrfs_root_blocknr(&extent_root->root_item); | 208 | old_extent_block = btrfs_root_blocknr(&extent_root->root_item); |
205 | if (old_extent_block == bh_blocknr(extent_root->node)) | 209 | if (old_extent_block == |
210 | extent_buffer_blocknr(extent_root->node)) | ||
206 | break; | 211 | break; |
207 | btrfs_set_root_blocknr(&extent_root->root_item, | 212 | btrfs_set_root_blocknr(&extent_root->root_item, |
208 | bh_blocknr(extent_root->node)); | 213 | extent_buffer_blocknr(extent_root->node)); |
209 | ret = btrfs_update_root(trans, tree_root, | 214 | ret = btrfs_update_root(trans, tree_root, |
210 | &extent_root->root_key, | 215 | &extent_root->root_key, |
211 | &extent_root->root_item); | 216 | &extent_root->root_item); |
@@ -279,9 +284,9 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
279 | (unsigned long)root->root_key.objectid, | 284 | (unsigned long)root->root_key.objectid, |
280 | BTRFS_ROOT_TRANS_TAG); | 285 | BTRFS_ROOT_TRANS_TAG); |
281 | if (root->commit_root == root->node) { | 286 | if (root->commit_root == root->node) { |
282 | WARN_ON(bh_blocknr(root->node) != | 287 | WARN_ON(extent_buffer_blocknr(root->node) != |
283 | btrfs_root_blocknr(&root->root_item)); | 288 | btrfs_root_blocknr(&root->root_item)); |
284 | brelse(root->commit_root); | 289 | free_extent_buffer(root->commit_root); |
285 | root->commit_root = NULL; | 290 | root->commit_root = NULL; |
286 | 291 | ||
287 | /* make sure to update the root on disk | 292 | /* make sure to update the root on disk |
@@ -310,7 +315,7 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
310 | 315 | ||
311 | root->root_key.offset = root->fs_info->generation; | 316 | root->root_key.offset = root->fs_info->generation; |
312 | btrfs_set_root_blocknr(&root->root_item, | 317 | btrfs_set_root_blocknr(&root->root_item, |
313 | bh_blocknr(root->node)); | 318 | extent_buffer_blocknr(root->node)); |
314 | err = btrfs_insert_root(trans, root->fs_info->tree_root, | 319 | err = btrfs_insert_root(trans, root->fs_info->tree_root, |
315 | &root->root_key, | 320 | &root->root_key, |
316 | &root->root_item); | 321 | &root->root_item); |
@@ -389,10 +394,10 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info) | |||
389 | for (i = 0; i < ret; i++) { | 394 | for (i = 0; i < ret; i++) { |
390 | root = gang[i]; | 395 | root = gang[i]; |
391 | last = root->root_key.objectid + 1; | 396 | last = root->root_key.objectid + 1; |
392 | btrfs_defrag_root(root, 1); | 397 | // btrfs_defrag_root(root, 1); |
393 | } | 398 | } |
394 | } | 399 | } |
395 | btrfs_defrag_root(info->extent_root, 1); | 400 | // btrfs_defrag_root(info->extent_root, 1); |
396 | return err; | 401 | return err; |
397 | } | 402 | } |
398 | 403 | ||
@@ -414,7 +419,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
414 | dirty = list_entry(list->next, struct dirty_root, list); | 419 | dirty = list_entry(list->next, struct dirty_root, list); |
415 | list_del_init(&dirty->list); | 420 | list_del_init(&dirty->list); |
416 | 421 | ||
417 | num_blocks = btrfs_root_blocks_used(&dirty->root->root_item); | 422 | num_blocks = btrfs_root_used(&dirty->root->root_item); |
418 | root = dirty->latest_root; | 423 | root = dirty->latest_root; |
419 | 424 | ||
420 | while(1) { | 425 | while(1) { |
@@ -441,11 +446,11 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
441 | } | 446 | } |
442 | BUG_ON(ret); | 447 | BUG_ON(ret); |
443 | 448 | ||
444 | num_blocks -= btrfs_root_blocks_used(&dirty->root->root_item); | 449 | num_blocks -= btrfs_root_used(&dirty->root->root_item); |
445 | blocks_used = btrfs_root_blocks_used(&root->root_item); | 450 | blocks_used = btrfs_root_used(&root->root_item); |
446 | if (num_blocks) { | 451 | if (num_blocks) { |
447 | record_root_in_trans(root); | 452 | record_root_in_trans(root); |
448 | btrfs_set_root_blocks_used(&root->root_item, | 453 | btrfs_set_root_used(&root->root_item, |
449 | blocks_used - num_blocks); | 454 | blocks_used - num_blocks); |
450 | } | 455 | } |
451 | ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); | 456 | ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); |
@@ -553,9 +558,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
553 | btrfs_set_super_generation(&root->fs_info->super_copy, | 558 | btrfs_set_super_generation(&root->fs_info->super_copy, |
554 | cur_trans->transid); | 559 | cur_trans->transid); |
555 | btrfs_set_super_root(&root->fs_info->super_copy, | 560 | btrfs_set_super_root(&root->fs_info->super_copy, |
556 | bh_blocknr(root->fs_info->tree_root->node)); | 561 | extent_buffer_blocknr(root->fs_info->tree_root->node)); |
557 | memcpy(root->fs_info->disk_super, &root->fs_info->super_copy, | 562 | |
558 | sizeof(root->fs_info->super_copy)); | 563 | write_extent_buffer(root->fs_info->sb_buffer, |
564 | &root->fs_info->super_copy, 0, | ||
565 | sizeof(root->fs_info->super_copy)); | ||
559 | 566 | ||
560 | btrfs_copy_pinned(root, &pinned_copy); | 567 | btrfs_copy_pinned(root, &pinned_copy); |
561 | 568 | ||
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 4bc328cbb24c..ae39fcfc169a 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -28,7 +28,7 @@ struct btrfs_transaction { | |||
28 | int use_count; | 28 | int use_count; |
29 | int commit_done; | 29 | int commit_done; |
30 | struct list_head list; | 30 | struct list_head list; |
31 | struct radix_tree_root dirty_pages; | 31 | struct extent_map_tree dirty_pages; |
32 | unsigned long start_time; | 32 | unsigned long start_time; |
33 | wait_queue_head_t writer_wait; | 33 | wait_queue_head_t writer_wait; |
34 | wait_queue_head_t commit_wait; | 34 | wait_queue_head_t commit_wait; |
@@ -83,5 +83,6 @@ int btrfs_add_dead_root(struct btrfs_root *root, struct btrfs_root *latest, | |||
83 | int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info); | 83 | int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info); |
84 | int btrfs_defrag_root(struct btrfs_root *root, int cacheonly); | 84 | int btrfs_defrag_root(struct btrfs_root *root, int cacheonly); |
85 | int btrfs_clean_old_snapshots(struct btrfs_root *root); | 85 | int btrfs_clean_old_snapshots(struct btrfs_root *root); |
86 | 86 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |
87 | struct btrfs_root *root); | ||
87 | #endif | 88 | #endif |
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index 420597127ed1..daf019afa0a1 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c | |||
@@ -23,14 +23,14 @@ | |||
23 | #include "transaction.h" | 23 | #include "transaction.h" |
24 | 24 | ||
25 | static void reada_defrag(struct btrfs_root *root, | 25 | static void reada_defrag(struct btrfs_root *root, |
26 | struct btrfs_node *node) | 26 | struct extent_buffer *node) |
27 | { | 27 | { |
28 | int i; | 28 | int i; |
29 | u32 nritems; | 29 | u32 nritems; |
30 | u64 blocknr; | 30 | u64 blocknr; |
31 | int ret; | 31 | int ret; |
32 | 32 | ||
33 | nritems = btrfs_header_nritems(&node->header); | 33 | nritems = btrfs_header_nritems(node); |
34 | for (i = 0; i < nritems; i++) { | 34 | for (i = 0; i < nritems; i++) { |
35 | blocknr = btrfs_node_blockptr(node, i); | 35 | blocknr = btrfs_node_blockptr(node, i); |
36 | ret = readahead_tree_block(root, blocknr); | 36 | ret = readahead_tree_block(root, blocknr); |
@@ -44,8 +44,8 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
44 | struct btrfs_path *path, int *level, | 44 | struct btrfs_path *path, int *level, |
45 | int cache_only, u64 *last_ret) | 45 | int cache_only, u64 *last_ret) |
46 | { | 46 | { |
47 | struct buffer_head *next; | 47 | struct extent_buffer *next; |
48 | struct buffer_head *cur; | 48 | struct extent_buffer *cur; |
49 | u64 blocknr; | 49 | u64 blocknr; |
50 | int ret = 0; | 50 | int ret = 0; |
51 | int is_extent = 0; | 51 | int is_extent = 0; |
@@ -62,13 +62,13 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
62 | cur = path->nodes[*level]; | 62 | cur = path->nodes[*level]; |
63 | 63 | ||
64 | if (!cache_only && *level > 1 && path->slots[*level] == 0) | 64 | if (!cache_only && *level > 1 && path->slots[*level] == 0) |
65 | reada_defrag(root, btrfs_buffer_node(cur)); | 65 | reada_defrag(root, cur); |
66 | 66 | ||
67 | if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) | 67 | if (btrfs_header_level(cur) != *level) |
68 | WARN_ON(1); | 68 | WARN_ON(1); |
69 | 69 | ||
70 | if (path->slots[*level] >= | 70 | if (path->slots[*level] >= |
71 | btrfs_header_nritems(btrfs_buffer_header(cur))) | 71 | btrfs_header_nritems(cur)) |
72 | break; | 72 | break; |
73 | 73 | ||
74 | if (*level == 1) { | 74 | if (*level == 1) { |
@@ -80,14 +80,13 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
80 | 80 | ||
81 | break; | 81 | break; |
82 | } | 82 | } |
83 | blocknr = btrfs_node_blockptr(btrfs_buffer_node(cur), | 83 | blocknr = btrfs_node_blockptr(cur, path->slots[*level]); |
84 | path->slots[*level]); | ||
85 | 84 | ||
86 | if (cache_only) { | 85 | if (cache_only) { |
87 | next = btrfs_find_tree_block(root, blocknr); | 86 | next = btrfs_find_tree_block(root, blocknr); |
88 | if (!next || !buffer_uptodate(next) || | 87 | /* FIXME, test for defrag */ |
89 | buffer_locked(next) || !buffer_defrag(next)) { | 88 | if (!next || !btrfs_buffer_uptodate(next)) { |
90 | brelse(next); | 89 | free_extent_buffer(next); |
91 | path->slots[*level]++; | 90 | path->slots[*level]++; |
92 | continue; | 91 | continue; |
93 | } | 92 | } |
@@ -106,16 +105,18 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
106 | 105 | ||
107 | WARN_ON(*level <= 0); | 106 | WARN_ON(*level <= 0); |
108 | if (path->nodes[*level-1]) | 107 | if (path->nodes[*level-1]) |
109 | btrfs_block_release(root, path->nodes[*level-1]); | 108 | free_extent_buffer(path->nodes[*level-1]); |
110 | path->nodes[*level-1] = next; | 109 | path->nodes[*level-1] = next; |
111 | *level = btrfs_header_level(btrfs_buffer_header(next)); | 110 | *level = btrfs_header_level(next); |
112 | path->slots[*level] = 0; | 111 | path->slots[*level] = 0; |
113 | } | 112 | } |
114 | WARN_ON(*level < 0); | 113 | WARN_ON(*level < 0); |
115 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 114 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
115 | #if 0 | ||
116 | clear_buffer_defrag(path->nodes[*level]); | 116 | clear_buffer_defrag(path->nodes[*level]); |
117 | clear_buffer_defrag_done(path->nodes[*level]); | 117 | clear_buffer_defrag_done(path->nodes[*level]); |
118 | btrfs_block_release(root, path->nodes[*level]); | 118 | #endif |
119 | free_extent_buffer(path->nodes[*level]); | ||
119 | path->nodes[*level] = NULL; | 120 | path->nodes[*level] = NULL; |
120 | *level += 1; | 121 | *level += 1; |
121 | WARN_ON(ret); | 122 | WARN_ON(ret); |
@@ -129,24 +130,25 @@ static int defrag_walk_up(struct btrfs_trans_handle *trans, | |||
129 | { | 130 | { |
130 | int i; | 131 | int i; |
131 | int slot; | 132 | int slot; |
132 | struct btrfs_node *node; | 133 | struct extent_buffer *node; |
133 | 134 | ||
134 | for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { | 135 | for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { |
135 | slot = path->slots[i]; | 136 | slot = path->slots[i]; |
136 | if (slot < btrfs_header_nritems( | 137 | if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { |
137 | btrfs_buffer_header(path->nodes[i])) - 1) { | ||
138 | path->slots[i]++; | 138 | path->slots[i]++; |
139 | *level = i; | 139 | *level = i; |
140 | node = btrfs_buffer_node(path->nodes[i]); | 140 | node = path->nodes[i]; |
141 | WARN_ON(i == 0); | 141 | WARN_ON(i == 0); |
142 | btrfs_disk_key_to_cpu(&root->defrag_progress, | 142 | btrfs_node_key_to_cpu(node, &root->defrag_progress, |
143 | &node->ptrs[path->slots[i]].key); | 143 | path->slots[i]); |
144 | root->defrag_level = i; | 144 | root->defrag_level = i; |
145 | return 0; | 145 | return 0; |
146 | } else { | 146 | } else { |
147 | /* | ||
147 | clear_buffer_defrag(path->nodes[*level]); | 148 | clear_buffer_defrag(path->nodes[*level]); |
148 | clear_buffer_defrag_done(path->nodes[*level]); | 149 | clear_buffer_defrag_done(path->nodes[*level]); |
149 | btrfs_block_release(root, path->nodes[*level]); | 150 | */ |
151 | free_extent_buffer(path->nodes[*level]); | ||
150 | path->nodes[*level] = NULL; | 152 | path->nodes[*level] = NULL; |
151 | *level = i + 1; | 153 | *level = i + 1; |
152 | } | 154 | } |
@@ -158,7 +160,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
158 | struct btrfs_root *root, int cache_only) | 160 | struct btrfs_root *root, int cache_only) |
159 | { | 161 | { |
160 | struct btrfs_path *path = NULL; | 162 | struct btrfs_path *path = NULL; |
161 | struct buffer_head *tmp; | 163 | struct extent_buffer *tmp; |
162 | int ret = 0; | 164 | int ret = 0; |
163 | int wret; | 165 | int wret; |
164 | int level; | 166 | int level; |
@@ -172,17 +174,18 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
172 | 174 | ||
173 | if (root->ref_cows == 0 && !is_extent) | 175 | if (root->ref_cows == 0 && !is_extent) |
174 | goto out; | 176 | goto out; |
177 | |||
175 | path = btrfs_alloc_path(); | 178 | path = btrfs_alloc_path(); |
176 | if (!path) | 179 | if (!path) |
177 | return -ENOMEM; | 180 | return -ENOMEM; |
178 | 181 | ||
179 | level = btrfs_header_level(btrfs_buffer_header(root->node)); | 182 | level = btrfs_header_level(root->node); |
180 | orig_level = level; | 183 | orig_level = level; |
181 | if (level == 0) { | 184 | if (level == 0) { |
182 | goto out; | 185 | goto out; |
183 | } | 186 | } |
184 | if (root->defrag_progress.objectid == 0) { | 187 | if (root->defrag_progress.objectid == 0) { |
185 | get_bh(root->node); | 188 | extent_buffer_get(root->node); |
186 | ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); | 189 | ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); |
187 | BUG_ON(ret); | 190 | BUG_ON(ret); |
188 | ret = btrfs_realloc_node(trans, root, root->node, cache_only, | 191 | ret = btrfs_realloc_node(trans, root, root->node, cache_only, |
@@ -200,12 +203,15 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
200 | 203 | ||
201 | if (is_extent) | 204 | if (is_extent) |
202 | btrfs_extent_post_op(trans, root); | 205 | btrfs_extent_post_op(trans, root); |
206 | |||
203 | if (wret < 0) { | 207 | if (wret < 0) { |
204 | ret = wret; | 208 | ret = wret; |
205 | goto out; | 209 | goto out; |
206 | } | 210 | } |
211 | |||
207 | while(level > 0 && !path->nodes[level]) | 212 | while(level > 0 && !path->nodes[level]) |
208 | level--; | 213 | level--; |
214 | |||
209 | if (!path->nodes[level]) { | 215 | if (!path->nodes[level]) { |
210 | ret = 0; | 216 | ret = 0; |
211 | goto out; | 217 | goto out; |
@@ -230,7 +236,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
230 | } | 236 | } |
231 | for (i = 0; i <= orig_level; i++) { | 237 | for (i = 0; i <= orig_level; i++) { |
232 | if (path->nodes[i]) { | 238 | if (path->nodes[i]) { |
233 | btrfs_block_release(root, path->nodes[i]); | 239 | free_extent_buffer(path->nodes[i]); |
234 | path->nodes[i] = 0; | 240 | path->nodes[i] = 0; |
235 | } | 241 | } |
236 | } | 242 | } |