summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mkfs.c8
-rw-r--r--utils.c31
-rw-r--r--utils.h2
3 files changed, 41 insertions, 0 deletions
diff --git a/mkfs.c b/mkfs.c
index 5631a62b..bb2c58ed 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -430,6 +430,14 @@ int main(int ac, char **av)
fprintf(stderr, "unable to open %s\n", file);
exit(1);
}
+ ret = btrfs_device_already_in_root(root, fd,
+ BTRFS_SUPER_INFO_OFFSET);
+ if (ret) {
+ fprintf(stderr, "skipping duplicate device %s in FS\n",
+ file);
+ close(fd);
+ continue;
+ }
ret = btrfs_prepare_device(fd, file, zero_end,
&dev_block_count);
diff --git a/utils.c b/utils.c
index ba9c7fbb..b9d85ac0 100644
--- a/utils.c
+++ b/utils.c
@@ -743,3 +743,34 @@ int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs,
{
return btrfs_scan_one_dir("/dev", run_ioctls);
}
+
+int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
+ int super_offset)
+{
+ struct btrfs_super_block *disk_super;
+ char *buf;
+ int ret = 0;
+
+ buf = malloc(BTRFS_SUPER_INFO_SIZE);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = pread(fd, buf, BTRFS_SUPER_INFO_SIZE, super_offset);
+ if (ret != BTRFS_SUPER_INFO_SIZE)
+ goto brelse;
+
+ ret = 0;
+ disk_super = (struct btrfs_super_block *)buf;
+ if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC,
+ sizeof(disk_super->magic)))
+ goto brelse;
+
+ if (!memcmp(disk_super->fsid, root->fs_info->super_copy.fsid,
+ BTRFS_FSID_SIZE))
+ ret = 1;
+brelse:
+ free(buf);
+out:
+ return ret;
+}
diff --git a/utils.h b/utils.h
index d03cd076..f93f8b30 100644
--- a/utils.h
+++ b/utils.h
@@ -37,4 +37,6 @@ int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs,
int btrfs_register_one_device(char *fname);
int btrfs_scan_one_dir(char *dirname, int run_ioctl);
int check_mounted(char *devicename);
+int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
+ int super_offset);
#endif