Message ID | 1402633581-19265-2-git-send-email-Anand.Jain@oracle.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Hi Anand, On 06/13/2014 12:26 PM, Anand Jain wrote: > <..snip..> > @@ -523,6 +523,16 @@ static noinline int device_list_add(const char *path, > > if (fs_devices->opened) > return -EBUSY; > + else { > + /* > + * That is if the FS is _not_ mounted and if you are here, that > + * means there is more than one disk with same uuid and devid. > + * We keep the one with larger generation number or the last-in > + * if generation are equal. > + */ > + if (found_transid < device->generation) > + return -EINVAL; > + } I tried this patch it outputed the following message if it encounter two device with the same uuid and device id: Scanning for Btrfs filesystems ERROR: device scan failed '/dev/sdc' - Invalid argument Same comment as your first patch here. > > name = rcu_string_strdup(path, GFP_NOFS); > if (!name) > @@ -535,6 +545,15 @@ static noinline int device_list_add(const char *path, > } > } > > + /* > + * Unmount does not free the btrfs_device struct but would zero > + * generation along with most of the other members. So just update > + * it back. We need it to pick the disk with largest generation > + * (as above). > + */ > + if (!fs_devices->opened) > + device->generation = found_transid; > + > if (found_transid > fs_devices->latest_trans) { > fs_devices->latest_devid = devid; > fs_devices->latest_trans = found_transid; -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 56822f0..bb1b4bd 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -523,6 +523,16 @@ static noinline int device_list_add(const char *path, if (fs_devices->opened) return -EBUSY; + else { + /* + * That is if the FS is _not_ mounted and if you are here, that + * means there is more than one disk with same uuid and devid. + * We keep the one with larger generation number or the last-in + * if generation are equal. + */ + if (found_transid < device->generation) + return -EINVAL; + } name = rcu_string_strdup(path, GFP_NOFS); if (!name) @@ -535,6 +545,15 @@ static noinline int device_list_add(const char *path, } } + /* + * Unmount does not free the btrfs_device struct but would zero + * generation along with most of the other members. So just update + * it back. We need it to pick the disk with largest generation + * (as above). + */ + if (!fs_devices->opened) + device->generation = found_transid; + if (found_transid > fs_devices->latest_trans) { fs_devices->latest_devid = devid; fs_devices->latest_trans = found_transid;