btrfs: fix a deadlock in btrfs_scan_one_device()
pathname resolution under a global mutex, taken on some paths in ->mount() is a Bad Idea(tm) - think what happens if said pathname resolution triggers automount of some btrfs instance and walks into attempt to grab the same mutex. Deadlock - we are waiting for daemon to finish walking the path, daemon is waiting for us to release the mutex... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
6de1d09d96
commit
10f6327b5d
|
@ -706,8 +706,6 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
|
||||||
u64 devid;
|
u64 devid;
|
||||||
u64 transid;
|
u64 transid;
|
||||||
|
|
||||||
mutex_lock(&uuid_mutex);
|
|
||||||
|
|
||||||
flags |= FMODE_EXCL;
|
flags |= FMODE_EXCL;
|
||||||
bdev = blkdev_get_by_path(path, flags, holder);
|
bdev = blkdev_get_by_path(path, flags, holder);
|
||||||
|
|
||||||
|
@ -716,6 +714,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&uuid_mutex);
|
||||||
ret = set_blocksize(bdev, 4096);
|
ret = set_blocksize(bdev, 4096);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_close;
|
goto error_close;
|
||||||
|
@ -737,9 +736,9 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
|
||||||
|
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
error_close:
|
error_close:
|
||||||
|
mutex_unlock(&uuid_mutex);
|
||||||
blkdev_put(bdev, flags);
|
blkdev_put(bdev, flags);
|
||||||
error:
|
error:
|
||||||
mutex_unlock(&uuid_mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue