aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-18 10:29:38 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:02 -0400
commita443755f1ca3e190e12e3a845ddecb3ee1782512 (patch)
treeedd5d77fe4b14eb91ac0add756094f2f1669a57d /fs/btrfs
parent41471e8341a6b476bcd8ecc765a8b297c22a74f9 (diff)
Btrfs: Check device uuids along with devids
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/volumes.c30
2 files changed, 28 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b56ae1950658..d119d95d139a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -800,6 +800,11 @@ static inline struct btrfs_stripe *btrfs_stripe_nr(struct btrfs_chunk *c,
800 return (struct btrfs_stripe *)offset; 800 return (struct btrfs_stripe *)offset;
801} 801}
802 802
803static inline char *btrfs_stripe_dev_uuid_nr(struct btrfs_chunk *c, int nr)
804{
805 return btrfs_stripe_dev_uuid(btrfs_stripe_nr(c, nr));
806}
807
803static inline u64 btrfs_stripe_offset_nr(struct extent_buffer *eb, 808static inline u64 btrfs_stripe_offset_nr(struct extent_buffer *eb,
804 struct btrfs_chunk *c, int nr) 809 struct btrfs_chunk *c, int nr)
805{ 810{
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c11b6fd408a6..cdf0019cca2e 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -69,15 +69,18 @@ int btrfs_cleanup_fs_uuids(void)
69 return 0; 69 return 0;
70} 70}
71 71
72static struct btrfs_device *__find_device(struct list_head *head, u64 devid) 72static struct btrfs_device *__find_device(struct list_head *head, u64 devid,
73 u8 *uuid)
73{ 74{
74 struct btrfs_device *dev; 75 struct btrfs_device *dev;
75 struct list_head *cur; 76 struct list_head *cur;
76 77
77 list_for_each(cur, head) { 78 list_for_each(cur, head) {
78 dev = list_entry(cur, struct btrfs_device, dev_list); 79 dev = list_entry(cur, struct btrfs_device, dev_list);
79 if (dev->devid == devid) 80 if (dev->devid == devid &&
81 !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE)) {
80 return dev; 82 return dev;
83 }
81 } 84 }
82 return NULL; 85 return NULL;
83} 86}
@@ -117,7 +120,8 @@ static int device_list_add(const char *path,
117 fs_devices->num_devices = 0; 120 fs_devices->num_devices = 0;
118 device = NULL; 121 device = NULL;
119 } else { 122 } else {
120 device = __find_device(&fs_devices->devices, devid); 123 device = __find_device(&fs_devices->devices, devid,
124 disk_super->dev_item.uuid);
121 } 125 }
122 if (!device) { 126 if (!device) {
123 device = kzalloc(sizeof(*device), GFP_NOFS); 127 device = kzalloc(sizeof(*device), GFP_NOFS);
@@ -126,6 +130,8 @@ static int device_list_add(const char *path,
126 return -ENOMEM; 130 return -ENOMEM;
127 } 131 }
128 device->devid = devid; 132 device->devid = devid;
133 memcpy(device->uuid, disk_super->dev_item.uuid,
134 BTRFS_UUID_SIZE);
129 device->barriers = 1; 135 device->barriers = 1;
130 spin_lock_init(&device->io_lock); 136 spin_lock_init(&device->io_lock);
131 device->name = kstrdup(path, GFP_NOFS); 137 device->name = kstrdup(path, GFP_NOFS);
@@ -1098,11 +1104,12 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
1098 return 0; 1104 return 0;
1099} 1105}
1100 1106
1101struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid) 1107struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid,
1108 u8 *uuid)
1102{ 1109{
1103 struct list_head *head = &root->fs_info->fs_devices->devices; 1110 struct list_head *head = &root->fs_info->fs_devices->devices;
1104 1111
1105 return __find_device(head, devid); 1112 return __find_device(head, devid, uuid);
1106} 1113}
1107 1114
1108static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, 1115static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
@@ -1115,6 +1122,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
1115 u64 logical; 1122 u64 logical;
1116 u64 length; 1123 u64 length;
1117 u64 devid; 1124 u64 devid;
1125 u8 uuid[BTRFS_UUID_SIZE];
1118 int num_stripes; 1126 int num_stripes;
1119 int ret; 1127 int ret;
1120 int i; 1128 int i;
@@ -1163,7 +1171,10 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
1163 map->stripes[i].physical = 1171 map->stripes[i].physical =
1164 btrfs_stripe_offset_nr(leaf, chunk, i); 1172 btrfs_stripe_offset_nr(leaf, chunk, i);
1165 devid = btrfs_stripe_devid_nr(leaf, chunk, i); 1173 devid = btrfs_stripe_devid_nr(leaf, chunk, i);
1166 map->stripes[i].dev = btrfs_find_device(root, devid); 1174 read_extent_buffer(leaf, uuid, (unsigned long)
1175 btrfs_stripe_dev_uuid_nr(chunk, i),
1176 BTRFS_UUID_SIZE);
1177 map->stripes[i].dev = btrfs_find_device(root, devid, uuid);
1167 if (!map->stripes[i].dev) { 1178 if (!map->stripes[i].dev) {
1168 kfree(map); 1179 kfree(map);
1169 free_extent_map(em); 1180 free_extent_map(em);
@@ -1207,8 +1218,13 @@ static int read_one_dev(struct btrfs_root *root,
1207 struct btrfs_device *device; 1218 struct btrfs_device *device;
1208 u64 devid; 1219 u64 devid;
1209 int ret; 1220 int ret;
1221 u8 dev_uuid[BTRFS_UUID_SIZE];
1222
1210 devid = btrfs_device_id(leaf, dev_item); 1223 devid = btrfs_device_id(leaf, dev_item);
1211 device = btrfs_find_device(root, devid); 1224 read_extent_buffer(leaf, dev_uuid,
1225 (unsigned long)btrfs_device_uuid(dev_item),
1226 BTRFS_UUID_SIZE);
1227 device = btrfs_find_device(root, devid, dev_uuid);
1212 if (!device) { 1228 if (!device) {
1213 printk("warning devid %Lu not found already\n", devid); 1229 printk("warning devid %Lu not found already\n", devid);
1214 device = kzalloc(sizeof(*device), GFP_NOFS); 1230 device = kzalloc(sizeof(*device), GFP_NOFS);