linux-stable/fs
Qu Wenruo b1cf23c2c8 btrfs: scrub: Don't use inode pages for device replace
commit ac0b4145d6 upstream.

[BUG]
Btrfs can create compressed extent without checksum (even though it
shouldn't), and if we then try to replace device containing such extent,
the result device will contain all the uncompressed data instead of the
compressed one.

Test case already submitted to fstests:
https://patchwork.kernel.org/patch/10442353/

[CAUSE]
When handling compressed extent without checksum, device replace will
goe into copy_nocow_pages() function.

In that function, btrfs will get all inodes referring to this data
extents and then use find_or_create_page() to get pages direct from that
inode.

The problem here is, pages directly from inode are always uncompressed.
And for compressed data extent, they mismatch with on-disk data.
Thus this leads to corrupted compressed data extent written to replace
device.

[FIX]
In this attempt, we could just remove the "optimization" branch, and let
unified scrub_pages() to handle it.

Although scrub_pages() won't bother reusing page cache, it will be a
little slower, but it does the correct csum checking and won't cause
such data corruption caused by "optimization".

Note about the fix: this is the minimal fix that can be backported to
older stable trees without conflicts. The whole callchain from
copy_nocow_pages() can be deleted, and will be in followup patches.

Fixes: ff023aac31 ("Btrfs: add code to scrub to copy read data to another disk")
CC: stable@vger.kernel.org # 4.4+
Reported-by: James Harvey <jamespharvey20@gmail.com>
Reviewed-by: James Harvey <jamespharvey20@gmail.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
[ remove code removal, add note why ]
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-26 08:06:30 +08:00
..
9p fs/9p: Compare qid.path in v9fs_test_inode 2017-11-30 08:40:49 +00:00
adfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
affs affs_lookup(): close a race with affs_remove_link() 2018-05-30 07:51:47 +02:00
afs afs: Fix the non-encryption of calls 2018-06-21 04:02:59 +09:00
autofs4 autofs: mount point create should honour passed in mode 2018-04-24 09:36:39 +02:00
befs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
bfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
btrfs btrfs: scrub: Don't use inode pages for device replace 2018-06-26 08:06:30 +08:00
cachefiles License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ceph ceph: fix potential memory leak in init_caches() 2018-05-30 07:52:09 +02:00
cifs cifs: smb2ops: Fix listxattr() when there are no EAs 2018-06-21 04:02:56 +09:00
coda coda: fix 'kernel memory exposure attempt' in fsync 2017-11-24 08:37:05 +01:00
configfs
cramfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
crypto fscrypt: lock mutex before checking for bounce page pool 2017-11-30 08:40:44 +00:00
debugfs
devpts devpts: fix error handling in devpts_mntget() 2018-02-16 20:23:11 +01:00
dlm License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ecryptfs eCryptfs: don't pass up plaintext names when using filename encryption 2018-06-21 04:02:42 +09:00
efivarfs
efs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
exofs Merge branch 'for-4.14/block' of git://git.kernel.dk/linux-block 2017-09-07 11:59:42 -07:00
exportfs
ext2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
ext4 ext4: fix fencepost error in check for inode count overflow during resize 2018-06-26 08:06:29 +08:00
f2fs f2fs: fix to check extent cache in f2fs_drop_extent_tree 2018-05-30 07:52:33 +02:00
fat fs/fat/inode.c: fix sb_rdonly() change 2017-12-05 11:26:29 +01:00
freevxfs
fscache fscache: Fix hanging wait on page discarded by writeback 2018-05-30 07:52:25 +02:00
fuse fuse: fix READDIRPLUS skipping an entry 2017-10-25 16:34:27 +02:00
gfs2 gfs2: Fix fallocate chunk size 2018-05-30 07:52:35 +02:00
hfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
hfsplus hfsplus: stop workqueue when fill_super() failed 2018-05-25 16:17:35 +02:00
hostfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
hpfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
hugetlbfs hugetlbfs: fix bug in pgoff overflow checking 2018-04-19 08:56:21 +02:00
isofs isofs: fix potential memory leak in mount option parsing 2018-06-21 04:02:41 +09:00
jbd2 ext4: set h_journal if there is a failure starting a reserved handle 2018-05-01 12:58:06 -07:00
jffs2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
jfs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
kernfs kernfs: fix regression in kernfs_fop_write caused by wrong type 2018-02-16 20:22:59 +01:00
lockd race of lockd inetaddr notifiers vs nlmsvc_rqst change 2018-02-03 17:39:08 +01:00
minix License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ncpfs staging: ncpfs: memory corruption in ncp_read_kernel() 2018-03-28 18:24:43 +02:00
nfs NFSv4.1: Fix up replays of interrupted requests 2018-06-26 08:06:29 +08:00
nfs_common lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:39:08 +01:00
nfsd nfsd: fix incorrect umasks 2018-04-19 08:56:21 +02:00
nilfs2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
nls License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
notify fsnotify: fix ignore mask logic in send_to_group() 2018-06-21 04:02:41 +09:00
ntfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ocfs2 ocfs2: take inode cluster lock before moving reflinked inode from orphan dir 2018-06-21 04:02:57 +09:00
omfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
openpromfs
orangefs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
overlayfs ovl: fix lookup with middle layer opaque dir and absolute path redirects 2018-04-19 08:56:21 +02:00
proc proc/kcore: don't bounds check against address 0 2018-06-21 04:02:57 +09:00
pstore License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
qnx4 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
qnx6 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
quota quota: Check for register_shrinker() failure. 2018-02-03 17:39:11 +01:00
ramfs mm: make pagevec_lookup() update index 2017-09-06 17:27:26 -07:00
reiserfs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
romfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
squashfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sysfs sysfs: symlink: export sysfs_create_link_nowarn() 2018-03-31 18:10:38 +02:00
sysv License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tracefs
ubifs ubifs: Fix uninitialized variable in search_dh_cookie() 2018-04-26 11:02:07 +02:00
udf udf: Provide saner default for invalid uid / gid 2018-05-30 07:52:38 +02:00
ufs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
xfs xfs: detect agfl count corruption and reset agfl 2018-06-05 11:41:55 +02:00
aio.c fix io_destroy()/aio_complete() race 2018-06-05 11:41:54 +02:00
anon_inodes.c
attr.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
bad_inode.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
binfmt_aout.c fs: fix kernel_read prototype 2017-09-04 19:05:15 -04:00
binfmt_elf.c Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
binfmt_elf_fdpic.c Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
binfmt_em86.c
binfmt_flat.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
binfmt_misc.c fs/binfmt_misc.c: node could be NULL when evicting inode 2017-10-13 16:18:33 -07:00
binfmt_script.c exec: load_script: kill the onstack interp[BINPRM_BUF_SIZE] array 2017-10-03 17:54:25 -07:00
block_dev.c fs/mpage.c: fix mpage_writepage() for pages with buffers 2017-10-13 16:18:33 -07:00
buffer.c fs: guard_bio_eod() needs to consider partitions 2017-11-30 08:40:45 +00:00
char_dev.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
compat.c
compat_binfmt_elf.c
compat_ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
coredump.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
dax.c fs/dax.c: release PMD lock even when there is no PMD support in DAX 2018-04-26 11:02:14 +02:00
dcache.c fs: dcache: Use READ_ONCE when accessing i_dir_seq 2018-05-30 07:52:03 +02:00
dcookies.c
direct-io.c direct-io: Fix sleep in atomic due to sync AIO 2018-03-08 22:41:06 -08:00
drop_caches.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
eventfd.c
eventpoll.c fs/epoll: use faster rb_first_cached() 2017-09-08 18:26:49 -07:00
exec.c exec: avoid gcc-8 warning for get_task_comm 2018-03-03 10:24:21 +01:00
fcntl.c fcntl: don't cap l_start and l_end values for F_GETLK64 in compat syscall 2017-12-17 15:07:59 +01:00
fhandle.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
file.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
file_table.c fput: Don't reinvent the wheel but use existing llist API 2017-08-28 00:50:23 -04:00
filesystems.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
fs-writeback.c bdi: Fix oops in wb_workfn() 2018-05-16 10:10:25 +02:00
fs_pin.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
fs_struct.c
inode.c Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs 2017-09-13 09:11:44 -07:00
internal.h Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs 2017-09-13 09:11:44 -07:00
ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
iomap.c fs: invalidate page cache after end_io() in dio completion 2017-10-16 12:11:56 -07:00
Kconfig
Kconfig.binfmt
libfs.c
locks.c
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mbcache.c mbcache: initialize entry->e_referenced in mb_cache_entry_create() 2018-02-22 15:42:25 +01:00
mount.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mpage.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
namei.c getname_kernel() needs to make sure that ->name != ->iname in long case 2018-04-19 08:56:19 +02:00
namespace.c vfs: Undo an overly zealous MS_RDONLY -> SB_RDONLY conversion 2018-06-21 04:02:45 +09:00
no-block.c
nsfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
open.c ovl: don't allow writing ioctl on lower layer 2017-09-05 12:53:12 +02:00
pipe.c pipe: fix off-by-one error when checking buffer limits 2018-02-16 20:23:05 +01:00
pnode.c
pnode.h
posix_acl.c
proc_namespace.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
read_write.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
readdir.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
select.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
seq_file.c seq_file: fix incomplete reset on read from zero offset 2018-02-22 15:42:28 +01:00
signalfd.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
splice.c fs: move kernel_write to fs/read_write.c 2017-09-04 19:05:15 -04:00
stack.c
stat.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
statfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
super.c fs: don't scan the inode cache before SB_BORN is set 2018-05-30 07:51:47 +02:00
sync.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
timerfd.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
userfaultfd.c userfaultfd: clear the vma->vm_userfaultfd_ctx if UFFD_EVENT_FORK fails 2018-01-10 09:31:17 +01:00
utimes.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xattr.c lsm: fix smack_inode_removexattr and xattr_getsecurity memleak 2017-10-04 18:03:15 +11:00