From: Greg Kroah-Hartman Date: Thu, 17 Nov 2016 09:45:10 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.33~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3566c5222cac046dbc24a92dfd0247de2d4d8e24;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: btrfs-qgroup-prevent-qgroup-reserved-from-going-subzero.patch --- diff --git a/queue-4.4/btrfs-qgroup-prevent-qgroup-reserved-from-going-subzero.patch b/queue-4.4/btrfs-qgroup-prevent-qgroup-reserved-from-going-subzero.patch new file mode 100644 index 00000000000..c2a3935a772 --- /dev/null +++ b/queue-4.4/btrfs-qgroup-prevent-qgroup-reserved-from-going-subzero.patch @@ -0,0 +1,69 @@ +From 0b34c261e235a5c74dcf78bd305845bd15fe2b42 Mon Sep 17 00:00:00 2001 +From: Goldwyn Rodrigues +Date: Fri, 30 Sep 2016 10:40:52 -0500 +Subject: btrfs: qgroup: Prevent qgroup->reserved from going subzero + +From: Goldwyn Rodrigues + +commit 0b34c261e235a5c74dcf78bd305845bd15fe2b42 upstream. + +While free'ing qgroup->reserved resources, we much check if +the page has not been invalidated by a truncate operation +by checking if the page is still dirty before reducing the +qgroup resources. Resources in such a case are free'd when +the entire extent is released by delayed_ref. + +This fixes a double accounting while releasing resources +in case of truncating a file, reproduced by the following testcase. + +SCRATCH_DEV=/dev/vdb +SCRATCH_MNT=/mnt +mkfs.btrfs -f $SCRATCH_DEV +mount -t btrfs $SCRATCH_DEV $SCRATCH_MNT +cd $SCRATCH_MNT +btrfs quota enable $SCRATCH_MNT +btrfs subvolume create a +btrfs qgroup limit 500m a $SCRATCH_MNT +sync +for c in {1..15}; do +dd if=/dev/zero bs=1M count=40 of=$SCRATCH_MNT/a/file; +done + +sleep 10 +sync +sleep 5 + +touch $SCRATCH_MNT/a/newfile + +echo "Removing file" +rm $SCRATCH_MNT/a/file + +Fixes: b9d0b38928 ("btrfs: Add handler for invalidate page") +Signed-off-by: Goldwyn Rodrigues +Reviewed-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -8691,9 +8691,14 @@ static void btrfs_invalidatepage(struct + * So even we call qgroup_free_data(), it won't decrease reserved + * space. + * 2) Not written to disk +- * This means the reserved space should be freed here. ++ * This means the reserved space should be freed here. However, ++ * if a truncate invalidates the page (by clearing PageDirty) ++ * and the page is accounted for while allocating extent ++ * in btrfs_check_data_free_space() we let delayed_ref to ++ * free the entire extent. + */ +- btrfs_qgroup_free_data(inode, page_start, PAGE_CACHE_SIZE); ++ if (PageDirty(page)) ++ btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE); + if (!inode_evicting) { + clear_extent_bit(tree, page_start, page_end, + EXTENT_LOCKED | EXTENT_DIRTY | diff --git a/queue-4.4/series b/queue-4.4/series index 24239aac666..d66bdf95133 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -34,3 +34,4 @@ i40e-fix-call-of-ndo_dflt_bridge_getlink.patch acpi-apei-fix-incorrect-return-value-of-ghes_proc.patch asoc-sun4i-codec-return-error-code-instead-of-null-when-create_card-fails.patch mmc-mxs-initialize-the-spinlock-prior-to-using-it.patch +btrfs-qgroup-prevent-qgroup-reserved-from-going-subzero.patch