diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9e138b793dc7..dae12dc7e159 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3032,12 +3032,22 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
3032 | 3032 | ||
3033 | if ((offset & (blocksize - 1)) == 0) | 3033 | if ((offset & (blocksize - 1)) == 0) |
3034 | goto out; | 3034 | goto out; |
3035 | ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); | ||
3036 | if (ret) | ||
3037 | goto out; | ||
3038 | |||
3039 | ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1); | ||
3040 | if (ret) | ||
3041 | goto out; | ||
3035 | 3042 | ||
3036 | ret = -ENOMEM; | 3043 | ret = -ENOMEM; |
3037 | again: | 3044 | again: |
3038 | page = grab_cache_page(mapping, index); | 3045 | page = grab_cache_page(mapping, index); |
3039 | if (!page) | 3046 | if (!page) { |
3047 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
3048 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
3040 | goto out; | 3049 | goto out; |
3050 | } | ||
3041 | 3051 | ||
3042 | page_start = page_offset(page); | 3052 | page_start = page_offset(page); |
3043 | page_end = page_start + PAGE_CACHE_SIZE - 1; | 3053 | page_end = page_start + PAGE_CACHE_SIZE - 1; |
@@ -3070,6 +3080,10 @@ again: | |||
3070 | goto again; | 3080 | goto again; |
3071 | } | 3081 | } |
3072 | 3082 | ||
3083 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, | ||
3084 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, | ||
3085 | GFP_NOFS); | ||
3086 | |||
3073 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); | 3087 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); |
3074 | if (ret) { | 3088 | if (ret) { |
3075 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3089 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
@@ -3088,6 +3102,9 @@ again: | |||
3088 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3102 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
3089 | 3103 | ||
3090 | out_unlock: | 3104 | out_unlock: |
3105 | if (ret) | ||
3106 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
3107 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
3091 | unlock_page(page); | 3108 | unlock_page(page); |
3092 | page_cache_release(page); | 3109 | page_cache_release(page); |
3093 | out: | 3110 | out: |
@@ -3111,7 +3128,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
3111 | if (size <= hole_start) | 3128 | if (size <= hole_start) |
3112 | return 0; | 3129 | return 0; |
3113 | 3130 | ||
3114 | btrfs_truncate_page(inode->i_mapping, inode->i_size); | 3131 | err = btrfs_truncate_page(inode->i_mapping, inode->i_size); |
3132 | if (err) | ||
3133 | return err; | ||
3115 | 3134 | ||
3116 | while (1) { | 3135 | while (1) { |
3117 | struct btrfs_ordered_extent *ordered; | 3136 | struct btrfs_ordered_extent *ordered; |
@@ -3480,6 +3499,7 @@ static noinline void init_btrfs_i(struct inode *inode) | |||
3480 | bi->generation = 0; | 3499 | bi->generation = 0; |
3481 | bi->sequence = 0; | 3500 | bi->sequence = 0; |
3482 | bi->last_trans = 0; | 3501 | bi->last_trans = 0; |
3502 | bi->last_sub_trans = 0; | ||
3483 | bi->logged_trans = 0; | 3503 | bi->logged_trans = 0; |
3484 | bi->delalloc_bytes = 0; | 3504 | bi->delalloc_bytes = 0; |
3485 | bi->reserved_bytes = 0; | 3505 | bi->reserved_bytes = 0; |
@@ -4980,7 +5000,9 @@ again: | |||
4980 | set_page_dirty(page); | 5000 | set_page_dirty(page); |
4981 | SetPageUptodate(page); | 5001 | SetPageUptodate(page); |
4982 | 5002 | ||
4983 | BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; | 5003 | BTRFS_I(inode)->last_trans = root->fs_info->generation; |
5004 | BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; | ||
5005 | |||
4984 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 5006 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
4985 | 5007 | ||
4986 | out_unlock: | 5008 | out_unlock: |
@@ -5005,7 +5027,9 @@ static void btrfs_truncate(struct inode *inode) | |||
5005 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 5027 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
5006 | return; | 5028 | return; |
5007 | 5029 | ||
5008 | btrfs_truncate_page(inode->i_mapping, inode->i_size); | 5030 | ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); |
5031 | if (ret) | ||
5032 | return; | ||
5009 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); | 5033 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); |
5010 | 5034 | ||
5011 | trans = btrfs_start_transaction(root, 1); | 5035 | trans = btrfs_start_transaction(root, 1); |
@@ -5100,6 +5124,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
5100 | if (!ei) | 5124 | if (!ei) |
5101 | return NULL; | 5125 | return NULL; |
5102 | ei->last_trans = 0; | 5126 | ei->last_trans = 0; |
5127 | ei->last_sub_trans = 0; | ||
5103 | ei->logged_trans = 0; | 5128 | ei->logged_trans = 0; |
5104 | ei->outstanding_extents = 0; | 5129 | ei->outstanding_extents = 0; |
5105 | ei->reserved_extents = 0; | 5130 | ei->reserved_extents = 0; |