aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/free-space-cache.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-08-30 10:19:10 -0400
committerJosef Bacik <josef@redhat.com>2011-10-19 15:12:42 -0400
commitc09544e07f8cdc455ed8615d4c067d694c33bd18 (patch)
treec9943e56457ac64e2223396841e043e4514462e0 /fs/btrfs/free-space-cache.c
parent300e4f8a56f263797568c95b71c949f9f02e4534 (diff)
Btrfs: handle enospc accounting for free space inodes
Since free space inodes now use normal checksumming we need to make sure to account for their metadata use. So reserve metadata space, and then if we fail to write out the metadata we can just release it, otherwise it will be freed up when the io completes. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r--fs/btrfs/free-space-cache.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 1ea10731797a..3bde17ff14c0 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -532,6 +532,19 @@ out:
532 return ret; 532 return ret;
533} 533}
534 534
535/**
536 * __btrfs_write_out_cache - write out cached info to an inode
537 * @root - the root the inode belongs to
538 * @ctl - the free space cache we are going to write out
539 * @block_group - the block_group for this cache if it belongs to a block_group
540 * @trans - the trans handle
541 * @path - the path to use
542 * @offset - the offset for the key we'll insert
543 *
544 * This function writes out a free space cache struct to disk for quick recovery
545 * on mount. This will return 0 if it was successfull in writing the cache out,
546 * and -1 if it was not.
547 */
535int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, 548int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
536 struct btrfs_free_space_ctl *ctl, 549 struct btrfs_free_space_ctl *ctl,
537 struct btrfs_block_group_cache *block_group, 550 struct btrfs_block_group_cache *block_group,
@@ -555,7 +568,8 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
555 int index = 0, num_pages = 0; 568 int index = 0, num_pages = 0;
556 int entries = 0; 569 int entries = 0;
557 int bitmaps = 0; 570 int bitmaps = 0;
558 int ret = -1; 571 int ret;
572 int err = -1;
559 bool next_page = false; 573 bool next_page = false;
560 bool out_of_space = false; 574 bool out_of_space = false;
561 575
@@ -563,7 +577,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
563 577
564 node = rb_first(&ctl->free_space_offset); 578 node = rb_first(&ctl->free_space_offset);
565 if (!node) 579 if (!node)
566 return 0; 580 return -1;
567 581
568 if (!i_size_read(inode)) 582 if (!i_size_read(inode))
569 return -1; 583 return -1;
@@ -767,7 +781,6 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
767 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, 781 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
768 i_size_read(inode) - 1, &cached_state, 782 i_size_read(inode) - 1, &cached_state,
769 GFP_NOFS); 783 GFP_NOFS);
770 ret = 0;
771 goto out; 784 goto out;
772 } 785 }
773 786
@@ -789,10 +802,8 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
789 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, 802 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
790 i_size_read(inode) - 1, &cached_state, GFP_NOFS); 803 i_size_read(inode) - 1, &cached_state, GFP_NOFS);
791 804
792 if (ret) { 805 if (ret)
793 ret = 0;
794 goto out; 806 goto out;
795 }
796 807
797 BTRFS_I(inode)->generation = trans->transid; 808 BTRFS_I(inode)->generation = trans->transid;
798 809
@@ -804,7 +815,6 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
804 815
805 ret = btrfs_search_slot(trans, root, &key, path, 0, 1); 816 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
806 if (ret < 0) { 817 if (ret < 0) {
807 ret = -1;
808 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1, 818 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1,
809 EXTENT_DIRTY | EXTENT_DELALLOC | 819 EXTENT_DIRTY | EXTENT_DELALLOC |
810 EXTENT_DO_ACCOUNTING, 0, 0, NULL, GFP_NOFS); 820 EXTENT_DO_ACCOUNTING, 0, 0, NULL, GFP_NOFS);
@@ -818,7 +828,6 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
818 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 828 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
819 if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID || 829 if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID ||
820 found_key.offset != offset) { 830 found_key.offset != offset) {
821 ret = -1;
822 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1, 831 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1,
823 EXTENT_DIRTY | EXTENT_DELALLOC | 832 EXTENT_DIRTY | EXTENT_DELALLOC |
824 EXTENT_DO_ACCOUNTING, 0, 0, NULL, 833 EXTENT_DO_ACCOUNTING, 0, 0, NULL,
@@ -835,16 +844,15 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
835 btrfs_mark_buffer_dirty(leaf); 844 btrfs_mark_buffer_dirty(leaf);
836 btrfs_release_path(path); 845 btrfs_release_path(path);
837 846
838 ret = 1; 847 err = 0;
839
840out: 848out:
841 kfree(pages); 849 kfree(pages);
842 if (ret != 1) { 850 if (err) {
843 invalidate_inode_pages2_range(inode->i_mapping, 0, index); 851 invalidate_inode_pages2_range(inode->i_mapping, 0, index);
844 BTRFS_I(inode)->generation = 0; 852 BTRFS_I(inode)->generation = 0;
845 } 853 }
846 btrfs_update_inode(trans, root, inode); 854 btrfs_update_inode(trans, root, inode);
847 return ret; 855 return err;
848} 856}
849 857
850int btrfs_write_out_cache(struct btrfs_root *root, 858int btrfs_write_out_cache(struct btrfs_root *root,
@@ -871,14 +879,16 @@ int btrfs_write_out_cache(struct btrfs_root *root,
871 879
872 ret = __btrfs_write_out_cache(root, inode, ctl, block_group, trans, 880 ret = __btrfs_write_out_cache(root, inode, ctl, block_group, trans,
873 path, block_group->key.objectid); 881 path, block_group->key.objectid);
874 if (ret < 0) { 882 if (ret) {
883 btrfs_delalloc_release_metadata(inode, inode->i_size);
875 spin_lock(&block_group->lock); 884 spin_lock(&block_group->lock);
876 block_group->disk_cache_state = BTRFS_DC_ERROR; 885 block_group->disk_cache_state = BTRFS_DC_ERROR;
877 spin_unlock(&block_group->lock); 886 spin_unlock(&block_group->lock);
878 ret = 0; 887 ret = 0;
879 888#ifdef DEBUG
880 printk(KERN_ERR "btrfs: failed to write free space cace " 889 printk(KERN_ERR "btrfs: failed to write free space cace "
881 "for block group %llu\n", block_group->key.objectid); 890 "for block group %llu\n", block_group->key.objectid);
891#endif
882 } 892 }
883 893
884 iput(inode); 894 iput(inode);
@@ -2662,9 +2672,13 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
2662 return 0; 2672 return 0;
2663 2673
2664 ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0); 2674 ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0);
2665 if (ret < 0) 2675 if (ret) {
2676 btrfs_delalloc_release_metadata(inode, inode->i_size);
2677#ifdef DEBUG
2666 printk(KERN_ERR "btrfs: failed to write free ino cache " 2678 printk(KERN_ERR "btrfs: failed to write free ino cache "
2667 "for root %llu\n", root->root_key.objectid); 2679 "for root %llu\n", root->root_key.objectid);
2680#endif
2681 }
2668 2682
2669 iput(inode); 2683 iput(inode);
2670 return ret; 2684 return ret;