diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-18 14:13:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-18 14:13:25 -0400 |
commit | 04a1320651757c78277bea48bec97f0d43e6b17b (patch) | |
tree | f4bac092938916bcdbf4e0aa30211de9d8899f3a | |
parent | 47f7dc4b845a9fe60c53b84b8c88cf14efd0de7f (diff) | |
parent | 665d4953cde6d9e75c62a07ec8f4f8fd7d396ade (diff) |
Merge tag 'for-4.18-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba:
"Three regression fixes. They're few-liners and fixing some corner
cases missed in the origial patches"
* tag 'for-4.18-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: scrub: Don't use inode page cache in scrub_handle_errored_block()
btrfs: fix use-after-free of cmp workspace pages
btrfs: restore uuid_mutex in btrfs_open_devices
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 17 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 2 |
3 files changed, 13 insertions, 8 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 43ecbe620dea..b077544b5232 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3327,11 +3327,13 @@ static void btrfs_cmp_data_free(struct cmp_pages *cmp) | |||
3327 | if (pg) { | 3327 | if (pg) { |
3328 | unlock_page(pg); | 3328 | unlock_page(pg); |
3329 | put_page(pg); | 3329 | put_page(pg); |
3330 | cmp->src_pages[i] = NULL; | ||
3330 | } | 3331 | } |
3331 | pg = cmp->dst_pages[i]; | 3332 | pg = cmp->dst_pages[i]; |
3332 | if (pg) { | 3333 | if (pg) { |
3333 | unlock_page(pg); | 3334 | unlock_page(pg); |
3334 | put_page(pg); | 3335 | put_page(pg); |
3336 | cmp->dst_pages[i] = NULL; | ||
3335 | } | 3337 | } |
3336 | } | 3338 | } |
3337 | } | 3339 | } |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 572306036477..6702896cdb8f 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -1151,11 +1151,6 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
1151 | return ret; | 1151 | return ret; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | if (sctx->is_dev_replace && !is_metadata && !have_csum) { | ||
1155 | sblocks_for_recheck = NULL; | ||
1156 | goto nodatasum_case; | ||
1157 | } | ||
1158 | |||
1159 | /* | 1154 | /* |
1160 | * read all mirrors one after the other. This includes to | 1155 | * read all mirrors one after the other. This includes to |
1161 | * re-read the extent or metadata block that failed (that was | 1156 | * re-read the extent or metadata block that failed (that was |
@@ -1268,13 +1263,19 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
1268 | goto out; | 1263 | goto out; |
1269 | } | 1264 | } |
1270 | 1265 | ||
1271 | if (!is_metadata && !have_csum) { | 1266 | /* |
1267 | * NOTE: Even for nodatasum case, it's still possible that it's a | ||
1268 | * compressed data extent, thus scrub_fixup_nodatasum(), which write | ||
1269 | * inode page cache onto disk, could cause serious data corruption. | ||
1270 | * | ||
1271 | * So here we could only read from disk, and hope our recovery could | ||
1272 | * reach disk before the newer write. | ||
1273 | */ | ||
1274 | if (0 && !is_metadata && !have_csum) { | ||
1272 | struct scrub_fixup_nodatasum *fixup_nodatasum; | 1275 | struct scrub_fixup_nodatasum *fixup_nodatasum; |
1273 | 1276 | ||
1274 | WARN_ON(sctx->is_dev_replace); | 1277 | WARN_ON(sctx->is_dev_replace); |
1275 | 1278 | ||
1276 | nodatasum_case: | ||
1277 | |||
1278 | /* | 1279 | /* |
1279 | * !is_metadata and !have_csum, this means that the data | 1280 | * !is_metadata and !have_csum, this means that the data |
1280 | * might not be COWed, that it might be modified | 1281 | * might not be COWed, that it might be modified |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index e034ad9e23b4..1da162928d1a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1146,6 +1146,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
1146 | { | 1146 | { |
1147 | int ret; | 1147 | int ret; |
1148 | 1148 | ||
1149 | mutex_lock(&uuid_mutex); | ||
1149 | mutex_lock(&fs_devices->device_list_mutex); | 1150 | mutex_lock(&fs_devices->device_list_mutex); |
1150 | if (fs_devices->opened) { | 1151 | if (fs_devices->opened) { |
1151 | fs_devices->opened++; | 1152 | fs_devices->opened++; |
@@ -1155,6 +1156,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
1155 | ret = open_fs_devices(fs_devices, flags, holder); | 1156 | ret = open_fs_devices(fs_devices, flags, holder); |
1156 | } | 1157 | } |
1157 | mutex_unlock(&fs_devices->device_list_mutex); | 1158 | mutex_unlock(&fs_devices->device_list_mutex); |
1159 | mutex_unlock(&uuid_mutex); | ||
1158 | 1160 | ||
1159 | return ret; | 1161 | return ret; |
1160 | } | 1162 | } |