__le64 total_blocks;
        __le64 blocks_used;
        __le64 root_dir_objectid;
+       __le64 last_device_id;
        /* fields below here vary with the underlying disk */
        __le64 device_block_start;
        __le64 device_num_blocks;
        __le64 device_root;
+       __le64 device_id;
 } __attribute__ ((__packed__));
 
 /*
 
 struct btrfs_device_item {
        __le16 pathlen;
+       __le64 device_id;
 } __attribute__ ((__packed__));
 
 struct crypto_hash;
        s->root_dir_objectid = cpu_to_le64(val);
 }
 
+static inline u64 btrfs_super_last_device_id(struct btrfs_super_block *s)
+{
+       return le64_to_cpu(s->last_device_id);
+}
+
+static inline void btrfs_set_super_last_device_id(struct btrfs_super_block *s,
+                                                 u64 val)
+{
+       s->last_device_id = cpu_to_le64(val);
+}
+
+static inline u64 btrfs_super_device_id(struct btrfs_super_block *s)
+{
+       return le64_to_cpu(s->device_id);
+}
+
+static inline void btrfs_set_super_device_id(struct btrfs_super_block *s,
+                                                 u64 val)
+{
+       s->device_id = cpu_to_le64(val);
+}
+
 static inline u64 btrfs_super_device_block_start(struct btrfs_super_block *s)
 {
        return le64_to_cpu(s->device_block_start);
        d->pathlen = cpu_to_le16(val);
 }
 
+static inline u64 btrfs_device_id(struct btrfs_device_item *d)
+{
+       return le64_to_cpu(d->device_id);
+}
+
+static inline void btrfs_set_device_id(struct btrfs_device_item *d,
+                                               u64 val)
+{
+       d->device_id = cpu_to_le64(val);
+}
+
 static inline struct btrfs_root *btrfs_sb(struct super_block *sb)
 {
        return sb->s_fs_info;
 
 struct dev_lookup {
        u64 block_start;
        u64 num_blocks;
+       u64 device_id;
        struct block_device *bdev;
 };
 
 int btrfs_insert_dev_radix(struct btrfs_root *root,
                           struct block_device *bdev,
+                          u64 device_id,
                           u64 block_start,
                           u64 num_blocks)
 {
        lookup->block_start = block_start;
        lookup->num_blocks = num_blocks;
        lookup->bdev = bdev;
+       lookup->device_id = device_id;
 printk("inserting %s into dev radix %Lu %Lu\n", bdevname(bdev, b), block_start, num_blocks);
 
        ret = radix_tree_insert(&root->fs_info->dev_radix, block_start +
        return root;
 }
 
-int btrfs_open_disk(struct btrfs_root *root, u64 block_start, u64 num_blocks,
-                   char *filename, int name_len)
+static int btrfs_open_disk(struct btrfs_root *root, u64 device_id,
+                          u64 block_start, u64 num_blocks,
+                          char *filename, int name_len)
 {
        char *null_filename;
        struct block_device *bdev;
        int ret;
 
-       if (block_start == 0) {
-printk("skipping disk with block_start == 0\n");
-return 0;
-       }
        null_filename = kmalloc(name_len + 1, GFP_NOFS);
        if (!null_filename)
                return -ENOMEM;
                goto out;
        }
        set_blocksize(bdev, root->fs_info->sb->s_blocksize);
-       ret = btrfs_insert_dev_radix(root, bdev, block_start, num_blocks);
+       ret = btrfs_insert_dev_radix(root, bdev, device_id,
+                                    block_start, num_blocks);
        BUG_ON(ret);
        ret = 0;
 out:
                }
                dev_item = btrfs_item_ptr(leaf, slot, struct btrfs_device_item);
 printk("found key %Lu %Lu\n", key.objectid, key.offset);
-               ret = btrfs_open_disk(root, key.objectid, key.offset,
-                                     (char *)(dev_item + 1),
-                                     btrfs_device_pathlen(dev_item));
-               BUG_ON(ret);
+               if (btrfs_device_id(dev_item) !=
+                   btrfs_super_device_id(root->fs_info->disk_super)) {
+                       ret = btrfs_open_disk(root, btrfs_device_id(dev_item),
+                                             key.objectid, key.offset,
+                                             (char *)(dev_item + 1),
+                                             btrfs_device_pathlen(dev_item));
+                       BUG_ON(ret);
+               }
                path->slots[0]++;
        }
        btrfs_free_path(path);
        dev_lookup->block_start = 0;
        dev_lookup->num_blocks = (u32)-2;
        dev_lookup->bdev = sb->s_bdev;
+       dev_lookup->device_id = 0;
        ret = radix_tree_insert(&fs_info->dev_radix, (u32)-2, dev_lookup);
        BUG_ON(ret);
        fs_info->sb_buffer = read_tree_block(tree_root,
        radix_tree_delete(&fs_info->dev_radix, (u32)-2);
        dev_lookup->block_start = btrfs_super_device_block_start(disk_super);
        dev_lookup->num_blocks = btrfs_super_device_num_blocks(disk_super);
+       dev_lookup->device_id = btrfs_super_device_id(disk_super);
+
        ret = radix_tree_insert(&fs_info->dev_radix,
                                dev_lookup->block_start +
                                dev_lookup->num_blocks - 1, dev_lookup);
        }
        return 0;
 }
+
 static int free_dev_radix(struct btrfs_fs_info *fs_info)
 {
        struct dev_lookup *lookup[8];
 
        u16 item_size;
        u64 num_blocks;
        u64 new_blocks;
+       u64 device_id;
        int ret;
+
 printk("adding disk %s\n", name);
        path = btrfs_alloc_path();
        if (!path)
                                  path->slots[0], struct btrfs_device_item);
        btrfs_set_device_pathlen(dev_item, namelen);
        memcpy(dev_item + 1, name, namelen);
+
+       device_id = btrfs_super_last_device_id(root->fs_info->disk_super) + 1;
+       btrfs_set_super_last_device_id(root->fs_info->disk_super, device_id);
+       btrfs_set_device_id(dev_item, device_id);
        mark_buffer_dirty(path->nodes[0]);
 
-       ret = btrfs_insert_dev_radix(root, bdev, num_blocks, new_blocks);
+       ret = btrfs_insert_dev_radix(root, bdev, device_id, num_blocks,
+                                    new_blocks);
 
        if (!ret) {
                btrfs_set_super_total_blocks(root->fs_info->disk_super,