From 4da2e26a2a32b174878744bd0f07db180c875f26 Mon Sep 17 00:00:00 2001 From: Zhao Lei Date: Wed, 6 Jan 2016 18:24:43 +0800 Subject: btrfs: Continue write in case of can_not_nocow btrfs failed in xfstests btrfs/080 with -o nodatacow. Can be reproduced by following script: DEV=/dev/vdg MNT=/mnt/tmp umount $DEV &>/dev/null mkfs.btrfs -f $DEV mount -o nodatacow $DEV $MNT dd if=/dev/zero of=$MNT/test bs=1 count=2048 & btrfs subvolume snapshot -r $MNT $MNT/test_snap & wait -- We can see dd failed on NO_SPACE. Reason: __btrfs_buffered_write should run cow write when no_cow impossible, and current code is designed with above logic. But check_can_nocow() have 2 type of return value(0 and <0) on can_not_no_cow, and current code only continue write on first case, the second case happened in doing subvolume. Fix: Continue write when check_can_nocow() return 0 and <0. Reviewed-by: Filipe Manana Signed-off-by: Zhao Lei --- fs/btrfs/file.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'fs') diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 098bb8f690c9..cadfebaaf8c4 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1525,27 +1525,24 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, reserve_bytes = num_pages << PAGE_CACHE_SHIFT; - if (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | - BTRFS_INODE_PREALLOC)) { - ret = check_can_nocow(inode, pos, &write_bytes); - if (ret < 0) - break; - if (ret > 0) { - /* - * For nodata cow case, no need to reserve - * data space. - */ - only_release_metadata = true; - /* - * our prealloc extent may be smaller than - * write_bytes, so scale down. - */ - num_pages = DIV_ROUND_UP(write_bytes + offset, - PAGE_CACHE_SIZE); - reserve_bytes = num_pages << PAGE_CACHE_SHIFT; - goto reserve_metadata; - } + if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | + BTRFS_INODE_PREALLOC)) && + check_can_nocow(inode, pos, &write_bytes) > 0) { + /* + * For nodata cow case, no need to reserve + * data space. + */ + only_release_metadata = true; + /* + * our prealloc extent may be smaller than + * write_bytes, so scale down. + */ + num_pages = DIV_ROUND_UP(write_bytes + offset, + PAGE_CACHE_SIZE); + reserve_bytes = num_pages << PAGE_CACHE_SHIFT; + goto reserve_metadata; } + ret = btrfs_check_data_free_space(inode, pos, write_bytes); if (ret < 0) break; -- cgit v1.2.3-55-g7522 From aa66b0bb08869d93492bd817d2eae694ca743a3d Mon Sep 17 00:00:00 2001 From: Kinglong Mee Date: Fri, 29 Jan 2016 21:36:00 +0800 Subject: btrfs: fix memory leak of fs_info in block group cache When starting up linux with btrfs filesystem, I got many memory leak messages by kmemleak as, unreferenced object 0xffff880066882000 (size 4096): comm "modprobe", pid 730, jiffies 4294690024 (age 196.599s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] kmemleak_alloc+0x4e/0xb0 [] kmem_cache_alloc_trace+0xea/0x1e0 [] btrfs_alloc_dummy_fs_info+0x6b/0x2a0 [btrfs] [] btrfs_alloc_dummy_block_group+0x5c/0x120 [btrfs] [] btrfs_test_free_space_cache+0x39/0xed0 [btrfs] [] trace_raw_output_xfs_attr_class+0x54/0xe0 [xfs] [] do_one_initcall+0xb2/0x1f0 [] do_init_module+0x5e/0x1e9 [] load_module+0x20a9/0x2690 [] SyS_finit_module+0xb9/0xf0 [] entry_SYSCALL_64_fastpath+0x12/0x76 [] 0xffffffffffffffff unreferenced object 0xffff8800573f8000 (size 10256): comm "modprobe", pid 730, jiffies 4294690185 (age 196.460s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] kmemleak_alloc+0x4e/0xb0 [] kmalloc_order+0x5e/0x70 [] kmalloc_order_trace+0x24/0x90 [] btrfs_alloc_dummy_fs_info+0x23/0x2a0 [btrfs] [] btrfs_alloc_dummy_block_group+0x5c/0x120 [btrfs] [] run_test+0xfd/0x320 [btrfs] [] btrfs_test_free_space_tree+0x94/0xee [btrfs] [] trace_raw_output_xfs_attr_class+0x8b/0xe0 [xfs] [] do_one_initcall+0xb2/0x1f0 [] do_init_module+0x5e/0x1e9 [] load_module+0x20a9/0x2690 [] SyS_finit_module+0xb9/0xf0 [] entry_SYSCALL_64_fastpath+0x12/0x76 [] 0xffffffffffffffff This patch lets btrfs using fs_info stored in btrfs_root for block group cache directly without allocating a new one. Fixes: d0bd456074 ("Btrfs: add fragment=* debug mount option") Signed-off-by: Kinglong Mee Signed-off-by: David Sterba --- fs/btrfs/tests/btrfs-tests.c | 6 ------ fs/btrfs/tests/free-space-tree-tests.c | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index 0e1e61a7ec23..d39f714dabeb 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c @@ -189,12 +189,6 @@ btrfs_alloc_dummy_block_group(unsigned long length) kfree(cache); return NULL; } - cache->fs_info = btrfs_alloc_dummy_fs_info(); - if (!cache->fs_info) { - kfree(cache->free_space_ctl); - kfree(cache); - return NULL; - } cache->key.objectid = 0; cache->key.offset = length; diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c index d05fe1ab4808..7cea4462acd5 100644 --- a/fs/btrfs/tests/free-space-tree-tests.c +++ b/fs/btrfs/tests/free-space-tree-tests.c @@ -485,6 +485,7 @@ static int run_test(test_func_t test_func, int bitmaps) cache->bitmap_low_thresh = 0; cache->bitmap_high_thresh = (u32)-1; cache->needs_free_space = 1; + cache->fs_info = root->fs_info; btrfs_init_dummy_trans(&trans); -- cgit v1.2.3-55-g7522 From 11ea474f74709fc764fb7e80306e0776f94ce8b8 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 11 Feb 2016 15:30:07 +0100 Subject: btrfs: remove error message from search ioctl for nonexistent tree Let's remove the error message that appears when the tree_id is not present. This can happen with the quota tree and has been observed in practice. The applications are supposed to handle -ENOENT and we don't need to report that in the system log as it's not a fatal error. Reported-by: Vlastimil Babka Signed-off-by: David Sterba --- fs/btrfs/ioctl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs') diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 952172ca7e45..ab390c7958f5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -2097,8 +2097,6 @@ static noinline int search_ioctl(struct inode *inode, key.offset = (u64)-1; root = btrfs_read_fs_root_no_name(info, &key); if (IS_ERR(root)) { - btrfs_err(info, "could not find root %llu", - sk->tree_id); btrfs_free_path(path); return -ENOENT; } -- cgit v1.2.3-55-g7522 From f7e98a7fff8634ae655c666dc2c9fc55a48d0a73 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 8 Oct 2015 14:14:16 +0200 Subject: btrfs: change max_inline default to 2048 The current practical default is ~4k on x86_64 (the logic is more complex, simplified for brevity), the inlined files land in the metadata group and thus consume space that could be needed for the real metadata. The inlining brings some usability surprises: 1) total space consumption measured on various filesystems and btrfs with DUP metadata was quite visible because of the duplicated data within metadata 2) inlined data may exhaust the metadata, which are more precious in case the entire device space is allocated to chunks (ie. balance cannot make the space more compact) 3) performance suffers a bit as the inlined blocks are duplicate and stored far away on the device. Proposed fix: set the default to 2048 This fixes namely 1), the total filesysystem space consumption will be on par with other filesystems. Partially fixes 2), more data are pushed to the data block groups. The characteristics of 3) are based on actual small file size distribution. The change is independent of the metadata blockgroup type (though it's most visible with DUP) or system page size as these parameters are not trival to find out, compared to file size. Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index bfe4a337fb4d..6661ad8b4088 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2252,7 +2252,7 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26) #define BTRFS_DEFAULT_COMMIT_INTERVAL (30) -#define BTRFS_DEFAULT_MAX_INLINE (8192) +#define BTRFS_DEFAULT_MAX_INLINE (2048) #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) -- cgit v1.2.3-55-g7522