diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 96 |
1 files changed, 14 insertions, 82 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b531c36455d8..830d261d0e6b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -359,10 +359,14 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
359 | 359 | ||
360 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 360 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
361 | 361 | ||
362 | if (page->private == EXTENT_PAGE_PRIVATE) | 362 | if (page->private == EXTENT_PAGE_PRIVATE) { |
363 | WARN_ON(1); | ||
363 | goto out; | 364 | goto out; |
364 | if (!page->private) | 365 | } |
366 | if (!page->private) { | ||
367 | WARN_ON(1); | ||
365 | goto out; | 368 | goto out; |
369 | } | ||
366 | len = page->private >> 2; | 370 | len = page->private >> 2; |
367 | WARN_ON(len == 0); | 371 | WARN_ON(len == 0); |
368 | 372 | ||
@@ -843,7 +847,6 @@ static const struct address_space_operations btree_aops = { | |||
843 | .writepages = btree_writepages, | 847 | .writepages = btree_writepages, |
844 | .releasepage = btree_releasepage, | 848 | .releasepage = btree_releasepage, |
845 | .invalidatepage = btree_invalidatepage, | 849 | .invalidatepage = btree_invalidatepage, |
846 | .sync_page = block_sync_page, | ||
847 | #ifdef CONFIG_MIGRATION | 850 | #ifdef CONFIG_MIGRATION |
848 | .migratepage = btree_migratepage, | 851 | .migratepage = btree_migratepage, |
849 | #endif | 852 | #endif |
@@ -1327,82 +1330,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1327 | } | 1330 | } |
1328 | 1331 | ||
1329 | /* | 1332 | /* |
1330 | * this unplugs every device on the box, and it is only used when page | ||
1331 | * is null | ||
1332 | */ | ||
1333 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | ||
1334 | { | ||
1335 | struct btrfs_device *device; | ||
1336 | struct btrfs_fs_info *info; | ||
1337 | |||
1338 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; | ||
1339 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { | ||
1340 | if (!device->bdev) | ||
1341 | continue; | ||
1342 | |||
1343 | bdi = blk_get_backing_dev_info(device->bdev); | ||
1344 | if (bdi->unplug_io_fn) | ||
1345 | bdi->unplug_io_fn(bdi, page); | ||
1346 | } | ||
1347 | } | ||
1348 | |||
1349 | static void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | ||
1350 | { | ||
1351 | struct inode *inode; | ||
1352 | struct extent_map_tree *em_tree; | ||
1353 | struct extent_map *em; | ||
1354 | struct address_space *mapping; | ||
1355 | u64 offset; | ||
1356 | |||
1357 | /* the generic O_DIRECT read code does this */ | ||
1358 | if (1 || !page) { | ||
1359 | __unplug_io_fn(bdi, page); | ||
1360 | return; | ||
1361 | } | ||
1362 | |||
1363 | /* | ||
1364 | * page->mapping may change at any time. Get a consistent copy | ||
1365 | * and use that for everything below | ||
1366 | */ | ||
1367 | smp_mb(); | ||
1368 | mapping = page->mapping; | ||
1369 | if (!mapping) | ||
1370 | return; | ||
1371 | |||
1372 | inode = mapping->host; | ||
1373 | |||
1374 | /* | ||
1375 | * don't do the expensive searching for a small number of | ||
1376 | * devices | ||
1377 | */ | ||
1378 | if (BTRFS_I(inode)->root->fs_info->fs_devices->open_devices <= 2) { | ||
1379 | __unplug_io_fn(bdi, page); | ||
1380 | return; | ||
1381 | } | ||
1382 | |||
1383 | offset = page_offset(page); | ||
1384 | |||
1385 | em_tree = &BTRFS_I(inode)->extent_tree; | ||
1386 | read_lock(&em_tree->lock); | ||
1387 | em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE); | ||
1388 | read_unlock(&em_tree->lock); | ||
1389 | if (!em) { | ||
1390 | __unplug_io_fn(bdi, page); | ||
1391 | return; | ||
1392 | } | ||
1393 | |||
1394 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
1395 | free_extent_map(em); | ||
1396 | __unplug_io_fn(bdi, page); | ||
1397 | return; | ||
1398 | } | ||
1399 | offset = offset - em->start; | ||
1400 | btrfs_unplug_page(&BTRFS_I(inode)->root->fs_info->mapping_tree, | ||
1401 | em->block_start + offset, page); | ||
1402 | free_extent_map(em); | ||
1403 | } | ||
1404 | |||
1405 | /* | ||
1406 | * If this fails, caller must call bdi_destroy() to get rid of the | 1333 | * If this fails, caller must call bdi_destroy() to get rid of the |
1407 | * bdi again. | 1334 | * bdi again. |
1408 | */ | 1335 | */ |
@@ -1416,8 +1343,6 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) | |||
1416 | return err; | 1343 | return err; |
1417 | 1344 | ||
1418 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 1345 | bdi->ra_pages = default_backing_dev_info.ra_pages; |
1419 | bdi->unplug_io_fn = btrfs_unplug_io_fn; | ||
1420 | bdi->unplug_io_data = info; | ||
1421 | bdi->congested_fn = btrfs_congested_fn; | 1346 | bdi->congested_fn = btrfs_congested_fn; |
1422 | bdi->congested_data = info; | 1347 | bdi->congested_data = info; |
1423 | return 0; | 1348 | return 0; |
@@ -1550,6 +1475,7 @@ static int transaction_kthread(void *arg) | |||
1550 | spin_unlock(&root->fs_info->new_trans_lock); | 1475 | spin_unlock(&root->fs_info->new_trans_lock); |
1551 | 1476 | ||
1552 | trans = btrfs_join_transaction(root, 1); | 1477 | trans = btrfs_join_transaction(root, 1); |
1478 | BUG_ON(IS_ERR(trans)); | ||
1553 | if (transid == trans->transid) { | 1479 | if (transid == trans->transid) { |
1554 | ret = btrfs_commit_transaction(trans, root); | 1480 | ret = btrfs_commit_transaction(trans, root); |
1555 | BUG_ON(ret); | 1481 | BUG_ON(ret); |
@@ -2453,10 +2379,14 @@ int btrfs_commit_super(struct btrfs_root *root) | |||
2453 | up_write(&root->fs_info->cleanup_work_sem); | 2379 | up_write(&root->fs_info->cleanup_work_sem); |
2454 | 2380 | ||
2455 | trans = btrfs_join_transaction(root, 1); | 2381 | trans = btrfs_join_transaction(root, 1); |
2382 | if (IS_ERR(trans)) | ||
2383 | return PTR_ERR(trans); | ||
2456 | ret = btrfs_commit_transaction(trans, root); | 2384 | ret = btrfs_commit_transaction(trans, root); |
2457 | BUG_ON(ret); | 2385 | BUG_ON(ret); |
2458 | /* run commit again to drop the original snapshot */ | 2386 | /* run commit again to drop the original snapshot */ |
2459 | trans = btrfs_join_transaction(root, 1); | 2387 | trans = btrfs_join_transaction(root, 1); |
2388 | if (IS_ERR(trans)) | ||
2389 | return PTR_ERR(trans); | ||
2460 | btrfs_commit_transaction(trans, root); | 2390 | btrfs_commit_transaction(trans, root); |
2461 | ret = btrfs_write_and_wait_transaction(NULL, root); | 2391 | ret = btrfs_write_and_wait_transaction(NULL, root); |
2462 | BUG_ON(ret); | 2392 | BUG_ON(ret); |
@@ -2484,7 +2414,7 @@ int close_ctree(struct btrfs_root *root) | |||
2484 | * ERROR state on disk. | 2414 | * ERROR state on disk. |
2485 | * | 2415 | * |
2486 | * 2. when btrfs flips readonly just in btrfs_commit_super, | 2416 | * 2. when btrfs flips readonly just in btrfs_commit_super, |
2487 | * and in such case, btrfs cannnot write sb via btrfs_commit_super, | 2417 | * and in such case, btrfs cannot write sb via btrfs_commit_super, |
2488 | * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag, | 2418 | * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag, |
2489 | * btrfs will cleanup all FS resources first and write sb then. | 2419 | * btrfs will cleanup all FS resources first and write sb then. |
2490 | */ | 2420 | */ |
@@ -2554,6 +2484,8 @@ int close_ctree(struct btrfs_root *root) | |||
2554 | kfree(fs_info->chunk_root); | 2484 | kfree(fs_info->chunk_root); |
2555 | kfree(fs_info->dev_root); | 2485 | kfree(fs_info->dev_root); |
2556 | kfree(fs_info->csum_root); | 2486 | kfree(fs_info->csum_root); |
2487 | kfree(fs_info); | ||
2488 | |||
2557 | return 0; | 2489 | return 0; |
2558 | } | 2490 | } |
2559 | 2491 | ||