aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/file-item.c30
-rw-r--r--fs/btrfs/super.c213
3 files changed, 214 insertions, 32 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index e8f741167c6b..756ea9d0123b 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1198,5 +1198,8 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
1198 struct btrfs_path *path, 1198 struct btrfs_path *path,
1199 u64 objectid, u64 offset, 1199 u64 objectid, u64 offset,
1200 int cow); 1200 int cow);
1201int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
1202 struct btrfs_root *root, struct btrfs_path *path,
1203 u64 isize);
1201/* super.c */ 1204/* super.c */
1202#endif 1205#endif
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 7990b5742114..0782e924ddeb 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -2,6 +2,7 @@
2#include "ctree.h" 2#include "ctree.h"
3#include "disk-io.h" 3#include "disk-io.h"
4#include "transaction.h" 4#include "transaction.h"
5#include "print-tree.h"
5 6
6#define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \ 7#define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \
7 sizeof(struct btrfs_item) * 2) / \ 8 sizeof(struct btrfs_item) * 2) / \
@@ -27,6 +28,10 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
27 28
28 ret = btrfs_insert_empty_item(trans, root, path, &file_key, 29 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
29 sizeof(*item)); 30 sizeof(*item));
31 if (ret) {
32printk("failed to insert %Lu %Lu ret %d\n", objectid, pos, ret);
33btrfs_print_leaf(root, btrfs_buffer_leaf(path->nodes[0]));
34 }
30 BUG_ON(ret); 35 BUG_ON(ret);
31 item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 36 item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
32 struct btrfs_file_extent_item); 37 struct btrfs_file_extent_item);
@@ -218,6 +223,31 @@ fail:
218 return ret; 223 return ret;
219} 224}
220 225
226int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
227 struct btrfs_root *root, struct btrfs_path *path,
228 u64 isize)
229{
230 struct btrfs_key key;
231 struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[0]);
232 int slot = path->slots[0];
233 int ret;
234 u32 new_item_size;
235 u64 new_item_span;
236 u64 blocks;
237
238 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
239 if (isize <= key.offset)
240 return 0;
241 new_item_span = isize - key.offset;
242 blocks = (new_item_span + root->blocksize - 1) / root->blocksize;
243 new_item_size = blocks * BTRFS_CRC32_SIZE;
244 if (new_item_size >= btrfs_item_size(leaf->items + slot))
245 return 0;
246 ret = btrfs_truncate_item(trans, root, path, new_item_size);
247 BUG_ON(ret);
248 return ret;
249}
250
221int btrfs_csum_verify_file_block(struct btrfs_root *root, 251int btrfs_csum_verify_file_block(struct btrfs_root *root,
222 u64 objectid, u64 offset, 252 u64 objectid, u64 offset,
223 char *data, size_t len) 253 char *data, size_t len)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 5b87c4e9d491..0eb64d6eaf9d 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -36,6 +36,13 @@ static struct address_space_operations btrfs_aops;
36static struct address_space_operations btrfs_symlink_aops; 36static struct address_space_operations btrfs_symlink_aops;
37static struct file_operations btrfs_file_operations; 37static struct file_operations btrfs_file_operations;
38 38
39static int drop_extents(struct btrfs_trans_handle *trans,
40 struct btrfs_root *root,
41 struct inode *inode,
42 u64 start, u64 end, u64 *hint_block);
43static int btrfs_get_block(struct inode *inode, sector_t iblock,
44 struct buffer_head *result, int create);
45
39static void btrfs_read_locked_inode(struct inode *inode) 46static void btrfs_read_locked_inode(struct inode *inode)
40{ 47{
41 struct btrfs_path *path; 48 struct btrfs_path *path;
@@ -381,10 +388,12 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
381 struct btrfs_disk_key *found_key; 388 struct btrfs_disk_key *found_key;
382 u32 found_type; 389 u32 found_type;
383 struct btrfs_leaf *leaf; 390 struct btrfs_leaf *leaf;
384 struct btrfs_file_extent_item *fi = NULL; 391 struct btrfs_file_extent_item *fi;
385 u64 extent_start = 0; 392 u64 extent_start = 0;
386 u64 extent_num_blocks = 0; 393 u64 extent_num_blocks = 0;
394 u64 item_end = 0;
387 int found_extent; 395 int found_extent;
396 int del_item;
388 397
389 path = btrfs_alloc_path(); 398 path = btrfs_alloc_path();
390 BUG_ON(!path); 399 BUG_ON(!path);
@@ -394,6 +403,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
394 key.flags = (u32)-1; 403 key.flags = (u32)-1;
395 while(1) { 404 while(1) {
396 btrfs_init_path(path); 405 btrfs_init_path(path);
406 fi = NULL;
397 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 407 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
398 if (ret < 0) { 408 if (ret < 0) {
399 goto error; 409 goto error;
@@ -413,16 +423,52 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
413 found_type != BTRFS_DIR_INDEX_KEY && 423 found_type != BTRFS_DIR_INDEX_KEY &&
414 found_type != BTRFS_EXTENT_DATA_KEY) 424 found_type != BTRFS_EXTENT_DATA_KEY)
415 break; 425 break;
416 if (btrfs_disk_key_offset(found_key) < inode->i_size) 426 item_end = btrfs_disk_key_offset(found_key);
417 break; 427 if (found_type == BTRFS_EXTENT_DATA_KEY) {
418 found_extent = 0;
419 if (btrfs_disk_key_type(found_key) == BTRFS_EXTENT_DATA_KEY) {
420 fi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 428 fi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
421 path->slots[0], 429 path->slots[0],
422 struct btrfs_file_extent_item); 430 struct btrfs_file_extent_item);
423 if (btrfs_file_extent_type(fi) != 431 if (btrfs_file_extent_type(fi) !=
424 BTRFS_FILE_EXTENT_INLINE) { 432 BTRFS_FILE_EXTENT_INLINE) {
425 u64 num_dec; 433 item_end += btrfs_file_extent_num_blocks(fi) <<
434 inode->i_blkbits;
435 }
436 }
437 if (found_type == BTRFS_CSUM_ITEM_KEY) {
438 ret = btrfs_csum_truncate(trans, root, path,
439 inode->i_size);
440 BUG_ON(ret);
441 }
442 if (item_end < inode->i_size) {
443 if (found_type) {
444 btrfs_set_key_type(&key, found_type - 1);
445 continue;
446 }
447 break;
448 }
449 if (btrfs_disk_key_offset(found_key) >= inode->i_size)
450 del_item = 1;
451 else
452 del_item = 0;
453 found_extent = 0;
454
455 if (found_type == BTRFS_EXTENT_DATA_KEY &&
456 btrfs_file_extent_type(fi) !=
457 BTRFS_FILE_EXTENT_INLINE) {
458 u64 num_dec;
459 if (!del_item) {
460 u64 orig_num_blocks =
461 btrfs_file_extent_num_blocks(fi);
462 extent_num_blocks = inode->i_size -
463 btrfs_disk_key_offset(found_key) +
464 root->blocksize - 1;
465 extent_num_blocks >>= inode->i_blkbits;
466 btrfs_set_file_extent_num_blocks(fi,
467 extent_num_blocks);
468 inode->i_blocks -= (orig_num_blocks -
469 extent_num_blocks) << 3;
470 mark_buffer_dirty(path->nodes[0]);
471 } else {
426 extent_start = 472 extent_start =
427 btrfs_file_extent_disk_blocknr(fi); 473 btrfs_file_extent_disk_blocknr(fi);
428 extent_num_blocks = 474 extent_num_blocks =
@@ -435,8 +481,12 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
435 } 481 }
436 } 482 }
437 } 483 }
438 ret = btrfs_del_item(trans, root, path); 484 if (del_item) {
439 BUG_ON(ret); 485 ret = btrfs_del_item(trans, root, path);
486 BUG_ON(ret);
487 } else {
488 break;
489 }
440 btrfs_release_path(root, path); 490 btrfs_release_path(root, path);
441 if (found_extent) { 491 if (found_extent) {
442 ret = btrfs_free_extent(trans, root, extent_start, 492 ret = btrfs_free_extent(trans, root, extent_start,
@@ -452,6 +502,68 @@ error:
452 return ret; 502 return ret;
453} 503}
454 504
505static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
506{
507 struct inode *inode = mapping->host;
508 unsigned blocksize = 1 << inode->i_blkbits;
509 pgoff_t index = from >> PAGE_CACHE_SHIFT;
510 unsigned offset = from & (PAGE_CACHE_SIZE-1);
511 struct page *page;
512 char *kaddr;
513 int ret = 0;
514 struct btrfs_root *root = BTRFS_I(inode)->root;
515 u64 alloc_hint;
516 struct btrfs_key ins;
517 struct btrfs_trans_handle *trans;
518
519 if ((offset & (blocksize - 1)) == 0)
520 goto out;
521
522 ret = -ENOMEM;
523 page = grab_cache_page(mapping, index);
524 if (!page)
525 goto out;
526
527 if (!PageUptodate(page)) {
528 ret = mpage_readpage(page, btrfs_get_block);
529 lock_page(page);
530 if (!PageUptodate(page)) {
531 ret = -EIO;
532 goto out;
533 }
534 }
535 mutex_lock(&root->fs_info->fs_mutex);
536 trans = btrfs_start_transaction(root, 1);
537 btrfs_set_trans_block_group(trans, inode);
538
539 ret = drop_extents(trans, root, inode, page->index << PAGE_CACHE_SHIFT,
540 (page->index + 1) << PAGE_CACHE_SHIFT, &alloc_hint);
541 BUG_ON(ret);
542 ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1,
543 alloc_hint, (u64)-1, &ins, 1);
544 BUG_ON(ret);
545 ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
546 page->index << PAGE_CACHE_SHIFT,
547 ins.objectid, 1, 1);
548 BUG_ON(ret);
549 SetPageChecked(page);
550 kaddr = kmap(page);
551 memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
552 flush_dcache_page(page);
553 btrfs_csum_file_block(trans, root, inode->i_ino,
554 page->index << PAGE_CACHE_SHIFT,
555 kaddr, PAGE_CACHE_SIZE);
556 kunmap(page);
557 btrfs_end_transaction(trans, root);
558 mutex_unlock(&root->fs_info->fs_mutex);
559
560 set_page_dirty(page);
561 unlock_page(page);
562 page_cache_release(page);
563out:
564 return ret;
565}
566
455static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) 567static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
456{ 568{
457 struct inode *inode = dentry->d_inode; 569 struct inode *inode = dentry->d_inode;
@@ -469,8 +581,11 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
469 u64 pos = (inode->i_size + mask) & ~mask; 581 u64 pos = (inode->i_size + mask) & ~mask;
470 u64 hole_size; 582 u64 hole_size;
471 583
472 if (attr->ia_size < pos) 584 if (attr->ia_size <= pos)
473 goto out; 585 goto out;
586
587 btrfs_truncate_page(inode->i_mapping, inode->i_size);
588
474 hole_size = (attr->ia_size - pos + mask) & ~mask; 589 hole_size = (attr->ia_size - pos + mask) & ~mask;
475 hole_size >>= inode->i_blkbits; 590 hole_size >>= inode->i_blkbits;
476 591
@@ -483,10 +598,9 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
483 btrfs_end_transaction(trans, root); 598 btrfs_end_transaction(trans, root);
484 mutex_unlock(&root->fs_info->fs_mutex); 599 mutex_unlock(&root->fs_info->fs_mutex);
485 } 600 }
486 601out:
487 err = inode_setattr(inode, attr); 602 err = inode_setattr(inode, attr);
488 603
489out:
490 return err; 604 return err;
491} 605}
492static void btrfs_delete_inode(struct inode *inode) 606static void btrfs_delete_inode(struct inode *inode)
@@ -1161,17 +1275,30 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1161 u64 extent_end = 0; 1275 u64 extent_end = 0;
1162 u64 objectid = inode->i_ino; 1276 u64 objectid = inode->i_ino;
1163 u32 found_type; 1277 u32 found_type;
1278 u64 alloc_hint = 0;
1164 struct btrfs_path *path; 1279 struct btrfs_path *path;
1165 struct btrfs_root *root = BTRFS_I(inode)->root; 1280 struct btrfs_root *root = BTRFS_I(inode)->root;
1166 struct btrfs_file_extent_item *item; 1281 struct btrfs_file_extent_item *item;
1167 struct btrfs_leaf *leaf; 1282 struct btrfs_leaf *leaf;
1168 struct btrfs_disk_key *found_key; 1283 struct btrfs_disk_key *found_key;
1284 struct btrfs_trans_handle *trans = NULL;
1169 1285
1170 path = btrfs_alloc_path(); 1286 path = btrfs_alloc_path();
1171 BUG_ON(!path); 1287 BUG_ON(!path);
1172 btrfs_init_path(path); 1288 btrfs_init_path(path);
1173 if (create) { 1289 if (create) {
1174 WARN_ON(1); 1290 WARN_ON(1);
1291 /* this almost but not quite works */
1292 trans = btrfs_start_transaction(root, 1);
1293 if (!trans) {
1294 err = -ENOMEM;
1295 goto out;
1296 }
1297 ret = drop_extents(trans, root, inode,
1298 iblock << inode->i_blkbits,
1299 (iblock + 1) << inode->i_blkbits,
1300 &alloc_hint);
1301 BUG_ON(ret);
1175 } 1302 }
1176 1303
1177 ret = btrfs_lookup_file_extent(NULL, root, path, 1304 ret = btrfs_lookup_file_extent(NULL, root, path,
@@ -1185,7 +1312,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1185 if (ret != 0) { 1312 if (ret != 0) {
1186 if (path->slots[0] == 0) { 1313 if (path->slots[0] == 0) {
1187 btrfs_release_path(root, path); 1314 btrfs_release_path(root, path);
1188 goto out; 1315 goto not_found;
1189 } 1316 }
1190 path->slots[0]--; 1317 path->slots[0]--;
1191 } 1318 }
@@ -1203,7 +1330,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1203 found_type != BTRFS_EXTENT_DATA_KEY) { 1330 found_type != BTRFS_EXTENT_DATA_KEY) {
1204 extent_end = 0; 1331 extent_end = 0;
1205 extent_start = 0; 1332 extent_start = 0;
1206 goto out; 1333 goto not_found;
1207 } 1334 }
1208 found_type = btrfs_file_extent_type(item); 1335 found_type = btrfs_file_extent_type(item);
1209 extent_start = btrfs_disk_key_offset(&leaf->items[path->slots[0]].key); 1336 extent_start = btrfs_disk_key_offset(&leaf->items[path->slots[0]].key);
@@ -1211,7 +1338,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1211 extent_start = extent_start >> inode->i_blkbits; 1338 extent_start = extent_start >> inode->i_blkbits;
1212 extent_end = extent_start + btrfs_file_extent_num_blocks(item); 1339 extent_end = extent_start + btrfs_file_extent_num_blocks(item);
1213 err = 0; 1340 err = 0;
1214 if (blocknr == 0) 1341 if (btrfs_file_extent_disk_blocknr(item) == 0)
1215 goto out; 1342 goto out;
1216 if (iblock >= extent_start && iblock < extent_end) { 1343 if (iblock >= extent_start && iblock < extent_end) {
1217 btrfs_map_bh_to_logical(root, result, blocknr + 1344 btrfs_map_bh_to_logical(root, result, blocknr +
@@ -1227,7 +1354,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1227 extent_end = (extent_start + size) >> inode->i_blkbits; 1354 extent_end = (extent_start + size) >> inode->i_blkbits;
1228 extent_start >>= inode->i_blkbits; 1355 extent_start >>= inode->i_blkbits;
1229 if (iblock < extent_start || iblock > extent_end) { 1356 if (iblock < extent_start || iblock > extent_end) {
1230 goto out; 1357 goto not_found;
1231 } 1358 }
1232 ptr = btrfs_file_extent_inline_start(item); 1359 ptr = btrfs_file_extent_inline_start(item);
1233 map = kmap(result->b_page); 1360 map = kmap(result->b_page);
@@ -1239,7 +1366,24 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1239 SetPageChecked(result->b_page); 1366 SetPageChecked(result->b_page);
1240 btrfs_map_bh_to_logical(root, result, 0); 1367 btrfs_map_bh_to_logical(root, result, 0);
1241 } 1368 }
1369not_found:
1370 if (create) {
1371 struct btrfs_key ins;
1372 ret = btrfs_alloc_extent(trans, root, inode->i_ino,
1373 1, alloc_hint, (u64)-1,
1374 &ins, 1);
1375 BUG_ON(ret);
1376 ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
1377 iblock << inode->i_blkbits,
1378 ins.objectid, ins.offset,
1379 ins.offset);
1380 BUG_ON(ret);
1381 SetPageChecked(result->b_page);
1382 btrfs_map_bh_to_logical(root, result, ins.objectid);
1383 }
1242out: 1384out:
1385 if (trans)
1386 err = btrfs_end_transaction(trans, root);
1243 btrfs_free_path(path); 1387 btrfs_free_path(path);
1244 return err; 1388 return err;
1245} 1389}
@@ -1258,7 +1402,7 @@ static int btrfs_get_block(struct inode *inode, sector_t iblock,
1258static int btrfs_prepare_write(struct file *file, struct page *page, 1402static int btrfs_prepare_write(struct file *file, struct page *page,
1259 unsigned from, unsigned to) 1403 unsigned from, unsigned to)
1260{ 1404{
1261 return nobh_prepare_write(page, from, to, btrfs_get_block); 1405 return block_prepare_write(page, from, to, btrfs_get_block);
1262} 1406}
1263 1407
1264static void btrfs_write_super(struct super_block *sb) 1408static void btrfs_write_super(struct super_block *sb)
@@ -1500,12 +1644,13 @@ static void btrfs_truncate(struct inode *inode)
1500 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) 1644 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
1501 return; 1645 return;
1502 1646
1503 nobh_truncate_page(inode->i_mapping, inode->i_size); 1647 btrfs_truncate_page(inode->i_mapping, inode->i_size);
1504 1648
1505 /* FIXME, add redo link to tree so we don't leak on crash */
1506 mutex_lock(&root->fs_info->fs_mutex); 1649 mutex_lock(&root->fs_info->fs_mutex);
1507 trans = btrfs_start_transaction(root, 1); 1650 trans = btrfs_start_transaction(root, 1);
1508 btrfs_set_trans_block_group(trans, inode); 1651 btrfs_set_trans_block_group(trans, inode);
1652
1653 /* FIXME, add redo link to tree so we don't leak on crash */
1509 ret = btrfs_truncate_in_trans(trans, root, inode); 1654 ret = btrfs_truncate_in_trans(trans, root, inode);
1510 BUG_ON(ret); 1655 BUG_ON(ret);
1511 btrfs_update_inode(trans, root, inode); 1656 btrfs_update_inode(trans, root, inode);
@@ -1515,10 +1660,6 @@ static void btrfs_truncate(struct inode *inode)
1515 btrfs_btree_balance_dirty(root); 1660 btrfs_btree_balance_dirty(root);
1516} 1661}
1517 1662
1518/*
1519 * Make sure any changes to nobh_commit_write() are reflected in
1520 * nobh_truncate_page(), since it doesn't call commit_write().
1521 */
1522static int btrfs_commit_write(struct file *file, struct page *page, 1663static int btrfs_commit_write(struct file *file, struct page *page,
1523 unsigned from, unsigned to) 1664 unsigned from, unsigned to)
1524{ 1665{
@@ -1528,6 +1669,7 @@ static int btrfs_commit_write(struct file *file, struct page *page,
1528 1669
1529 SetPageUptodate(page); 1670 SetPageUptodate(page);
1530 bh = page_buffers(page); 1671 bh = page_buffers(page);
1672 set_buffer_uptodate(bh);
1531 if (buffer_mapped(bh) && bh->b_blocknr != 0) { 1673 if (buffer_mapped(bh) && bh->b_blocknr != 0) {
1532 set_page_dirty(page); 1674 set_page_dirty(page);
1533 } 1675 }
@@ -1972,8 +2114,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1972 first_index = pos >> PAGE_CACHE_SHIFT; 2114 first_index = pos >> PAGE_CACHE_SHIFT;
1973 last_index = (pos + count) >> PAGE_CACHE_SHIFT; 2115 last_index = (pos + count) >> PAGE_CACHE_SHIFT;
1974 2116
1975 if ((first_index << PAGE_CACHE_SHIFT) < inode->i_size && 2117 if ((pos & (PAGE_CACHE_SIZE - 1))) {
1976 (pos & (PAGE_CACHE_SIZE - 1))) {
1977 pinned[0] = grab_cache_page(inode->i_mapping, first_index); 2118 pinned[0] = grab_cache_page(inode->i_mapping, first_index);
1978 if (!PageUptodate(pinned[0])) { 2119 if (!PageUptodate(pinned[0])) {
1979 ret = mpage_readpage(pinned[0], btrfs_get_block); 2120 ret = mpage_readpage(pinned[0], btrfs_get_block);
@@ -1983,10 +2124,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1983 unlock_page(pinned[0]); 2124 unlock_page(pinned[0]);
1984 } 2125 }
1985 } 2126 }
1986 if (first_index != last_index && 2127 if ((pos + count) & (PAGE_CACHE_SIZE - 1)) {
1987 (last_index << PAGE_CACHE_SHIFT) < inode->i_size &&
1988 pos + count < inode->i_size &&
1989 (count & (PAGE_CACHE_SIZE - 1))) {
1990 pinned[1] = grab_cache_page(inode->i_mapping, last_index); 2128 pinned[1] = grab_cache_page(inode->i_mapping, last_index);
1991 if (!PageUptodate(pinned[1])) { 2129 if (!PageUptodate(pinned[1])) {
1992 ret = mpage_readpage(pinned[1], btrfs_get_block); 2130 ret = mpage_readpage(pinned[1], btrfs_get_block);
@@ -2110,23 +2248,34 @@ static int btrfs_read_actor(read_descriptor_t *desc, struct page *page,
2110 if (!PageChecked(page)) { 2248 if (!PageChecked(page)) {
2111 /* FIXME, do it per block */ 2249 /* FIXME, do it per block */
2112 struct btrfs_root *root = BTRFS_I(inode)->root; 2250 struct btrfs_root *root = BTRFS_I(inode)->root;
2251 int ret;
2252 struct buffer_head *bh;
2253
2254 if (page_has_buffers(page)) {
2255 bh = page_buffers(page);
2256 if (!buffer_mapped(bh)) {
2257 SetPageChecked(page);
2258 goto checked;
2259 }
2260 }
2113 2261
2114 int ret = btrfs_csum_verify_file_block(root, 2262 ret = btrfs_csum_verify_file_block(root,
2115 page->mapping->host->i_ino, 2263 page->mapping->host->i_ino,
2116 page->index << PAGE_CACHE_SHIFT, 2264 page->index << PAGE_CACHE_SHIFT,
2117 kmap(page), PAGE_CACHE_SIZE); 2265 kmap(page), PAGE_CACHE_SIZE);
2118 if (ret) { 2266 if (ret) {
2119 if (ret != -ENOENT) { 2267 if (ret != -ENOENT) {
2120 printk("failed to verify ino %lu page %lu\n", 2268 printk("failed to verify ino %lu page %lu ret %d\n",
2121 page->mapping->host->i_ino, 2269 page->mapping->host->i_ino,
2122 page->index); 2270 page->index, ret);
2123 memset(page_address(page), 0, PAGE_CACHE_SIZE); 2271 memset(page_address(page), 1, PAGE_CACHE_SIZE);
2124 flush_dcache_page(page); 2272 flush_dcache_page(page);
2125 } 2273 }
2126 } 2274 }
2127 SetPageChecked(page); 2275 SetPageChecked(page);
2128 kunmap(page); 2276 kunmap(page);
2129 } 2277 }
2278checked:
2130 /* 2279 /*
2131 * Faults on the destination of a read are common, so do it before 2280 * Faults on the destination of a read are common, so do it before
2132 * taking the kmap. 2281 * taking the kmap.