aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-13 13:46:40 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commitdfe25020689bb2d318782d2c9c7141203583fc70 (patch)
treee106059546d7755af0d3b86bf47c113ca8927d7d /fs/btrfs/disk-io.c
parent1259ab75c62462b8ffad90067b5e1f6312786a18 (diff)
Btrfs: Add mount -o degraded to allow mounts to continue with missing devices
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 574b1245964e..38b0d9ecda6a 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -614,21 +614,6 @@ int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
614 return ret; 614 return ret;
615} 615}
616 616
617static int close_all_devices(struct btrfs_fs_info *fs_info)
618{
619 struct list_head *list;
620 struct list_head *next;
621 struct btrfs_device *device;
622
623 list = &fs_info->fs_devices->devices;
624 list_for_each(next, list) {
625 device = list_entry(next, struct btrfs_device, dev_list);
626 close_bdev_excl(device->bdev);
627 device->bdev = NULL;
628 }
629 return 0;
630}
631
632struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, 617struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
633 u64 bytenr, u32 blocksize) 618 u64 bytenr, u32 blocksize)
634{ 619{
@@ -927,6 +912,8 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
927 912
928 list_for_each(cur, &info->fs_devices->devices) { 913 list_for_each(cur, &info->fs_devices->devices) {
929 device = list_entry(cur, struct btrfs_device, dev_list); 914 device = list_entry(cur, struct btrfs_device, dev_list);
915 if (!device->bdev)
916 continue;
930 bdi = blk_get_backing_dev_info(device->bdev); 917 bdi = blk_get_backing_dev_info(device->bdev);
931 if (bdi && bdi_congested(bdi, bdi_bits)) { 918 if (bdi && bdi_congested(bdi, bdi_bits)) {
932 ret = 1; 919 ret = 1;
@@ -1140,7 +1127,8 @@ static void btrfs_async_submit_work(struct work_struct *work)
1140} 1127}
1141 1128
1142struct btrfs_root *open_ctree(struct super_block *sb, 1129struct btrfs_root *open_ctree(struct super_block *sb,
1143 struct btrfs_fs_devices *fs_devices) 1130 struct btrfs_fs_devices *fs_devices,
1131 char *options)
1144{ 1132{
1145 u32 sectorsize; 1133 u32 sectorsize;
1146 u32 nodesize; 1134 u32 nodesize;
@@ -1276,12 +1264,19 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1276 if (!btrfs_super_root(disk_super)) 1264 if (!btrfs_super_root(disk_super))
1277 goto fail_sb_buffer; 1265 goto fail_sb_buffer;
1278 1266
1279 if (btrfs_super_num_devices(disk_super) != fs_devices->num_devices) { 1267 btrfs_parse_options(options, tree_root, NULL);
1268
1269 if (btrfs_super_num_devices(disk_super) > fs_devices->num_devices) {
1280 printk("Btrfs: wanted %llu devices, but found %llu\n", 1270 printk("Btrfs: wanted %llu devices, but found %llu\n",
1281 (unsigned long long)btrfs_super_num_devices(disk_super), 1271 (unsigned long long)btrfs_super_num_devices(disk_super),
1282 (unsigned long long)fs_devices->num_devices); 1272 (unsigned long long)fs_devices->num_devices);
1283 goto fail_sb_buffer; 1273 if (btrfs_test_opt(tree_root, DEGRADED))
1274 printk("continuing in degraded mode\n");
1275 else {
1276 goto fail_sb_buffer;
1277 }
1284 } 1278 }
1279
1285 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); 1280 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
1286 1281
1287 nodesize = btrfs_super_nodesize(disk_super); 1282 nodesize = btrfs_super_nodesize(disk_super);
@@ -1329,6 +1324,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1329 ret = btrfs_read_chunk_tree(chunk_root); 1324 ret = btrfs_read_chunk_tree(chunk_root);
1330 BUG_ON(ret); 1325 BUG_ON(ret);
1331 1326
1327 btrfs_close_extra_devices(fs_devices);
1328
1332 blocksize = btrfs_level_size(tree_root, 1329 blocksize = btrfs_level_size(tree_root,
1333 btrfs_super_root_level(disk_super)); 1330 btrfs_super_root_level(disk_super));
1334 1331
@@ -1374,7 +1371,7 @@ fail_sb_buffer:
1374fail_iput: 1371fail_iput:
1375 iput(fs_info->btree_inode); 1372 iput(fs_info->btree_inode);
1376fail: 1373fail:
1377 close_all_devices(fs_info); 1374 btrfs_close_devices(fs_info->fs_devices);
1378 btrfs_mapping_tree_free(&fs_info->mapping_tree); 1375 btrfs_mapping_tree_free(&fs_info->mapping_tree);
1379 1376
1380 kfree(extent_root); 1377 kfree(extent_root);
@@ -1429,6 +1426,13 @@ int write_all_supers(struct btrfs_root *root)
1429 dev_item = &sb->dev_item; 1426 dev_item = &sb->dev_item;
1430 list_for_each(cur, head) { 1427 list_for_each(cur, head) {
1431 dev = list_entry(cur, struct btrfs_device, dev_list); 1428 dev = list_entry(cur, struct btrfs_device, dev_list);
1429 if (!dev->bdev) {
1430 total_errors++;
1431 continue;
1432 }
1433 if (!dev->in_fs_metadata)
1434 continue;
1435
1432 btrfs_set_stack_device_type(dev_item, dev->type); 1436 btrfs_set_stack_device_type(dev_item, dev->type);
1433 btrfs_set_stack_device_id(dev_item, dev->devid); 1437 btrfs_set_stack_device_id(dev_item, dev->devid);
1434 btrfs_set_stack_device_total_bytes(dev_item, dev->total_bytes); 1438 btrfs_set_stack_device_total_bytes(dev_item, dev->total_bytes);
@@ -1482,6 +1486,11 @@ int write_all_supers(struct btrfs_root *root)
1482 1486
1483 list_for_each(cur, head) { 1487 list_for_each(cur, head) {
1484 dev = list_entry(cur, struct btrfs_device, dev_list); 1488 dev = list_entry(cur, struct btrfs_device, dev_list);
1489 if (!dev->bdev)
1490 continue;
1491 if (!dev->in_fs_metadata)
1492 continue;
1493
1485 BUG_ON(!dev->pending_io); 1494 BUG_ON(!dev->pending_io);
1486 bh = dev->pending_io; 1495 bh = dev->pending_io;
1487 wait_on_buffer(bh); 1496 wait_on_buffer(bh);
@@ -1631,7 +1640,7 @@ int close_ctree(struct btrfs_root *root)
1631 kfree(hasher); 1640 kfree(hasher);
1632 } 1641 }
1633#endif 1642#endif
1634 close_all_devices(fs_info); 1643 btrfs_close_devices(fs_info->fs_devices);
1635 btrfs_mapping_tree_free(&fs_info->mapping_tree); 1644 btrfs_mapping_tree_free(&fs_info->mapping_tree);
1636 1645
1637#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) 1646#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)