diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-06-18 09:57:58 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-06-18 09:57:58 -0400 |
commit | 8c2383c3dd2cb5bb39598ce4fa97154bc591020a (patch) | |
tree | 68a9c491bfa19d572dca6b41e5dde7f05165c270 /fs | |
parent | 9ebefb180bad4914a31c4e1748ba187a30e1e990 (diff) |
Subject: Rework btrfs_file_write to only allocate while page locks are held
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/disk-io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 1 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 1 | ||||
-rw-r--r-- | fs/btrfs/file.c | 244 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 11 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 18 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 1 |
7 files changed, 161 insertions, 117 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 602b63dc76c3..15cc9ec92308 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -541,6 +541,8 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root | |||
541 | else | 541 | else |
542 | ret = submit_bh(WRITE, bh); | 542 | ret = submit_bh(WRITE, bh); |
543 | if (ret == -EOPNOTSUPP) { | 543 | if (ret == -EOPNOTSUPP) { |
544 | get_bh(bh); | ||
545 | lock_buffer(bh); | ||
544 | set_buffer_uptodate(bh); | 546 | set_buffer_uptodate(bh); |
545 | root->fs_info->do_barriers = 0; | 547 | root->fs_info->do_barriers = 0; |
546 | ret = submit_bh(WRITE, bh); | 548 | ret = submit_bh(WRITE, bh); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5f4eaba8b85f..e0738c65bc5b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1477,7 +1477,6 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1477 | break; | 1477 | break; |
1478 | if (wret < 0) | 1478 | if (wret < 0) |
1479 | ret = wret; | 1479 | ret = wret; |
1480 | btrfs_btree_balance_dirty(root); | ||
1481 | } | 1480 | } |
1482 | for (i = 0; i <= orig_level; i++) { | 1481 | for (i = 0; i <= orig_level; i++) { |
1483 | if (path->nodes[i]) { | 1482 | if (path->nodes[i]) { |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 1068993ab1c9..cf894f09f6c7 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -228,7 +228,6 @@ found: | |||
228 | path->nodes[0]->b_data, | 228 | path->nodes[0]->b_data, |
229 | root->fs_info->sb->s_blocksize); | 229 | root->fs_info->sb->s_blocksize); |
230 | ret = btrfs_csum_data(root, data, len, &item->csum); | 230 | ret = btrfs_csum_data(root, data, len, &item->csum); |
231 | // printk("file %lu offset %llu csum %X\n", objectid, (unsigned long long)offset, *(int *)(&item->csum)); | ||
232 | btrfs_mark_buffer_dirty(path->nodes[0]); | 231 | btrfs_mark_buffer_dirty(path->nodes[0]); |
233 | fail: | 232 | fail: |
234 | btrfs_release_path(root, path); | 233 | btrfs_release_path(root, path); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index de8d47b44e12..6b455c2b3f03 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -207,6 +207,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
207 | } | 207 | } |
208 | path->slots[0]--; | 208 | path->slots[0]--; |
209 | } | 209 | } |
210 | next_slot: | ||
210 | keep = 0; | 211 | keep = 0; |
211 | bookend = 0; | 212 | bookend = 0; |
212 | found_extent = 0; | 213 | found_extent = 0; |
@@ -214,39 +215,48 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
214 | extent = NULL; | 215 | extent = NULL; |
215 | leaf = btrfs_buffer_leaf(path->nodes[0]); | 216 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
216 | slot = path->slots[0]; | 217 | slot = path->slots[0]; |
218 | ret = 0; | ||
217 | btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); | 219 | btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); |
218 | if (key.offset >= end || key.objectid != inode->i_ino) { | 220 | if (key.offset >= end || key.objectid != inode->i_ino) { |
219 | ret = 0; | ||
220 | goto out; | 221 | goto out; |
221 | } | 222 | } |
222 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) { | 223 | if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY) { |
223 | ret = 0; | ||
224 | goto out; | 224 | goto out; |
225 | } | 225 | } |
226 | extent = btrfs_item_ptr(leaf, slot, | 226 | if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { |
227 | struct btrfs_file_extent_item); | 227 | extent = btrfs_item_ptr(leaf, slot, |
228 | found_type = btrfs_file_extent_type(extent); | 228 | struct btrfs_file_extent_item); |
229 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 229 | found_type = btrfs_file_extent_type(extent); |
230 | extent_end = key.offset + | 230 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
231 | (btrfs_file_extent_num_blocks(extent) << | 231 | extent_end = key.offset + |
232 | inode->i_blkbits); | 232 | (btrfs_file_extent_num_blocks(extent) << |
233 | found_extent = 1; | 233 | inode->i_blkbits); |
234 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 234 | found_extent = 1; |
235 | found_inline = 1; | 235 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
236 | extent_end = key.offset + | 236 | found_inline = 1; |
237 | btrfs_file_extent_inline_len(leaf->items + slot); | 237 | extent_end = key.offset + |
238 | btrfs_file_extent_inline_len(leaf->items + | ||
239 | slot); | ||
240 | } | ||
241 | } else { | ||
242 | extent_end = search_start; | ||
238 | } | 243 | } |
239 | 244 | ||
240 | /* we found nothing we can drop */ | 245 | /* we found nothing we can drop */ |
241 | if (!found_extent && !found_inline) { | 246 | if ((!found_extent && !found_inline) || |
242 | ret = 0; | 247 | search_start >= extent_end) { |
243 | goto out; | 248 | int nextret; |
244 | } | 249 | u32 nritems; |
245 | 250 | nritems = btrfs_header_nritems( | |
246 | /* we found nothing inside the range */ | 251 | btrfs_buffer_header(path->nodes[0])); |
247 | if (search_start >= extent_end) { | 252 | if (slot >= nritems - 1) { |
248 | ret = 0; | 253 | nextret = btrfs_next_leaf(root, path); |
249 | goto out; | 254 | if (nextret) |
255 | goto out; | ||
256 | } else { | ||
257 | path->slots[0]++; | ||
258 | } | ||
259 | goto next_slot; | ||
250 | } | 260 | } |
251 | 261 | ||
252 | /* FIXME, there's only one inline extent allowed right now */ | 262 | /* FIXME, there's only one inline extent allowed right now */ |
@@ -272,7 +282,6 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
272 | WARN_ON(found_inline); | 282 | WARN_ON(found_inline); |
273 | bookend = 1; | 283 | bookend = 1; |
274 | } | 284 | } |
275 | |||
276 | /* truncate existing extent */ | 285 | /* truncate existing extent */ |
277 | if (start > key.offset) { | 286 | if (start > key.offset) { |
278 | u64 new_num; | 287 | u64 new_num; |
@@ -337,10 +346,14 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
337 | ins.offset = end; | 346 | ins.offset = end; |
338 | ins.flags = 0; | 347 | ins.flags = 0; |
339 | btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); | 348 | btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); |
340 | |||
341 | btrfs_release_path(root, path); | 349 | btrfs_release_path(root, path); |
342 | ret = btrfs_insert_empty_item(trans, root, path, &ins, | 350 | ret = btrfs_insert_empty_item(trans, root, path, &ins, |
343 | sizeof(*extent)); | 351 | sizeof(*extent)); |
352 | |||
353 | if (ret) { | ||
354 | btrfs_print_leaf(root, btrfs_buffer_leaf(path->nodes[0])); | ||
355 | printk("got %d on inserting %Lu %u %Lu start %Lu end %Lu found %Lu %Lu\n", ret , ins.objectid, ins.flags, ins.offset, start, end, key.offset, extent_end); | ||
356 | } | ||
344 | BUG_ON(ret); | 357 | BUG_ON(ret); |
345 | extent = btrfs_item_ptr( | 358 | extent = btrfs_item_ptr( |
346 | btrfs_buffer_leaf(path->nodes[0]), | 359 | btrfs_buffer_leaf(path->nodes[0]), |
@@ -387,8 +400,7 @@ static int prepare_pages(struct btrfs_root *root, | |||
387 | loff_t pos, | 400 | loff_t pos, |
388 | unsigned long first_index, | 401 | unsigned long first_index, |
389 | unsigned long last_index, | 402 | unsigned long last_index, |
390 | size_t write_bytes, | 403 | size_t write_bytes) |
391 | u64 alloc_extent_start) | ||
392 | { | 404 | { |
393 | int i; | 405 | int i; |
394 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 406 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
@@ -399,6 +411,16 @@ static int prepare_pages(struct btrfs_root *root, | |||
399 | struct buffer_head *bh; | 411 | struct buffer_head *bh; |
400 | struct buffer_head *head; | 412 | struct buffer_head *head; |
401 | loff_t isize = i_size_read(inode); | 413 | loff_t isize = i_size_read(inode); |
414 | struct btrfs_trans_handle *trans; | ||
415 | u64 hint_block; | ||
416 | u64 num_blocks; | ||
417 | u64 alloc_extent_start; | ||
418 | u64 start_pos; | ||
419 | struct btrfs_key ins; | ||
420 | |||
421 | start_pos = pos & ~((u64)PAGE_CACHE_SIZE - 1); | ||
422 | num_blocks = (write_bytes + pos - start_pos + root->blocksize - 1) >> | ||
423 | inode->i_blkbits; | ||
402 | 424 | ||
403 | memset(pages, 0, num_pages * sizeof(struct page *)); | 425 | memset(pages, 0, num_pages * sizeof(struct page *)); |
404 | 426 | ||
@@ -408,6 +430,72 @@ static int prepare_pages(struct btrfs_root *root, | |||
408 | err = -ENOMEM; | 430 | err = -ENOMEM; |
409 | goto failed_release; | 431 | goto failed_release; |
410 | } | 432 | } |
433 | } | ||
434 | |||
435 | mutex_lock(&root->fs_info->fs_mutex); | ||
436 | trans = btrfs_start_transaction(root, 1); | ||
437 | if (!trans) { | ||
438 | err = -ENOMEM; | ||
439 | mutex_unlock(&root->fs_info->fs_mutex); | ||
440 | goto out_unlock; | ||
441 | } | ||
442 | btrfs_set_trans_block_group(trans, inode); | ||
443 | /* FIXME blocksize != 4096 */ | ||
444 | inode->i_blocks += num_blocks << 3; | ||
445 | hint_block = 0; | ||
446 | |||
447 | /* FIXME...EIEIO, ENOSPC and more */ | ||
448 | |||
449 | /* step one, delete the existing extents in this range */ | ||
450 | /* FIXME blocksize != pagesize */ | ||
451 | if (start_pos < inode->i_size) { | ||
452 | err = btrfs_drop_extents(trans, root, inode, | ||
453 | start_pos, (pos + write_bytes + root->blocksize -1) & | ||
454 | ~((u64)root->blocksize - 1), &hint_block); | ||
455 | BUG_ON(err); | ||
456 | } | ||
457 | |||
458 | /* insert any holes we need to create */ | ||
459 | if (inode->i_size < start_pos) { | ||
460 | u64 last_pos_in_file; | ||
461 | u64 hole_size; | ||
462 | u64 mask = root->blocksize - 1; | ||
463 | last_pos_in_file = (isize + mask) & ~mask; | ||
464 | hole_size = (start_pos - last_pos_in_file + mask) & ~mask; | ||
465 | hole_size >>= inode->i_blkbits; | ||
466 | if (last_pos_in_file < start_pos) { | ||
467 | err = btrfs_insert_file_extent(trans, root, | ||
468 | inode->i_ino, | ||
469 | last_pos_in_file, | ||
470 | 0, 0, hole_size); | ||
471 | } | ||
472 | BUG_ON(err); | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * either allocate an extent for the new bytes or setup the key | ||
477 | * to show we are doing inline data in the extent | ||
478 | */ | ||
479 | if (isize >= PAGE_CACHE_SIZE || pos + write_bytes < inode->i_size || | ||
480 | pos + write_bytes - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { | ||
481 | err = btrfs_alloc_extent(trans, root, inode->i_ino, | ||
482 | num_blocks, hint_block, (u64)-1, | ||
483 | &ins, 1); | ||
484 | BUG_ON(err); | ||
485 | err = btrfs_insert_file_extent(trans, root, inode->i_ino, | ||
486 | start_pos, ins.objectid, ins.offset, | ||
487 | ins.offset); | ||
488 | BUG_ON(err); | ||
489 | } else { | ||
490 | ins.offset = 0; | ||
491 | ins.objectid = 0; | ||
492 | } | ||
493 | BUG_ON(err); | ||
494 | alloc_extent_start = ins.objectid; | ||
495 | err = btrfs_end_transaction(trans, root); | ||
496 | mutex_unlock(&root->fs_info->fs_mutex); | ||
497 | |||
498 | for (i = 0; i < num_pages; i++) { | ||
411 | cancel_dirty_page(pages[i], PAGE_CACHE_SIZE); | 499 | cancel_dirty_page(pages[i], PAGE_CACHE_SIZE); |
412 | wait_on_page_writeback(pages[i]); | 500 | wait_on_page_writeback(pages[i]); |
413 | offset = pos & (PAGE_CACHE_SIZE -1); | 501 | offset = pos & (PAGE_CACHE_SIZE -1); |
@@ -444,6 +532,11 @@ failed_truncate: | |||
444 | if (pos > isize) | 532 | if (pos > isize) |
445 | vmtruncate(inode, isize); | 533 | vmtruncate(inode, isize); |
446 | return err; | 534 | return err; |
535 | |||
536 | out_unlock: | ||
537 | mutex_unlock(&root->fs_info->fs_mutex); | ||
538 | goto failed_release; | ||
539 | |||
447 | } | 540 | } |
448 | 541 | ||
449 | static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | 542 | static ssize_t btrfs_file_write(struct file *file, const char __user *buf, |
@@ -455,16 +548,14 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
455 | int ret = 0; | 548 | int ret = 0; |
456 | struct inode *inode = file->f_path.dentry->d_inode; | 549 | struct inode *inode = file->f_path.dentry->d_inode; |
457 | struct btrfs_root *root = BTRFS_I(inode)->root; | 550 | struct btrfs_root *root = BTRFS_I(inode)->root; |
458 | struct page *pages[8]; | 551 | struct page **pages = NULL; |
552 | int nrptrs; | ||
459 | struct page *pinned[2]; | 553 | struct page *pinned[2]; |
460 | unsigned long first_index; | 554 | unsigned long first_index; |
461 | unsigned long last_index; | 555 | unsigned long last_index; |
462 | u64 start_pos; | 556 | |
463 | u64 num_blocks; | 557 | nrptrs = min((count + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE, |
464 | u64 alloc_extent_start; | 558 | PAGE_CACHE_SIZE / (sizeof(struct page *))); |
465 | u64 hint_block; | ||
466 | struct btrfs_trans_handle *trans; | ||
467 | struct btrfs_key ins; | ||
468 | pinned[0] = NULL; | 559 | pinned[0] = NULL; |
469 | pinned[1] = NULL; | 560 | pinned[1] = NULL; |
470 | if (file->f_flags & O_DIRECT) | 561 | if (file->f_flags & O_DIRECT) |
@@ -482,9 +573,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
482 | goto out; | 573 | goto out; |
483 | file_update_time(file); | 574 | file_update_time(file); |
484 | 575 | ||
485 | start_pos = pos & ~((u64)PAGE_CACHE_SIZE - 1); | 576 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); |
486 | num_blocks = (count + pos - start_pos + root->blocksize - 1) >> | ||
487 | inode->i_blkbits; | ||
488 | 577 | ||
489 | mutex_lock(&inode->i_mutex); | 578 | mutex_lock(&inode->i_mutex); |
490 | first_index = pos >> PAGE_CACHE_SHIFT; | 579 | first_index = pos >> PAGE_CACHE_SHIFT; |
@@ -516,87 +605,20 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
516 | } | 605 | } |
517 | } | 606 | } |
518 | 607 | ||
519 | mutex_lock(&root->fs_info->fs_mutex); | ||
520 | trans = btrfs_start_transaction(root, 1); | ||
521 | if (!trans) { | ||
522 | err = -ENOMEM; | ||
523 | mutex_unlock(&root->fs_info->fs_mutex); | ||
524 | goto out_unlock; | ||
525 | } | ||
526 | btrfs_set_trans_block_group(trans, inode); | ||
527 | /* FIXME blocksize != 4096 */ | ||
528 | inode->i_blocks += num_blocks << 3; | ||
529 | hint_block = 0; | ||
530 | |||
531 | /* FIXME...EIEIO, ENOSPC and more */ | ||
532 | |||
533 | /* step one, delete the existing extents in this range */ | ||
534 | if (start_pos < inode->i_size) { | ||
535 | /* FIXME blocksize != pagesize */ | ||
536 | ret = btrfs_drop_extents(trans, root, inode, | ||
537 | start_pos, | ||
538 | (pos + count + root->blocksize -1) & | ||
539 | ~((u64)root->blocksize - 1), | ||
540 | &hint_block); | ||
541 | BUG_ON(ret); | ||
542 | } | ||
543 | |||
544 | /* insert any holes we need to create */ | ||
545 | if (inode->i_size < start_pos) { | ||
546 | u64 last_pos_in_file; | ||
547 | u64 hole_size; | ||
548 | u64 mask = root->blocksize - 1; | ||
549 | last_pos_in_file = (inode->i_size + mask) & ~mask; | ||
550 | hole_size = (start_pos - last_pos_in_file + mask) & ~mask; | ||
551 | hole_size >>= inode->i_blkbits; | ||
552 | if (last_pos_in_file < start_pos) { | ||
553 | ret = btrfs_insert_file_extent(trans, root, | ||
554 | inode->i_ino, | ||
555 | last_pos_in_file, | ||
556 | 0, 0, hole_size); | ||
557 | } | ||
558 | BUG_ON(ret); | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * either allocate an extent for the new bytes or setup the key | ||
563 | * to show we are doing inline data in the extent | ||
564 | */ | ||
565 | if (inode->i_size >= PAGE_CACHE_SIZE || pos + count < inode->i_size || | ||
566 | pos + count - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { | ||
567 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, | ||
568 | num_blocks, hint_block, (u64)-1, | ||
569 | &ins, 1); | ||
570 | BUG_ON(ret); | ||
571 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, | ||
572 | start_pos, ins.objectid, ins.offset, | ||
573 | ins.offset); | ||
574 | BUG_ON(ret); | ||
575 | } else { | ||
576 | ins.offset = 0; | ||
577 | ins.objectid = 0; | ||
578 | } | ||
579 | BUG_ON(ret); | ||
580 | alloc_extent_start = ins.objectid; | ||
581 | ret = btrfs_end_transaction(trans, root); | ||
582 | mutex_unlock(&root->fs_info->fs_mutex); | ||
583 | |||
584 | while(count > 0) { | 608 | while(count > 0) { |
585 | size_t offset = pos & (PAGE_CACHE_SIZE - 1); | 609 | size_t offset = pos & (PAGE_CACHE_SIZE - 1); |
586 | size_t write_bytes = min(count, | 610 | size_t write_bytes = min(count, nrptrs * PAGE_CACHE_SIZE - |
587 | (size_t)PAGE_CACHE_SIZE - offset); | 611 | offset); |
588 | size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> | 612 | size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> |
589 | PAGE_CACHE_SHIFT; | 613 | PAGE_CACHE_SHIFT; |
590 | 614 | ||
615 | WARN_ON(num_pages > nrptrs); | ||
591 | memset(pages, 0, sizeof(pages)); | 616 | memset(pages, 0, sizeof(pages)); |
592 | ret = prepare_pages(root, file, pages, num_pages, | 617 | ret = prepare_pages(root, file, pages, num_pages, |
593 | pos, first_index, last_index, | 618 | pos, first_index, last_index, |
594 | write_bytes, alloc_extent_start); | 619 | write_bytes); |
595 | BUG_ON(ret); | 620 | BUG_ON(ret); |
596 | 621 | ||
597 | /* FIXME blocks != pagesize */ | ||
598 | if (alloc_extent_start) | ||
599 | alloc_extent_start += num_pages; | ||
600 | ret = btrfs_copy_from_user(pos, num_pages, | 622 | ret = btrfs_copy_from_user(pos, num_pages, |
601 | write_bytes, pages, buf); | 623 | write_bytes, pages, buf); |
602 | BUG_ON(ret); | 624 | BUG_ON(ret); |
@@ -611,13 +633,13 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
611 | pos += write_bytes; | 633 | pos += write_bytes; |
612 | num_written += write_bytes; | 634 | num_written += write_bytes; |
613 | 635 | ||
614 | balance_dirty_pages_ratelimited(inode->i_mapping); | 636 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages); |
615 | btrfs_btree_balance_dirty(root); | 637 | btrfs_btree_balance_dirty(root); |
616 | cond_resched(); | 638 | cond_resched(); |
617 | } | 639 | } |
618 | out_unlock: | ||
619 | mutex_unlock(&inode->i_mutex); | 640 | mutex_unlock(&inode->i_mutex); |
620 | out: | 641 | out: |
642 | kfree(pages); | ||
621 | if (pinned[0]) | 643 | if (pinned[0]) |
622 | page_cache_release(pinned[0]); | 644 | page_cache_release(pinned[0]); |
623 | if (pinned[1]) | 645 | if (pinned[1]) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index def33ac90d77..94f1c28c25b9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -962,7 +962,6 @@ void btrfs_dirty_inode(struct inode *inode) | |||
962 | btrfs_update_inode(trans, root, inode); | 962 | btrfs_update_inode(trans, root, inode); |
963 | btrfs_end_transaction(trans, root); | 963 | btrfs_end_transaction(trans, root); |
964 | mutex_unlock(&root->fs_info->fs_mutex); | 964 | mutex_unlock(&root->fs_info->fs_mutex); |
965 | btrfs_btree_balance_dirty(root); | ||
966 | } | 965 | } |
967 | 966 | ||
968 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | 967 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, |
@@ -1402,7 +1401,6 @@ int btrfs_get_block_csum(struct inode *inode, sector_t iblock, | |||
1402 | goto out; | 1401 | goto out; |
1403 | } | 1402 | } |
1404 | memcpy((char *)&result->b_private, &item->csum, BTRFS_CRC32_SIZE); | 1403 | memcpy((char *)&result->b_private, &item->csum, BTRFS_CRC32_SIZE); |
1405 | printk("get_block_sum file %lu offset %llu csum %X\n", inode->i_ino, (unsigned long long)offset, *(int *)(&item->csum)); | ||
1406 | out: | 1404 | out: |
1407 | if (path) | 1405 | if (path) |
1408 | btrfs_free_path(path); | 1406 | btrfs_free_path(path); |
@@ -1476,7 +1474,6 @@ static void btrfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
1476 | (unsigned long long)offset); | 1474 | (unsigned long long)offset); |
1477 | memset(kaddr + bh_offset(bh), 1, bh->b_size); | 1475 | memset(kaddr + bh_offset(bh), 1, bh->b_size); |
1478 | flush_dcache_page(page); | 1476 | flush_dcache_page(page); |
1479 | printk("bad verify file %lu offset %llu bh_private %lX csum %X\n", inode->i_ino, (unsigned long long)offset, (unsigned long)(bh->b_private), *(int *)csum); | ||
1480 | } | 1477 | } |
1481 | kunmap_atomic(kaddr, KM_IRQ0); | 1478 | kunmap_atomic(kaddr, KM_IRQ0); |
1482 | } | 1479 | } |
@@ -1655,6 +1652,13 @@ static int __btrfs_write_full_page(struct inode *inode, struct page *page, | |||
1655 | 1652 | ||
1656 | last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; | 1653 | last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; |
1657 | 1654 | ||
1655 | /* no csumming allowed when from PF_MEMALLOC */ | ||
1656 | if (current->flags & PF_MEMALLOC) { | ||
1657 | redirty_page_for_writepage(wbc, page); | ||
1658 | unlock_page(page); | ||
1659 | return 0; | ||
1660 | } | ||
1661 | |||
1658 | if (!page_has_buffers(page)) { | 1662 | if (!page_has_buffers(page)) { |
1659 | create_empty_buffers(page, blocksize, | 1663 | create_empty_buffers(page, blocksize, |
1660 | (1 << BH_Dirty)|(1 << BH_Uptodate)); | 1664 | (1 << BH_Dirty)|(1 << BH_Uptodate)); |
@@ -1885,7 +1889,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
1885 | 1889 | ||
1886 | lock_page(page); | 1890 | lock_page(page); |
1887 | wait_on_page_writeback(page); | 1891 | wait_on_page_writeback(page); |
1888 | printk("btrfs_page_mkwrite %lu %lu\n", page->mapping->host->i_ino, page->index); | ||
1889 | size = i_size_read(inode); | 1892 | size = i_size_read(inode); |
1890 | if ((page->mapping != inode->i_mapping) || | 1893 | if ((page->mapping != inode->i_mapping) || |
1891 | ((page->index << PAGE_CACHE_SHIFT) > size)) { | 1894 | ((page->index << PAGE_CACHE_SHIFT) > size)) { |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 1fa705683008..e66acd4e2745 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -31,6 +31,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) | |||
31 | struct btrfs_dir_item *di; | 31 | struct btrfs_dir_item *di; |
32 | struct btrfs_inode_item *ii; | 32 | struct btrfs_inode_item *ii; |
33 | struct btrfs_block_group_item *bi; | 33 | struct btrfs_block_group_item *bi; |
34 | struct btrfs_file_extent_item *fi; | ||
34 | u32 type; | 35 | u32 type; |
35 | 36 | ||
36 | printk("leaf %llu total ptrs %d free space %d\n", | 37 | printk("leaf %llu total ptrs %d free space %d\n", |
@@ -75,6 +76,23 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) | |||
75 | printk("\t\textent data refs %u\n", | 76 | printk("\t\textent data refs %u\n", |
76 | btrfs_extent_refs(ei)); | 77 | btrfs_extent_refs(ei)); |
77 | break; | 78 | break; |
79 | |||
80 | case BTRFS_EXTENT_DATA_KEY: | ||
81 | fi = btrfs_item_ptr(l, i, | ||
82 | struct btrfs_file_extent_item); | ||
83 | if (btrfs_file_extent_type(fi) == | ||
84 | BTRFS_FILE_EXTENT_INLINE) { | ||
85 | printk("\t\tinline extent data size %u\n", | ||
86 | btrfs_file_extent_inline_len(l->items + i)); | ||
87 | break; | ||
88 | } | ||
89 | printk("\t\textent data disk block %llu nr %llu\n", | ||
90 | (unsigned long long)btrfs_file_extent_disk_blocknr(fi), | ||
91 | (unsigned long long)btrfs_file_extent_disk_num_blocks(fi)); | ||
92 | printk("\t\textent data offset %llu nr %llu\n", | ||
93 | (unsigned long long)btrfs_file_extent_offset(fi), | ||
94 | (unsigned long long)btrfs_file_extent_num_blocks(fi)); | ||
95 | break; | ||
78 | case BTRFS_BLOCK_GROUP_ITEM_KEY: | 96 | case BTRFS_BLOCK_GROUP_ITEM_KEY: |
79 | bi = btrfs_item_ptr(l, i, | 97 | bi = btrfs_item_ptr(l, i, |
80 | struct btrfs_block_group_item); | 98 | struct btrfs_block_group_item); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index cd4f1d140385..b5b99a85763f 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -279,6 +279,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
279 | BUG_ON(ret); | 279 | BUG_ON(ret); |
280 | kfree(dirty); | 280 | kfree(dirty); |
281 | mutex_unlock(&tree_root->fs_info->fs_mutex); | 281 | mutex_unlock(&tree_root->fs_info->fs_mutex); |
282 | btrfs_btree_balance_dirty(tree_root); | ||
282 | } | 283 | } |
283 | return 0; | 284 | return 0; |
284 | } | 285 | } |