linux/fs
Qu Wenruo 40e082b99a btrfs: qgroup: Finish rescan when hit the last leaf of extent tree
[ Upstream commit ff3d27a048 ]

Under the following case, qgroup rescan can double account cowed tree
blocks:

In this case, extent tree only has one tree block.

-
| transid=5 last committed=4
| btrfs_qgroup_rescan_worker()
| |- btrfs_start_transaction()
| |  transid = 5
| |- qgroup_rescan_leaf()
|    |- btrfs_search_slot_for_read() on extent tree
|       Get the only extent tree block from commit root (transid = 4).
|       Scan it, set qgroup_rescan_progress to the last
|       EXTENT/META_ITEM + 1
|       now qgroup_rescan_progress = A + 1.
|
| fs tree get CoWed, new tree block is at A + 16K
| transid 5 get committed
-
| transid=6 last committed=5
| btrfs_qgroup_rescan_worker()
| btrfs_qgroup_rescan_worker()
| |- btrfs_start_transaction()
| |  transid = 5
| |- qgroup_rescan_leaf()
|    |- btrfs_search_slot_for_read() on extent tree
|       Get the only extent tree block from commit root (transid = 5).
|       scan it using qgroup_rescan_progress (A + 1).
|       found new tree block beyong A, and it's fs tree block,
|       account it to increase qgroup numbers.
-

In above case, tree block A, and tree block A + 16K get accounted twice,
while qgroup rescan should stop when it already reach the last leaf,
other than continue using its qgroup_rescan_progress.

Such case could happen by just looping btrfs/017 and with some
possibility it can hit such double qgroup accounting problem.

Fix it by checking the path to determine if we should finish qgroup
rescan, other than relying on next loop to exit.

Reported-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-08-06 16:24:33 +02:00
..
9p fs/9p: Compare qid.path in v9fs_test_inode 2017-11-30 08:37:22 +00:00
adfs
affs affs_lookup(): close a race with affs_remove_link() 2018-05-30 07:48:51 +02:00
afs afs: Fix afs_kill_pages() 2017-12-20 10:04:56 +01:00
autofs4 autofs: mount point create should honour passed in mode 2018-04-24 09:32:11 +02:00
befs
bfs
btrfs btrfs: qgroup: Finish rescan when hit the last leaf of extent tree 2018-08-06 16:24:33 +02:00
cachefiles
ceph ceph: drop negative child dentries before try pruning inode's alias 2017-12-20 10:04:52 +01:00
cifs cifs: Fix infinite loop when using hard mount option 2018-07-11 16:03:48 +02:00
coda coda: fix 'kernel memory exposure attempt' in fsync 2017-11-24 08:32:25 +01:00
configfs configfs: Fix race between create_link and configfs_rmdir 2017-06-26 07:13:08 +02:00
cramfs
debugfs dentry name snapshots 2017-08-06 19:19:42 -07:00
devpts devpts: clean up interface to pty drivers 2016-08-16 09:30:49 +02:00
dlm dlm: avoid double-free on error path in dlm_device_{register,unregister} 2017-09-13 14:09:45 -07:00
ecryptfs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
efivarfs efi: Make efivarfs entries immutable by default 2016-03-03 15:07:09 -08:00
efs
exofs osd fs: __r4w_get_page rely on PageUptodate for uptodate 2015-12-12 10:15:34 -08:00
exportfs
ext2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
ext4 ext4: check superblock mapped prior to committing 2018-07-11 16:03:49 +02:00
f2fs f2fs: fix to don't trigger writeback during recovery 2018-08-06 16:24:31 +02:00
fat fat: fix memory allocation failure handling of match_strdup() 2018-07-25 10:18:15 +02:00
freevxfs
fscache fscache: Fix hanging wait on page discarded by writeback 2018-05-30 07:49:08 +02:00
fuse fuse: fix control dir setup and teardown 2018-07-03 11:21:28 +02:00
gfs2 gfs2: Fix fallocate chunk size 2018-05-30 07:49:13 +02:00
hfs
hfsplus hfsplus: stop workqueue when fill_super() failed 2018-05-26 08:49:01 +02:00
hostfs hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common() 2016-09-30 10:18:39 +02:00
hpfs hpfs: implement the show_options method 2016-06-01 12:15:54 -07:00
hugetlbfs mm: larger stack guard gap, between vmas 2017-06-26 07:13:11 +02:00
isofs isofs: fix timestamps beyond 2027 2017-11-30 08:37:20 +00:00
jbd2 jbd2: don't mark block as modified if the handle is out of credits 2018-07-11 16:03:48 +02:00
jffs2 jffs2: Fix use-after-free bug in jffs2_iget()'s error handling path 2018-05-30 07:48:54 +02:00
jfs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
kernfs kernfs: fix regression in kernfs_fop_write caused by wrong type 2018-02-16 20:09:42 +01:00
lockd lockd: lost rollback of set_grace_period() in lockd_down_net() 2018-05-26 08:48:50 +02:00
logfs
minix
ncpfs staging: ncpfs: memory corruption in ncp_read_kernel() 2018-03-28 18:40:15 +02:00
nfs NFSv4: Fix possible 1-byte stack overflow in nfs_idmap_read_and_verify_message 2018-07-03 11:21:34 +02:00
nfs_common lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:04:28 +01:00
nfsd nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo 2018-08-06 16:24:30 +02:00
nilfs2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
nls
notify fanotify: fix logic of events on child 2018-04-24 09:32:11 +02:00
ntfs
ocfs2 ocfs2: subsystem.su_mutex is required while accessing the item->ci_parent 2018-07-22 14:25:52 +02:00
omfs
openpromfs
overlayfs ovl: filter trusted xattr for non-admin 2018-04-13 19:50:14 +02:00
proc proc: Use underscores for SSBD in 'status' 2018-07-25 10:18:28 +02:00
pstore pstore: Use dynamic spinlock initializer 2017-08-06 19:19:43 -07:00
qnx4
qnx6
quota quota: Check for register_shrinker() failure. 2018-02-03 17:04:28 +01:00
ramfs
reiserfs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
romfs romfs: use different way to generate fsid for BLOCK or MTD 2017-06-17 06:39:38 +02:00
squashfs
sysfs sysfs: be careful of error returns from ops->show() 2017-04-12 12:38:33 +02:00
sysv
tracefs
ubifs UBIFS: Fix potential integer overflow in allocation 2018-07-03 11:21:32 +02:00
udf udf: Detect incorrect directory size 2018-07-03 11:21:34 +02:00
ufs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
xfs xfs: fix incorrect log_flushed on fsync 2018-06-13 16:15:27 +02:00
aio.c fix io_destroy()/aio_complete() race 2018-06-06 16:46:23 +02:00
anon_inodes.c
attr.c vfs: move permission checking into notify_change() for utimes(NULL) 2016-10-22 12:26:56 +02:00
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c
binfmt_elf.c binfmt_elf: use ELF_ET_DYN_BASE only for PIE 2017-07-21 07:44:57 +02:00
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c fs/binfmt_misc.c: do not allow offset overflow 2018-07-03 11:21:26 +02:00
binfmt_script.c
block_dev.c fs/block_dev: always invalidate cleancache in invalidate_bdev() 2017-05-20 14:27:01 +02:00
buffer.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
char_dev.c
compat_binfmt_elf.c binfmt_elf: compat: avoid unused function warning 2018-02-25 11:03:51 +01:00
compat_ioctl.c fs: compat: Remove warning from COMPATIBLE_IOCTL 2018-04-08 11:51:57 +02:00
compat.c
coredump.c coredump: Ensure proper size of sparse core files 2017-07-05 14:37:20 +02:00
dax.c
dcache.c do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
dcookies.c
direct-io.c direct-io: Prevent NULL pointer access in submit_page_section 2017-10-18 09:20:42 +02:00
drop_caches.c
eventfd.c
eventpoll.c epoll: fix race between ep_poll_callback(POLLFREE) and ep_free()/ep_remove() 2017-09-07 08:34:10 +02:00
exec.c exec: Limit arg stack to at most 75% of _STK_LIM 2017-07-21 07:44:57 +02:00
fcntl.c fs/fcntl: f_setown, avoid undefined behaviour 2018-01-31 12:06:11 +01:00
fhandle.c fs/coredump: prevent fsuid=0 dumps into user-controlled directories 2016-04-12 09:08:58 -07:00
file_table.c
file.c
filesystems.c
fs_pin.c
fs_struct.c
fs-writeback.c bdi: Fix oops in wb_workfn() 2018-05-16 10:06:51 +02:00
inode.c Fix up non-directory creation in SGID directories 2018-07-17 11:31:43 +02:00
internal.h
ioctl.c
Kconfig
Kconfig.binfmt
libfs.c
locks.c locks: don't check for race with close when setting OFD lock 2018-01-17 09:35:27 +01:00
Makefile
mbcache.c
mount.h mnt: In propgate_umount handle visiting mounts in any order 2017-07-21 07:44:57 +02:00
mpage.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
namei.c getname_kernel() needs to make sure that ->name != ->iname in long case 2018-04-24 09:32:04 +02:00
namespace.c Don't leak MNT_INTERNAL away from internal mounts 2018-04-24 09:32:11 +02:00
no-block.c
nsfs.c nsfs: mark dentry with DCACHE_RCUACCESS 2018-02-16 20:09:43 +01:00
open.c fs: completely ignore unknown open flags 2017-07-15 11:57:44 +02:00
pipe.c pipe: cap initial pipe capacity according to pipe-max-size limit 2018-05-26 08:48:51 +02:00
pnode.c mnt: Make propagate_umount less slow for overlapping mount propagation trees 2017-07-21 07:44:58 +02:00
pnode.h mnt: Add a per mount namespace limit on the number of mounts 2017-04-30 05:49:28 +02:00
posix_acl.c tmpfs: clear S_ISGID when setting posix ACLs 2017-01-26 08:23:47 +01:00
proc_namespace.c vfs: show_vfsstat: do not ignore errors from show_devname method 2016-04-12 09:08:55 -07:00
read_write.c vfs: Return -ENXIO for negative SEEK_HOLE / SEEK_DATA offsets 2017-10-05 09:41:45 +02:00
readdir.c
select.c fs/select: add vmalloc fallback for select(2) 2018-01-31 12:06:09 +01:00
seq_file.c Make file credentials available to the seqfile interfaces 2017-08-06 19:19:42 -07:00
signalfd.c
splice.c vfs: fix uninitialized flags in splice_to_pipe() 2017-02-23 17:43:09 +01:00
stack.c
stat.c ufs: restore maintaining ->i_blocks 2017-06-14 13:16:24 +02:00
statfs.c
super.c sget(): handle failures of register_shrinker() 2018-03-03 10:19:41 +01:00
sync.c
timerfd.c timerfd: Protect the might cancel mechanism proper 2017-05-08 07:46:01 +02:00
userfaultfd.c userfaultfd: shmem: __do_fault requires VM_FAULT_NOPAGE 2017-12-20 10:04:53 +01:00
utimes.c vfs: move permission checking into notify_change() for utimes(NULL) 2016-10-22 12:26:56 +02:00
xattr.c lsm: fix smack_inode_removexattr and xattr_getsecurity memleak 2017-10-12 11:27:32 +02:00