diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-18 10:29:38 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | a443755f1ca3e190e12e3a845ddecb3ee1782512 (patch) | |
tree | edd5d77fe4b14eb91ac0add756094f2f1669a57d /fs | |
parent | 41471e8341a6b476bcd8ecc765a8b297c22a74f9 (diff) |
Btrfs: Check device uuids along with devids
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 5 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 30 |
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 | ||
803 | static 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 | |||
803 | static inline u64 btrfs_stripe_offset_nr(struct extent_buffer *eb, | 808 | static 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 | ||
72 | static struct btrfs_device *__find_device(struct list_head *head, u64 devid) | 72 | static 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 | ||
1101 | struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid) | 1107 | struct 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 | ||
1108 | static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | 1115 | static 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); |