aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c221
1 files changed, 212 insertions, 9 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b38187573108..55da5f0c56e3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -45,6 +45,16 @@ struct map_lookup {
45static DEFINE_MUTEX(uuid_mutex); 45static DEFINE_MUTEX(uuid_mutex);
46static LIST_HEAD(fs_uuids); 46static LIST_HEAD(fs_uuids);
47 47
48void btrfs_lock_volumes(void)
49{
50 mutex_lock(&uuid_mutex);
51}
52
53void btrfs_unlock_volumes(void)
54{
55 mutex_unlock(&uuid_mutex);
56}
57
48int btrfs_cleanup_fs_uuids(void) 58int btrfs_cleanup_fs_uuids(void)
49{ 59{
50 struct btrfs_fs_devices *fs_devices; 60 struct btrfs_fs_devices *fs_devices;
@@ -193,12 +203,14 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
193 ret = PTR_ERR(bdev); 203 ret = PTR_ERR(bdev);
194 goto fail; 204 goto fail;
195 } 205 }
206 set_blocksize(bdev, 4096);
196 if (device->devid == fs_devices->latest_devid) 207 if (device->devid == fs_devices->latest_devid)
197 fs_devices->latest_bdev = bdev; 208 fs_devices->latest_bdev = bdev;
198 if (device->devid == fs_devices->lowest_devid) { 209 if (device->devid == fs_devices->lowest_devid) {
199 fs_devices->lowest_bdev = bdev; 210 fs_devices->lowest_bdev = bdev;
200 } 211 }
201 device->bdev = bdev; 212 device->bdev = bdev;
213
202 } 214 }
203 mutex_unlock(&uuid_mutex); 215 mutex_unlock(&uuid_mutex);
204 return 0; 216 return 0;
@@ -393,6 +405,9 @@ int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
393 struct btrfs_path *path; 405 struct btrfs_path *path;
394 struct btrfs_root *root = device->dev_root; 406 struct btrfs_root *root = device->dev_root;
395 struct btrfs_key key; 407 struct btrfs_key key;
408 struct btrfs_key found_key;
409 struct extent_buffer *leaf = NULL;
410 struct btrfs_dev_extent *extent = NULL;
396 411
397 path = btrfs_alloc_path(); 412 path = btrfs_alloc_path();
398 if (!path) 413 if (!path)
@@ -403,8 +418,25 @@ int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
403 key.type = BTRFS_DEV_EXTENT_KEY; 418 key.type = BTRFS_DEV_EXTENT_KEY;
404 419
405 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 420 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
421 if (ret > 0) {
422 ret = btrfs_previous_item(root, path, key.objectid,
423 BTRFS_DEV_EXTENT_KEY);
424 BUG_ON(ret);
425 leaf = path->nodes[0];
426 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
427 extent = btrfs_item_ptr(leaf, path->slots[0],
428 struct btrfs_dev_extent);
429 BUG_ON(found_key.offset > start || found_key.offset +
430 btrfs_dev_extent_length(leaf, extent) < start);
431 ret = 0;
432 } else if (ret == 0) {
433 leaf = path->nodes[0];
434 extent = btrfs_item_ptr(leaf, path->slots[0],
435 struct btrfs_dev_extent);
436 }
406 BUG_ON(ret); 437 BUG_ON(ret);
407 438
439 device->bytes_used -= btrfs_dev_extent_length(leaf, extent);
408 ret = btrfs_del_item(trans, root, path); 440 ret = btrfs_del_item(trans, root, path);
409 BUG_ON(ret); 441 BUG_ON(ret);
410 442
@@ -593,6 +625,170 @@ out:
593 return ret; 625 return ret;
594} 626}
595 627
628static int btrfs_rm_dev_item(struct btrfs_root *root,
629 struct btrfs_device *device)
630{
631 int ret;
632 struct btrfs_path *path;
633 struct block_device *bdev = device->bdev;
634 struct btrfs_device *next_dev;
635 struct btrfs_key key;
636 u64 total_bytes;
637 struct btrfs_fs_devices *fs_devices;
638 struct btrfs_trans_handle *trans;
639
640 root = root->fs_info->chunk_root;
641
642 path = btrfs_alloc_path();
643 if (!path)
644 return -ENOMEM;
645
646 trans = btrfs_start_transaction(root, 1);
647 key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
648 key.type = BTRFS_DEV_ITEM_KEY;
649 key.offset = device->devid;
650
651 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
652 if (ret < 0)
653 goto out;
654
655 if (ret > 0) {
656 ret = -ENOENT;
657 goto out;
658 }
659
660 ret = btrfs_del_item(trans, root, path);
661 if (ret)
662 goto out;
663
664 /*
665 * at this point, the device is zero sized. We want to
666 * remove it from the devices list and zero out the old super
667 */
668 list_del_init(&device->dev_list);
669 list_del_init(&device->dev_alloc_list);
670 fs_devices = root->fs_info->fs_devices;
671
672 next_dev = list_entry(fs_devices->devices.next, struct btrfs_device,
673 dev_list);
674 if (bdev == fs_devices->lowest_bdev)
675 fs_devices->lowest_bdev = next_dev->bdev;
676 if (bdev == root->fs_info->sb->s_bdev)
677 root->fs_info->sb->s_bdev = next_dev->bdev;
678 if (bdev == fs_devices->latest_bdev)
679 fs_devices->latest_bdev = next_dev->bdev;
680
681 total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
682 btrfs_set_super_total_bytes(&root->fs_info->super_copy,
683 total_bytes - device->total_bytes);
684
685 total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy);
686 btrfs_set_super_num_devices(&root->fs_info->super_copy,
687 total_bytes - 1);
688out:
689 btrfs_free_path(path);
690 btrfs_commit_transaction(trans, root);
691 return ret;
692}
693
694int btrfs_rm_device(struct btrfs_root *root, char *device_path)
695{
696 struct btrfs_device *device;
697 struct block_device *bdev;
698 struct buffer_head *bh;
699 struct btrfs_super_block *disk_super;
700 u64 all_avail;
701 u64 devid;
702 int ret = 0;
703
704 mutex_lock(&root->fs_info->fs_mutex);
705 mutex_lock(&uuid_mutex);
706
707 all_avail = root->fs_info->avail_data_alloc_bits |
708 root->fs_info->avail_system_alloc_bits |
709 root->fs_info->avail_metadata_alloc_bits;
710
711 if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) &&
712 root->fs_info->fs_devices->num_devices <= 4) {
713 printk("btrfs: unable to go below four devices on raid10\n");
714 ret = -EINVAL;
715 goto out;
716 }
717
718 if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) &&
719 root->fs_info->fs_devices->num_devices <= 2) {
720 printk("btrfs: unable to go below two devices on raid1\n");
721 ret = -EINVAL;
722 goto out;
723 }
724
725 bdev = open_bdev_excl(device_path, 0, root->fs_info->bdev_holder);
726 if (IS_ERR(bdev)) {
727 ret = PTR_ERR(bdev);
728 goto out;
729 }
730
731 bh = __bread(bdev, BTRFS_SUPER_INFO_OFFSET / 4096, 4096);
732 if (!bh) {
733 ret = -EIO;
734 goto error_close;
735 }
736 disk_super = (struct btrfs_super_block *)bh->b_data;
737 if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC,
738 sizeof(disk_super->magic))) {
739 ret = -ENOENT;
740 goto error_brelse;
741 }
742 if (memcmp(disk_super->fsid, root->fs_info->fsid, BTRFS_FSID_SIZE)) {
743 ret = -ENOENT;
744 goto error_brelse;
745 }
746 devid = le64_to_cpu(disk_super->dev_item.devid);
747 device = btrfs_find_device(root, devid, NULL);
748 if (!device) {
749 ret = -ENOENT;
750 goto error_brelse;
751 }
752
753 root->fs_info->fs_devices->num_devices--;
754
755 ret = btrfs_shrink_device(device, 0);
756 if (ret)
757 goto error_brelse;
758
759
760 ret = btrfs_rm_dev_item(root->fs_info->chunk_root, device);
761 if (ret)
762 goto error_brelse;
763
764 /* make sure this device isn't detected as part of the FS anymore */
765 memset(&disk_super->magic, 0, sizeof(disk_super->magic));
766 set_buffer_dirty(bh);
767 sync_dirty_buffer(bh);
768
769 brelse(bh);
770
771 /* one close for the device struct or super_block */
772 close_bdev_excl(device->bdev);
773
774 /* one close for us */
775 close_bdev_excl(device->bdev);
776
777 kfree(device->name);
778 kfree(device);
779 ret = 0;
780 goto out;
781
782error_brelse:
783 brelse(bh);
784error_close:
785 close_bdev_excl(bdev);
786out:
787 mutex_unlock(&uuid_mutex);
788 mutex_unlock(&root->fs_info->fs_mutex);
789 return ret;
790}
791
596int btrfs_init_new_device(struct btrfs_root *root, char *device_path) 792int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
597{ 793{
598 struct btrfs_trans_handle *trans; 794 struct btrfs_trans_handle *trans;
@@ -831,13 +1027,17 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
831 em = lookup_extent_mapping(em_tree, chunk_offset, 1); 1027 em = lookup_extent_mapping(em_tree, chunk_offset, 1);
832 spin_unlock(&em_tree->lock); 1028 spin_unlock(&em_tree->lock);
833 1029
834 BUG_ON(em->start > chunk_offset || em->start + em->len < chunk_offset); 1030 BUG_ON(em->start > chunk_offset ||
1031 em->start + em->len < chunk_offset);
835 map = (struct map_lookup *)em->bdev; 1032 map = (struct map_lookup *)em->bdev;
836 1033
837 for (i = 0; i < map->num_stripes; i++) { 1034 for (i = 0; i < map->num_stripes; i++) {
838 ret = btrfs_free_dev_extent(trans, map->stripes[i].dev, 1035 ret = btrfs_free_dev_extent(trans, map->stripes[i].dev,
839 map->stripes[i].physical); 1036 map->stripes[i].physical);
840 BUG_ON(ret); 1037 BUG_ON(ret);
1038
1039 ret = btrfs_update_device(trans, map->stripes[i].dev);
1040 BUG_ON(ret);
841 } 1041 }
842 ret = btrfs_free_chunk(trans, root, chunk_tree, chunk_objectid, 1042 ret = btrfs_free_chunk(trans, root, chunk_tree, chunk_objectid,
843 chunk_offset); 1043 chunk_offset);
@@ -847,11 +1047,8 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
847 if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) { 1047 if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
848 ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset); 1048 ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset);
849 BUG_ON(ret); 1049 BUG_ON(ret);
850 goto out;
851 } 1050 }
852 1051
853
854
855 spin_lock(&em_tree->lock); 1052 spin_lock(&em_tree->lock);
856 remove_extent_mapping(em_tree, em); 1053 remove_extent_mapping(em_tree, em);
857 kfree(map); 1054 kfree(map);
@@ -861,7 +1058,6 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
861 free_extent_map(em); 1058 free_extent_map(em);
862 spin_unlock(&em_tree->lock); 1059 spin_unlock(&em_tree->lock);
863 1060
864out:
865 /* once for us */ 1061 /* once for us */
866 free_extent_map(em); 1062 free_extent_map(em);
867 1063
@@ -1449,7 +1645,7 @@ again:
1449 return 0; 1645 return 0;
1450 1646
1451 if (!em) { 1647 if (!em) {
1452 printk("unable to find logical %Lu\n", logical); 1648 printk("unable to find logical %Lu len %Lu\n", logical, *length);
1453 BUG(); 1649 BUG();
1454 } 1650 }
1455 1651
@@ -1712,6 +1908,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
1712 1908
1713 logical = key->offset; 1909 logical = key->offset;
1714 length = btrfs_chunk_length(leaf, chunk); 1910 length = btrfs_chunk_length(leaf, chunk);
1911
1715 spin_lock(&map_tree->map_tree.lock); 1912 spin_lock(&map_tree->map_tree.lock);
1716 em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); 1913 em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
1717 spin_unlock(&map_tree->map_tree.lock); 1914 spin_unlock(&map_tree->map_tree.lock);
@@ -1845,7 +2042,7 @@ int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf)
1845int btrfs_read_sys_array(struct btrfs_root *root) 2042int btrfs_read_sys_array(struct btrfs_root *root)
1846{ 2043{
1847 struct btrfs_super_block *super_copy = &root->fs_info->super_copy; 2044 struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
1848 struct extent_buffer *sb = root->fs_info->sb_buffer; 2045 struct extent_buffer *sb;
1849 struct btrfs_disk_key *disk_key; 2046 struct btrfs_disk_key *disk_key;
1850 struct btrfs_chunk *chunk; 2047 struct btrfs_chunk *chunk;
1851 u8 *ptr; 2048 u8 *ptr;
@@ -1857,6 +2054,12 @@ int btrfs_read_sys_array(struct btrfs_root *root)
1857 u32 cur; 2054 u32 cur;
1858 struct btrfs_key key; 2055 struct btrfs_key key;
1859 2056
2057 sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET,
2058 BTRFS_SUPER_INFO_SIZE);
2059 if (!sb)
2060 return -ENOMEM;
2061 btrfs_set_buffer_uptodate(sb);
2062 write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE);
1860 array_size = btrfs_super_sys_array_size(super_copy); 2063 array_size = btrfs_super_sys_array_size(super_copy);
1861 2064
1862 ptr = super_copy->sys_chunk_array; 2065 ptr = super_copy->sys_chunk_array;
@@ -1867,8 +2070,7 @@ int btrfs_read_sys_array(struct btrfs_root *root)
1867 disk_key = (struct btrfs_disk_key *)ptr; 2070 disk_key = (struct btrfs_disk_key *)ptr;
1868 btrfs_disk_key_to_cpu(&key, disk_key); 2071 btrfs_disk_key_to_cpu(&key, disk_key);
1869 2072
1870 len = sizeof(*disk_key); 2073 len = sizeof(*disk_key); ptr += len;
1871 ptr += len;
1872 sb_ptr += len; 2074 sb_ptr += len;
1873 cur += len; 2075 cur += len;
1874 2076
@@ -1887,6 +2089,7 @@ int btrfs_read_sys_array(struct btrfs_root *root)
1887 sb_ptr += len; 2089 sb_ptr += len;
1888 cur += len; 2090 cur += len;
1889 } 2091 }
2092 free_extent_buffer(sb);
1890 return ret; 2093 return ret;
1891} 2094}
1892 2095