linux/fs/btrfs
Wang Xiaoguang 47b5d64691 btrfs: fix false enospc error when truncating heavily reflinked file
Below test script can reveal this bug:
    dd if=/dev/zero of=fs.img bs=$((1024*1024)) count=100
    dev=$(losetup --show -f fs.img)
    mkdir -p /mnt/mntpoint
    mkfs.btrfs  -f $dev
    mount $dev /mnt/mntpoint
    cd /mnt/mntpoint

    echo "workdir is: /mnt/mntpoint"
    blocksize=$((128 * 1024))
    dd if=/dev/zero of=testfile bs=$blocksize count=1
    sync
    count=$((17*1024*1024*1024/blocksize))
    echo "file size is:" $((count*blocksize))
    for ((i = 1; i <= $count; i++)); do
        dst_offset=$((blocksize * i))
        xfs_io -f -c "reflink testfile 0 $dst_offset $blocksize"\
                testfile > /dev/null
    done
    sync
    truncate --size 0 testfile

The last truncate operation will fail for ENOSPC reason, but indeed
it should not fail.

In btrfs_truncate(), we use a temporary block_rsv to do truncate
operation. With every btrfs_truncate_inode_items() call, we migrate space
to this block_rsv, but forget to cleanup previous reservation, which
will make this block_rsv's reserved bytes keep growing, and this reserved
space will only be released in the end of btrfs_truncate(), this metadata
leak will impact other's metadata reservation. In this case, it's
"btrfs_start_transaction(root, 2);" fails for enospc error, which make
this truncate operation fail.

Call btrfs_block_rsv_release() to fix this bug.

Signed-off-by: Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2017-01-19 18:00:58 +01:00
..
tests btrfs: pull node/sector/stripe sizes out of root and into fs_info 2016-12-06 16:06:58 +01:00
acl.c posix_acl: Clear SGID bit when setting file permissions 2016-09-22 10:55:32 +02:00
async-thread.c btrfs: fix crash when tracepoint arguments are freed by wq callbacks 2017-01-09 11:24:50 +01:00
async-thread.h btrfs: limit async_work allocation and worker func duration 2016-12-13 11:01:30 -08:00
backref.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
backref.h
btrfs_inode.h Btrfs: add a flags field to btrfs_fs_info 2016-09-26 17:59:49 +02:00
check-integrity.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
check-integrity.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
compression.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
compression.h btrfs: use bio iterators for the decompression handlers 2016-11-30 13:45:19 +01:00
ctree.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
ctree.h Btrfs: don't WARN() in btrfs_transaction_abort() for IO errors 2016-12-09 06:00:28 -08:00
dedupe.h btrfs: expand cow_file_range() to support in-band dedup and subpage-blocksize 2016-07-26 13:52:25 +02:00
delayed-inode.c btrfs: limit async_work allocation and worker func duration 2016-12-13 11:01:30 -08:00
delayed-inode.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
delayed-ref.c btrfs: improve delayed refs iterations 2016-11-30 13:45:21 +01:00
delayed-ref.h Merge branch 'for-chris-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.10 2016-12-13 09:14:42 -08:00
dev-replace.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
dev-replace.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
dir-item.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
disk-io.c Merge branch 'for-chris-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.10 2016-12-13 09:14:42 -08:00
disk-io.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
export.c btrfs: root->fs_info cleanup, add fs_info convenience variables 2016-12-06 16:06:59 +01:00
export.h
extent_io.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
extent_io.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
extent_map.c btrfs: Fix slab accounting flags 2016-07-26 13:52:25 +02:00
extent_map.h btrfs: cleanup, stop casting for extent_map->lookup everywhere 2016-01-15 19:22:28 +01:00
extent-tree.c Btrfs: use down_read_nested to make lockdep silent 2017-01-03 15:19:17 +01:00
file-item.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
file.c Merge branch 'for-chris-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.10 2016-12-13 09:14:42 -08:00
free-space-cache.c btrfs: opencode chunk locking, remove helpers 2016-12-06 16:07:00 +01:00
free-space-cache.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
free-space-tree.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
free-space-tree.h Btrfs: implement the free space B-tree 2015-12-17 12:16:47 -08:00
hash.c btrfs: advertise which crc32c implementation is being used at module load 2016-06-06 14:08:28 +02:00
hash.h btrfs: advertise which crc32c implementation is being used at module load 2016-06-06 14:08:28 +02:00
inode-item.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
inode-map.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
inode-map.h Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots 2016-01-15 19:25:02 +01:00
inode.c btrfs: fix false enospc error when truncating heavily reflinked file 2017-01-19 18:00:58 +01:00
ioctl.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
Kconfig
locking.c btrfs: cleanup, remove stray return statements 2016-01-07 14:30:52 +01:00
locking.h
lzo.c btrfs: use bio iterators for the decompression handlers 2016-11-30 13:45:19 +01:00
Makefile Btrfs: add free space tree sanity tests 2015-12-17 12:16:47 -08:00
math.h
ordered-data.c btrfs: root->fs_info cleanup, add fs_info convenience variables 2016-12-06 16:06:59 +01:00
ordered-data.h btrfs: pull node/sector/stripe sizes out of root and into fs_info 2016-12-06 16:06:58 +01:00
orphan.c
print-tree.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
print-tree.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
props.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
props.h
qgroup.c Merge branch 'for-chris-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.10 2016-12-13 09:14:42 -08:00
qgroup.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
raid56.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
raid56.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
rcu-string.h
reada.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
relocation.c Merge branch 'for-chris-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.10 2016-12-13 09:14:42 -08:00
root-tree.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
scrub.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
send.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
send.h Btrfs: use linux/sizes.h to represent constants 2016-01-07 14:38:02 +01:00
struct-funcs.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
super.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
sysfs.c btrfs: convert printk(KERN_* to use pr_* calls 2016-09-26 18:08:44 +02:00
sysfs.h btrfs: sysfs: introduce helper for syncing bits with sysfs files 2016-01-21 18:50:40 +01:00
transaction.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
transaction.h btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
tree-defrag.c Btrfs: fix locking bugs when defragging leaves 2015-12-18 02:51:32 +00:00
tree-log.c Btrfs: fix lockdep warning about log_mutex 2017-01-03 15:19:28 +01:00
tree-log.h Btrfs: fix lockdep warning on deadlock against an inode's log mutex 2016-08-25 03:58:32 -07:00
ulist.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
ulist.h
uuid-tree.c btrfs: return the actual error value from from btrfs_uuid_tree_iterate 2016-12-19 18:08:15 +01:00
volumes.c btrfs: opencode chunk locking, remove helpers 2016-12-06 16:07:00 +01:00
volumes.h btrfs: opencode chunk locking, remove helpers 2016-12-06 16:07:00 +01:00
xattr.c btrfs: remove root parameter from transaction commit/end routines 2016-12-06 16:07:00 +01:00
xattr.h btrfs: Switch to generic xattr handlers 2016-05-17 19:17:09 -04:00
zlib.c btrfs: use bio iterators for the decompression handlers 2016-11-30 13:45:19 +01:00