diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-05-24 13:35:57 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-05-24 13:35:57 -0400 |
commit | 3a686375629da5d2e2ad019265b66ef113c87455 (patch) | |
tree | 1fbbedfcb92aeea38d90955ef11975187ddcc6f3 /fs | |
parent | 2b8d99a723a3186a69b5bd941a272dbecae9205b (diff) |
Btrfs: sparse files!
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 14 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 11 | ||||
-rw-r--r-- | fs/btrfs/super.c | 121 |
4 files changed, 116 insertions, 31 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3330004af1a6..e8f741167c6b 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1180,6 +1180,7 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1180 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 1180 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
1181 | struct btrfs_root *root, | 1181 | struct btrfs_root *root, |
1182 | u64 objectid, u64 pos, u64 offset, | 1182 | u64 objectid, u64 pos, u64 offset, |
1183 | u64 disk_num_blocks, | ||
1183 | u64 num_blocks); | 1184 | u64 num_blocks); |
1184 | int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, | 1185 | int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, |
1185 | struct btrfs_root *root, | 1186 | struct btrfs_root *root, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e3c6bfea3751..a366415e03a6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -443,6 +443,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
443 | buf_leaf = btrfs_buffer_leaf(buf); | 443 | buf_leaf = btrfs_buffer_leaf(buf); |
444 | for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) { | 444 | for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) { |
445 | if (leaf) { | 445 | if (leaf) { |
446 | u64 disk_blocknr; | ||
446 | key = &buf_leaf->items[i].key; | 447 | key = &buf_leaf->items[i].key; |
447 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) | 448 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) |
448 | continue; | 449 | continue; |
@@ -451,8 +452,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
451 | if (btrfs_file_extent_type(fi) == | 452 | if (btrfs_file_extent_type(fi) == |
452 | BTRFS_FILE_EXTENT_INLINE) | 453 | BTRFS_FILE_EXTENT_INLINE) |
453 | continue; | 454 | continue; |
454 | ret = btrfs_inc_extent_ref(trans, root, | 455 | disk_blocknr = btrfs_file_extent_disk_blocknr(fi); |
455 | btrfs_file_extent_disk_blocknr(fi), | 456 | if (disk_blocknr == 0) |
457 | continue; | ||
458 | ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, | ||
456 | btrfs_file_extent_disk_num_blocks(fi)); | 459 | btrfs_file_extent_disk_num_blocks(fi)); |
457 | BUG_ON(ret); | 460 | BUG_ON(ret); |
458 | } else { | 461 | } else { |
@@ -1248,6 +1251,7 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1248 | leaf = btrfs_buffer_leaf(cur); | 1251 | leaf = btrfs_buffer_leaf(cur); |
1249 | nritems = btrfs_header_nritems(&leaf->header); | 1252 | nritems = btrfs_header_nritems(&leaf->header); |
1250 | for (i = 0; i < nritems; i++) { | 1253 | for (i = 0; i < nritems; i++) { |
1254 | u64 disk_blocknr; | ||
1251 | key = &leaf->items[i].key; | 1255 | key = &leaf->items[i].key; |
1252 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) | 1256 | if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) |
1253 | continue; | 1257 | continue; |
@@ -1258,8 +1262,10 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1258 | * FIXME make sure to insert a trans record that | 1262 | * FIXME make sure to insert a trans record that |
1259 | * repeats the snapshot del on crash | 1263 | * repeats the snapshot del on crash |
1260 | */ | 1264 | */ |
1261 | ret = btrfs_free_extent(trans, root, | 1265 | disk_blocknr = btrfs_file_extent_disk_blocknr(fi); |
1262 | btrfs_file_extent_disk_blocknr(fi), | 1266 | if (disk_blocknr == 0) |
1267 | continue; | ||
1268 | ret = btrfs_free_extent(trans, root, disk_blocknr, | ||
1263 | btrfs_file_extent_disk_num_blocks(fi), | 1269 | btrfs_file_extent_disk_num_blocks(fi), |
1264 | 0); | 1270 | 0); |
1265 | BUG_ON(ret); | 1271 | BUG_ON(ret); |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index a66709e6d036..7990b5742114 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -9,7 +9,8 @@ | |||
9 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 9 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
10 | struct btrfs_root *root, | 10 | struct btrfs_root *root, |
11 | u64 objectid, u64 pos, | 11 | u64 objectid, u64 pos, |
12 | u64 offset, u64 num_blocks) | 12 | u64 offset, u64 disk_num_blocks, |
13 | u64 num_blocks) | ||
13 | { | 14 | { |
14 | int ret = 0; | 15 | int ret = 0; |
15 | struct btrfs_file_extent_item *item; | 16 | struct btrfs_file_extent_item *item; |
@@ -30,7 +31,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | |||
30 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], | 31 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
31 | struct btrfs_file_extent_item); | 32 | struct btrfs_file_extent_item); |
32 | btrfs_set_file_extent_disk_blocknr(item, offset); | 33 | btrfs_set_file_extent_disk_blocknr(item, offset); |
33 | btrfs_set_file_extent_disk_num_blocks(item, num_blocks); | 34 | btrfs_set_file_extent_disk_num_blocks(item, disk_num_blocks); |
34 | btrfs_set_file_extent_offset(item, 0); | 35 | btrfs_set_file_extent_offset(item, 0); |
35 | btrfs_set_file_extent_num_blocks(item, num_blocks); | 36 | btrfs_set_file_extent_num_blocks(item, num_blocks); |
36 | btrfs_set_file_extent_generation(item, trans->transid); | 37 | btrfs_set_file_extent_generation(item, trans->transid); |
@@ -176,14 +177,14 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
176 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || | 177 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || |
177 | found_key.objectid != objectid || | 178 | found_key.objectid != objectid || |
178 | csum_offset >= MAX_CSUM_ITEMS(root)) { | 179 | csum_offset >= MAX_CSUM_ITEMS(root)) { |
179 | WARN_ON(1); | ||
180 | goto insert; | 180 | goto insert; |
181 | } | 181 | } |
182 | if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) / | 182 | if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) / |
183 | BTRFS_CRC32_SIZE) { | 183 | BTRFS_CRC32_SIZE) { |
184 | u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE; | 184 | u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE; |
185 | diff = diff - btrfs_item_size(leaf->items + path->slots[0]); | 185 | diff = diff - btrfs_item_size(leaf->items + path->slots[0]); |
186 | WARN_ON(diff != BTRFS_CRC32_SIZE); | 186 | if (diff != BTRFS_CRC32_SIZE) |
187 | goto insert; | ||
187 | ret = btrfs_extend_item(trans, root, path, diff); | 188 | ret = btrfs_extend_item(trans, root, path, diff); |
188 | BUG_ON(ret); | 189 | BUG_ON(ret); |
189 | goto csum; | 190 | goto csum; |
@@ -241,7 +242,7 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, | |||
241 | ret = PTR_ERR(item); | 242 | ret = PTR_ERR(item); |
242 | /* a csum that isn't present is a preallocated region. */ | 243 | /* a csum that isn't present is a preallocated region. */ |
243 | if (ret == -ENOENT || ret == -EFBIG) | 244 | if (ret == -ENOENT || ret == -EFBIG) |
244 | ret = 1; | 245 | ret = -ENOENT; |
245 | goto fail; | 246 | goto fail; |
246 | } | 247 | } |
247 | 248 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index c1a0adde9b1c..5b87c4e9d491 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "transaction.h" | 17 | #include "transaction.h" |
18 | #include "btrfs_inode.h" | 18 | #include "btrfs_inode.h" |
19 | #include "ioctl.h" | 19 | #include "ioctl.h" |
20 | #include "print-tree.h" | ||
20 | 21 | ||
21 | struct btrfs_iget_args { | 22 | struct btrfs_iget_args { |
22 | u64 ino; | 23 | u64 ino; |
@@ -421,14 +422,17 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
421 | struct btrfs_file_extent_item); | 422 | struct btrfs_file_extent_item); |
422 | if (btrfs_file_extent_type(fi) != | 423 | if (btrfs_file_extent_type(fi) != |
423 | BTRFS_FILE_EXTENT_INLINE) { | 424 | BTRFS_FILE_EXTENT_INLINE) { |
425 | u64 num_dec; | ||
424 | extent_start = | 426 | extent_start = |
425 | btrfs_file_extent_disk_blocknr(fi); | 427 | btrfs_file_extent_disk_blocknr(fi); |
426 | extent_num_blocks = | 428 | extent_num_blocks = |
427 | btrfs_file_extent_disk_num_blocks(fi); | 429 | btrfs_file_extent_disk_num_blocks(fi); |
428 | /* FIXME blocksize != 4096 */ | 430 | /* FIXME blocksize != 4096 */ |
429 | inode->i_blocks -= | 431 | num_dec = btrfs_file_extent_num_blocks(fi) << 3; |
430 | btrfs_file_extent_num_blocks(fi) << 3; | 432 | if (extent_start != 0) { |
431 | found_extent = 1; | 433 | found_extent = 1; |
434 | inode->i_blocks -= num_dec; | ||
435 | } | ||
432 | } | 436 | } |
433 | } | 437 | } |
434 | ret = btrfs_del_item(trans, root, path); | 438 | ret = btrfs_del_item(trans, root, path); |
@@ -448,6 +452,43 @@ error: | |||
448 | return ret; | 452 | return ret; |
449 | } | 453 | } |
450 | 454 | ||
455 | static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | ||
456 | { | ||
457 | struct inode *inode = dentry->d_inode; | ||
458 | int err; | ||
459 | |||
460 | err = inode_change_ok(inode, attr); | ||
461 | if (err) | ||
462 | return err; | ||
463 | |||
464 | if (S_ISREG(inode->i_mode) && | ||
465 | attr->ia_valid & ATTR_SIZE && attr->ia_size > inode->i_size) { | ||
466 | struct btrfs_trans_handle *trans; | ||
467 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
468 | u64 mask = root->blocksize - 1; | ||
469 | u64 pos = (inode->i_size + mask) & ~mask; | ||
470 | u64 hole_size; | ||
471 | |||
472 | if (attr->ia_size < pos) | ||
473 | goto out; | ||
474 | hole_size = (attr->ia_size - pos + mask) & ~mask; | ||
475 | hole_size >>= inode->i_blkbits; | ||
476 | |||
477 | mutex_lock(&root->fs_info->fs_mutex); | ||
478 | trans = btrfs_start_transaction(root, 1); | ||
479 | btrfs_set_trans_block_group(trans, inode); | ||
480 | err = btrfs_insert_file_extent(trans, root, inode->i_ino, | ||
481 | pos, 0, 0, hole_size); | ||
482 | BUG_ON(err); | ||
483 | btrfs_end_transaction(trans, root); | ||
484 | mutex_unlock(&root->fs_info->fs_mutex); | ||
485 | } | ||
486 | |||
487 | err = inode_setattr(inode, attr); | ||
488 | |||
489 | out: | ||
490 | return err; | ||
491 | } | ||
451 | static void btrfs_delete_inode(struct inode *inode) | 492 | static void btrfs_delete_inode(struct inode *inode) |
452 | { | 493 | { |
453 | struct btrfs_trans_handle *trans; | 494 | struct btrfs_trans_handle *trans; |
@@ -1169,8 +1210,10 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
1169 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 1210 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
1170 | extent_start = extent_start >> inode->i_blkbits; | 1211 | extent_start = extent_start >> inode->i_blkbits; |
1171 | extent_end = extent_start + btrfs_file_extent_num_blocks(item); | 1212 | extent_end = extent_start + btrfs_file_extent_num_blocks(item); |
1213 | err = 0; | ||
1214 | if (blocknr == 0) | ||
1215 | goto out; | ||
1172 | if (iblock >= extent_start && iblock < extent_end) { | 1216 | if (iblock >= extent_start && iblock < extent_end) { |
1173 | err = 0; | ||
1174 | btrfs_map_bh_to_logical(root, result, blocknr + | 1217 | btrfs_map_bh_to_logical(root, result, blocknr + |
1175 | iblock - extent_start); | 1218 | iblock - extent_start); |
1176 | goto out; | 1219 | goto out; |
@@ -1591,7 +1634,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
1591 | ptr, bh->b_data, offset + write_bytes); | 1634 | ptr, bh->b_data, offset + write_bytes); |
1592 | mark_buffer_dirty(path->nodes[0]); | 1635 | mark_buffer_dirty(path->nodes[0]); |
1593 | btrfs_free_path(path); | 1636 | btrfs_free_path(path); |
1594 | } else { | 1637 | } else if (buffer_mapped(bh)) { |
1595 | btrfs_csum_file_block(trans, root, inode->i_ino, | 1638 | btrfs_csum_file_block(trans, root, inode->i_ino, |
1596 | pages[i]->index << PAGE_CACHE_SHIFT, | 1639 | pages[i]->index << PAGE_CACHE_SHIFT, |
1597 | kmap(pages[i]), PAGE_CACHE_SIZE); | 1640 | kmap(pages[i]), PAGE_CACHE_SIZE); |
@@ -1693,15 +1736,24 @@ static int drop_extents(struct btrfs_trans_handle *trans, | |||
1693 | goto out; | 1736 | goto out; |
1694 | } | 1737 | } |
1695 | 1738 | ||
1696 | search_start = extent_end; | 1739 | if (found_inline) { |
1740 | u64 mask = root->blocksize - 1; | ||
1741 | search_start = (extent_end + mask) & ~mask; | ||
1742 | } else | ||
1743 | search_start = extent_end; | ||
1697 | 1744 | ||
1698 | if (end < extent_end && end >= key.offset) { | 1745 | if (end < extent_end && end >= key.offset) { |
1699 | if (found_extent) { | 1746 | if (found_extent) { |
1747 | u64 disk_blocknr = | ||
1748 | btrfs_file_extent_disk_blocknr(extent); | ||
1749 | u64 disk_num_blocks = | ||
1750 | btrfs_file_extent_disk_num_blocks(extent); | ||
1700 | memcpy(&old, extent, sizeof(old)); | 1751 | memcpy(&old, extent, sizeof(old)); |
1701 | ret = btrfs_inc_extent_ref(trans, root, | 1752 | if (disk_blocknr != 0) { |
1702 | btrfs_file_extent_disk_blocknr(&old), | 1753 | ret = btrfs_inc_extent_ref(trans, root, |
1703 | btrfs_file_extent_disk_num_blocks(&old)); | 1754 | disk_blocknr, disk_num_blocks); |
1704 | BUG_ON(ret); | 1755 | BUG_ON(ret); |
1756 | } | ||
1705 | } | 1757 | } |
1706 | WARN_ON(found_inline); | 1758 | WARN_ON(found_inline); |
1707 | bookend = 1; | 1759 | bookend = 1; |
@@ -1719,7 +1771,10 @@ static int drop_extents(struct btrfs_trans_handle *trans, | |||
1719 | old_num = btrfs_file_extent_num_blocks(extent); | 1771 | old_num = btrfs_file_extent_num_blocks(extent); |
1720 | *hint_block = | 1772 | *hint_block = |
1721 | btrfs_file_extent_disk_blocknr(extent); | 1773 | btrfs_file_extent_disk_blocknr(extent); |
1722 | inode->i_blocks -= (old_num - new_num) << 3; | 1774 | if (btrfs_file_extent_disk_blocknr(extent)) { |
1775 | inode->i_blocks -= | ||
1776 | (old_num - new_num) << 3; | ||
1777 | } | ||
1723 | btrfs_set_file_extent_num_blocks(extent, | 1778 | btrfs_set_file_extent_num_blocks(extent, |
1724 | new_num); | 1779 | new_num); |
1725 | mark_buffer_dirty(path->nodes[0]); | 1780 | mark_buffer_dirty(path->nodes[0]); |
@@ -1745,7 +1800,7 @@ static int drop_extents(struct btrfs_trans_handle *trans, | |||
1745 | BUG_ON(ret); | 1800 | BUG_ON(ret); |
1746 | btrfs_release_path(root, path); | 1801 | btrfs_release_path(root, path); |
1747 | extent = NULL; | 1802 | extent = NULL; |
1748 | if (found_extent) { | 1803 | if (found_extent && disk_blocknr != 0) { |
1749 | inode->i_blocks -= extent_num_blocks << 3; | 1804 | inode->i_blocks -= extent_num_blocks << 3; |
1750 | ret = btrfs_free_extent(trans, root, | 1805 | ret = btrfs_free_extent(trans, root, |
1751 | disk_blocknr, | 1806 | disk_blocknr, |
@@ -1785,18 +1840,19 @@ static int drop_extents(struct btrfs_trans_handle *trans, | |||
1785 | btrfs_file_extent_offset(&old) + | 1840 | btrfs_file_extent_offset(&old) + |
1786 | ((end - key.offset) >> inode->i_blkbits)); | 1841 | ((end - key.offset) >> inode->i_blkbits)); |
1787 | WARN_ON(btrfs_file_extent_num_blocks(&old) < | 1842 | WARN_ON(btrfs_file_extent_num_blocks(&old) < |
1788 | (end - key.offset) >> inode->i_blkbits); | 1843 | (extent_end - end) >> inode->i_blkbits); |
1789 | btrfs_set_file_extent_num_blocks(extent, | 1844 | btrfs_set_file_extent_num_blocks(extent, |
1790 | btrfs_file_extent_num_blocks(&old) - | 1845 | (extent_end - end) >> inode->i_blkbits); |
1791 | ((end - key.offset) >> inode->i_blkbits)); | ||
1792 | 1846 | ||
1793 | btrfs_set_file_extent_type(extent, | 1847 | btrfs_set_file_extent_type(extent, |
1794 | BTRFS_FILE_EXTENT_REG); | 1848 | BTRFS_FILE_EXTENT_REG); |
1795 | btrfs_set_file_extent_generation(extent, | 1849 | btrfs_set_file_extent_generation(extent, |
1796 | btrfs_file_extent_generation(&old)); | 1850 | btrfs_file_extent_generation(&old)); |
1797 | btrfs_mark_buffer_dirty(path->nodes[0]); | 1851 | btrfs_mark_buffer_dirty(path->nodes[0]); |
1798 | inode->i_blocks += | 1852 | if (btrfs_file_extent_disk_blocknr(&old) != 0) { |
1799 | btrfs_file_extent_num_blocks(extent) << 3; | 1853 | inode->i_blocks += |
1854 | btrfs_file_extent_num_blocks(extent) << 3; | ||
1855 | } | ||
1800 | ret = 0; | 1856 | ret = 0; |
1801 | goto out; | 1857 | goto out; |
1802 | } | 1858 | } |
@@ -1960,6 +2016,21 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1960 | ~((u64)root->blocksize - 1), &hint_block); | 2016 | ~((u64)root->blocksize - 1), &hint_block); |
1961 | BUG_ON(ret); | 2017 | BUG_ON(ret); |
1962 | } | 2018 | } |
2019 | if (inode->i_size < start_pos) { | ||
2020 | u64 last_pos_in_file; | ||
2021 | u64 hole_size; | ||
2022 | u64 mask = root->blocksize - 1; | ||
2023 | last_pos_in_file = (inode->i_size + mask) & ~mask; | ||
2024 | hole_size = (start_pos - last_pos_in_file + mask) & ~mask; | ||
2025 | hole_size >>= inode->i_blkbits; | ||
2026 | if (last_pos_in_file < start_pos) { | ||
2027 | ret = btrfs_insert_file_extent(trans, root, | ||
2028 | inode->i_ino, | ||
2029 | last_pos_in_file, | ||
2030 | 0, 0, hole_size); | ||
2031 | } | ||
2032 | BUG_ON(ret); | ||
2033 | } | ||
1963 | if (inode->i_size >= PAGE_CACHE_SIZE || pos + count < inode->i_size || | 2034 | if (inode->i_size >= PAGE_CACHE_SIZE || pos + count < inode->i_size || |
1964 | pos + count - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { | 2035 | pos + count - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { |
1965 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, | 2036 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, |
@@ -1967,7 +2038,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1967 | &ins, 1); | 2038 | &ins, 1); |
1968 | BUG_ON(ret); | 2039 | BUG_ON(ret); |
1969 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, | 2040 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, |
1970 | start_pos, ins.objectid, ins.offset); | 2041 | start_pos, ins.objectid, ins.offset, |
2042 | ins.offset); | ||
1971 | BUG_ON(ret); | 2043 | BUG_ON(ret); |
1972 | } else { | 2044 | } else { |
1973 | ins.offset = 0; | 2045 | ins.offset = 0; |
@@ -2044,10 +2116,13 @@ static int btrfs_read_actor(read_descriptor_t *desc, struct page *page, | |||
2044 | page->index << PAGE_CACHE_SHIFT, | 2116 | page->index << PAGE_CACHE_SHIFT, |
2045 | kmap(page), PAGE_CACHE_SIZE); | 2117 | kmap(page), PAGE_CACHE_SIZE); |
2046 | if (ret) { | 2118 | if (ret) { |
2047 | printk("failed to verify ino %lu page %lu\n", | 2119 | if (ret != -ENOENT) { |
2048 | page->mapping->host->i_ino, | 2120 | printk("failed to verify ino %lu page %lu\n", |
2049 | page->index); | 2121 | page->mapping->host->i_ino, |
2050 | memset(page_address(page), 0, PAGE_CACHE_SIZE); | 2122 | page->index); |
2123 | memset(page_address(page), 0, PAGE_CACHE_SIZE); | ||
2124 | flush_dcache_page(page); | ||
2125 | } | ||
2051 | } | 2126 | } |
2052 | SetPageChecked(page); | 2127 | SetPageChecked(page); |
2053 | kunmap(page); | 2128 | kunmap(page); |
@@ -2759,6 +2834,7 @@ static struct inode_operations btrfs_dir_inode_operations = { | |||
2759 | .rmdir = btrfs_rmdir, | 2834 | .rmdir = btrfs_rmdir, |
2760 | .rename = btrfs_rename, | 2835 | .rename = btrfs_rename, |
2761 | .symlink = btrfs_symlink, | 2836 | .symlink = btrfs_symlink, |
2837 | .setattr = btrfs_setattr, | ||
2762 | }; | 2838 | }; |
2763 | 2839 | ||
2764 | static struct inode_operations btrfs_dir_ro_inode_operations = { | 2840 | static struct inode_operations btrfs_dir_ro_inode_operations = { |
@@ -2788,6 +2864,7 @@ static struct address_space_operations btrfs_symlink_aops = { | |||
2788 | static struct inode_operations btrfs_file_inode_operations = { | 2864 | static struct inode_operations btrfs_file_inode_operations = { |
2789 | .truncate = btrfs_truncate, | 2865 | .truncate = btrfs_truncate, |
2790 | .getattr = btrfs_getattr, | 2866 | .getattr = btrfs_getattr, |
2867 | .setattr = btrfs_setattr, | ||
2791 | }; | 2868 | }; |
2792 | 2869 | ||
2793 | static struct file_operations btrfs_file_operations = { | 2870 | static struct file_operations btrfs_file_operations = { |