diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2009-01-06 11:42:00 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-01-06 11:42:00 -0500 |
commit | 07d400a6df4767a90d49a153fdb7f4cfa1e3f23e (patch) | |
tree | 8ca61bb87ffb72343b8d392a26fb7a6265f6fa3d /fs/btrfs/file-item.c | |
parent | 1ba12553f3600ffebad226c5204ab0e46df98161 (diff) |
Btrfs: tree logging checksum fixes
This patch contains following things.
1) Limit the max size of btrfs_ordered_sum structure to PAGE_SIZE. This
struct is kmalloced so we want to keep it reasonable.
2) Replace copy_extent_csums by btrfs_lookup_csums_range. This was
duplicated code in tree-log.c
3) Remove replay_one_csum. csum items are replayed at the same time as
replaying file extents. This guarantees we only replay useful csums.
4) nbytes accounting fix.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r-- | fs/btrfs/file-item.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index b11abfad81a5..964652435fd1 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -27,6 +27,12 @@ | |||
27 | #define MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ | 27 | #define MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ |
28 | sizeof(struct btrfs_item) * 2) / \ | 28 | sizeof(struct btrfs_item) * 2) / \ |
29 | size) - 1)) | 29 | size) - 1)) |
30 | |||
31 | #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \ | ||
32 | sizeof(struct btrfs_ordered_sum)) / \ | ||
33 | sizeof(struct btrfs_sector_sum) * \ | ||
34 | (r)->sectorsize - (r)->sectorsize) | ||
35 | |||
30 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 36 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
31 | struct btrfs_root *root, | 37 | struct btrfs_root *root, |
32 | u64 objectid, u64 pos, | 38 | u64 objectid, u64 pos, |
@@ -259,8 +265,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | |||
259 | key.offset = start; | 265 | key.offset = start; |
260 | key.type = BTRFS_EXTENT_CSUM_KEY; | 266 | key.type = BTRFS_EXTENT_CSUM_KEY; |
261 | 267 | ||
262 | ret = btrfs_search_slot(NULL, root->fs_info->csum_root, | 268 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
263 | &key, path, 0, 0); | ||
264 | if (ret < 0) | 269 | if (ret < 0) |
265 | goto fail; | 270 | goto fail; |
266 | if (ret > 0 && path->slots[0] > 0) { | 271 | if (ret > 0 && path->slots[0] > 0) { |
@@ -279,7 +284,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | |||
279 | while (start <= end) { | 284 | while (start <= end) { |
280 | leaf = path->nodes[0]; | 285 | leaf = path->nodes[0]; |
281 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | 286 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { |
282 | ret = btrfs_next_leaf(root->fs_info->csum_root, path); | 287 | ret = btrfs_next_leaf(root, path); |
283 | if (ret < 0) | 288 | if (ret < 0) |
284 | goto fail; | 289 | goto fail; |
285 | if (ret > 0) | 290 | if (ret > 0) |
@@ -306,33 +311,38 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | |||
306 | continue; | 311 | continue; |
307 | } | 312 | } |
308 | 313 | ||
309 | size = min(csum_end, end + 1) - start; | 314 | csum_end = min(csum_end, end + 1); |
310 | sums = kzalloc(btrfs_ordered_sum_size(root, size), GFP_NOFS); | 315 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], |
311 | BUG_ON(!sums); | 316 | struct btrfs_csum_item); |
317 | while (start < csum_end) { | ||
318 | size = min_t(size_t, csum_end - start, | ||
319 | MAX_ORDERED_SUM_BYTES(root)); | ||
320 | sums = kzalloc(btrfs_ordered_sum_size(root, size), | ||
321 | GFP_NOFS); | ||
322 | BUG_ON(!sums); | ||
312 | 323 | ||
313 | sector_sum = sums->sums; | 324 | sector_sum = sums->sums; |
314 | sums->bytenr = start; | 325 | sums->bytenr = start; |
315 | sums->len = size; | 326 | sums->len = size; |
316 | 327 | ||
317 | offset = (start - key.offset) >> | 328 | offset = (start - key.offset) >> |
318 | root->fs_info->sb->s_blocksize_bits; | 329 | root->fs_info->sb->s_blocksize_bits; |
319 | offset *= csum_size; | 330 | offset *= csum_size; |
320 | 331 | ||
321 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | 332 | while (size > 0) { |
322 | struct btrfs_csum_item); | 333 | read_extent_buffer(path->nodes[0], |
323 | while (size > 0) { | 334 | §or_sum->sum, |
324 | read_extent_buffer(path->nodes[0], §or_sum->sum, | 335 | ((unsigned long)item) + |
325 | ((unsigned long)item) + offset, | 336 | offset, csum_size); |
326 | csum_size); | 337 | sector_sum->bytenr = start; |
327 | sector_sum->bytenr = start; | 338 | |
328 | 339 | size -= root->sectorsize; | |
329 | size -= root->sectorsize; | 340 | start += root->sectorsize; |
330 | start += root->sectorsize; | 341 | offset += csum_size; |
331 | offset += csum_size; | 342 | sector_sum++; |
332 | sector_sum++; | 343 | } |
344 | list_add_tail(&sums->list, list); | ||
333 | } | 345 | } |
334 | list_add_tail(&sums->list, list); | ||
335 | |||
336 | path->slots[0]++; | 346 | path->slots[0]++; |
337 | } | 347 | } |
338 | ret = 0; | 348 | ret = 0; |