summaryrefslogtreecommitdiff
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-02-08 13:49:28 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit9069218d448ea547dbad5f1cbd537e88d6519d66 (patch)
treefafb142a36805f26678bb4e7a0ebe50d8c7f859a /fs/btrfs/file.c
parenta86c12c73d982c545a37a8ecdd66528ab260b770 (diff)
downloadlwn-9069218d448ea547dbad5f1cbd537e88d6519d66.tar.gz
lwn-9069218d448ea547dbad5f1cbd537e88d6519d66.zip
Btrfs: Fix i_blocks accounting
Now that delayed allocation accounting works, i_blocks accounting is changed to only modify i_blocks when extents inserted or removed. The fillattr call is changed to include the delayed allocation byte count in the i_blocks result. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index bfa4149c053d..f89396082544 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -175,6 +175,7 @@ static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
leaf = path->nodes[0];
ei = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
+ inode->i_blocks += (offset + size - found_end) >> 9;
}
if (found_end < offset) {
ptr = btrfs_file_extent_inline_start(ei) + found_size;
@@ -184,6 +185,7 @@ static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
insert:
btrfs_release_path(root, path);
datasize = offset + size - key.offset;
+ inode->i_blocks += datasize >> 9;
datasize = btrfs_file_extent_calc_inline_size(datasize);
ret = btrfs_insert_empty_item(trans, root, path, &key,
datasize);
@@ -256,7 +258,6 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
goto out_unlock;
}
btrfs_set_trans_block_group(trans, inode);
- inode->i_blocks += num_bytes >> 9;
hint_byte = 0;
if ((end_of_last_block & 4095) == 0) {
@@ -410,7 +411,7 @@ int btrfs_check_file(struct btrfs_root *root, struct inode *inode)
if (found_key.type != BTRFS_EXTENT_DATA_KEY)
goto out;
- if (found_key.offset != last_offset) {
+ if (found_key.offset < last_offset) {
WARN_ON(1);
btrfs_print_leaf(root, leaf);
printk("inode %lu found offset %Lu expected %Lu\n",
@@ -435,7 +436,7 @@ int btrfs_check_file(struct btrfs_root *root, struct inode *inode)
last_offset = extent_end;
path->slots[0]++;
}
- if (last_offset < inode->i_size) {
+ if (0 && last_offset < inode->i_size) {
WARN_ON(1);
btrfs_print_leaf(root, leaf);
printk("inode %lu found offset %Lu size %Lu\n", inode->i_ino,
@@ -608,8 +609,7 @@ next_slot:
extent);
if (btrfs_file_extent_disk_bytenr(leaf,
extent)) {
- inode->i_blocks -=
- (old_num - new_num) >> 9;
+ dec_i_blocks(inode, old_num - new_num);
}
btrfs_set_file_extent_num_bytes(leaf, extent,
new_num);
@@ -620,6 +620,8 @@ next_slot:
u32 new_size;
new_size = btrfs_file_extent_calc_inline_size(
inline_limit - key.offset);
+ dec_i_blocks(inode, (extent_end - key.offset) -
+ (inline_limit - key.offset));
btrfs_truncate_item(trans, root, path,
new_size, 1);
}
@@ -653,7 +655,7 @@ next_slot:
btrfs_release_path(root, path);
extent = NULL;
if (found_extent && disk_bytenr != 0) {
- inode->i_blocks -= extent_num_bytes >> 9;
+ dec_i_blocks(inode, extent_num_bytes);
ret = btrfs_free_extent(trans, root,
disk_bytenr,
disk_num_bytes,
@@ -674,6 +676,8 @@ next_slot:
u32 new_size;
new_size = btrfs_file_extent_calc_inline_size(
extent_end - end);
+ dec_i_blocks(inode, (extent_end - key.offset) -
+ (extent_end - end));
btrfs_truncate_item(trans, root, path, new_size, 0);
}
/* create bookend, splitting the extent in two */
@@ -718,6 +722,7 @@ next_slot:
}
out:
btrfs_free_path(path);
+ btrfs_check_file(root, inode);
return ret;
}