Skip to content

Commit f09b04c

Browse files
committed
Merge tag 'for-5.12-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "More regression fixes and stabilization. Regressions: - zoned mode - count zone sizes in wider int types - fix space accounting for read-only block groups - subpage: fix page tail zeroing Fixes: - fix spurious warning when remounting with free space tree - fix warning when creating a directory with smack enabled - ioctl checks for qgroup inheritance when creating a snapshot - qgroup - fix missing unlock on error path in zero range - fix amount of released reservation on error - fix flushing from unsafe context with open transaction, potentially deadlocking - minor build warning fixes" * tag 'for-5.12-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: zoned: do not account freed region of read-only block group as zone_unusable btrfs: zoned: use sector_t for zone sectors btrfs: subpage: fix the false data csum mismatch error btrfs: fix warning when creating a directory with smack enabled btrfs: don't flush from btrfs_delayed_inode_reserve_metadata btrfs: export and rename qgroup_reserve_meta btrfs: free correct amount of space in btrfs_delayed_inode_reserve_metadata btrfs: fix spurious free_space_tree remount warning btrfs: validate qgroup inherit for SNAP_CREATE_V2 ioctl btrfs: unlock extents in btrfs_zero_range in case of quota reservation errors btrfs: ref-verify: use 'inline void' keyword ordering
2 parents 6bf331d + badae9c commit f09b04c

File tree

12 files changed

+87
-25
lines changed

12 files changed

+87
-25
lines changed

fs/btrfs/delayed-inode.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ static int btrfs_delayed_inode_reserve_metadata(
627627
*/
628628
if (!src_rsv || (!trans->bytes_reserved &&
629629
src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
630-
ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true);
630+
ret = btrfs_qgroup_reserve_meta(root, num_bytes,
631+
BTRFS_QGROUP_RSV_META_PREALLOC, true);
631632
if (ret < 0)
632633
return ret;
633634
ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
@@ -649,7 +650,7 @@ static int btrfs_delayed_inode_reserve_metadata(
649650
btrfs_ino(inode),
650651
num_bytes, 1);
651652
} else {
652-
btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize);
653+
btrfs_qgroup_free_meta_prealloc(root, num_bytes);
653654
}
654655
return ret;
655656
}

fs/btrfs/extent_io.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3008,12 +3008,23 @@ static void end_bio_extent_readpage(struct bio *bio)
30083008
if (likely(uptodate)) {
30093009
loff_t i_size = i_size_read(inode);
30103010
pgoff_t end_index = i_size >> PAGE_SHIFT;
3011-
unsigned off;
30123011

3013-
/* Zero out the end if this page straddles i_size */
3014-
off = offset_in_page(i_size);
3015-
if (page->index == end_index && off)
3016-
zero_user_segment(page, off, PAGE_SIZE);
3012+
/*
3013+
* Zero out the remaining part if this range straddles
3014+
* i_size.
3015+
*
3016+
* Here we should only zero the range inside the bvec,
3017+
* not touch anything else.
3018+
*
3019+
* NOTE: i_size is exclusive while end is inclusive.
3020+
*/
3021+
if (page->index == end_index && i_size <= end) {
3022+
u32 zero_start = max(offset_in_page(i_size),
3023+
offset_in_page(end));
3024+
3025+
zero_user_segment(page, zero_start,
3026+
offset_in_page(end) + 1);
3027+
}
30173028
}
30183029
ASSERT(bio_offset + len > bio_offset);
30193030
bio_offset += len;

fs/btrfs/file.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3260,8 +3260,11 @@ static int btrfs_zero_range(struct inode *inode,
32603260
goto out;
32613261
ret = btrfs_qgroup_reserve_data(BTRFS_I(inode), &data_reserved,
32623262
alloc_start, bytes_to_reserve);
3263-
if (ret)
3263+
if (ret) {
3264+
unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart,
3265+
lockend, &cached_state);
32643266
goto out;
3267+
}
32653268
ret = btrfs_prealloc_file_range(inode, mode, alloc_start,
32663269
alloc_end - alloc_start,
32673270
i_blocksize(inode),

fs/btrfs/free-space-cache.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,12 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
25552555
to_unusable = size - to_free;
25562556

25572557
ctl->free_space += to_free;
2558-
block_group->zone_unusable += to_unusable;
2558+
/*
2559+
* If the block group is read-only, we should account freed space into
2560+
* bytes_readonly.
2561+
*/
2562+
if (!block_group->ro)
2563+
block_group->zone_unusable += to_unusable;
25592564
spin_unlock(&ctl->tree_lock);
25602565
if (!used) {
25612566
spin_lock(&block_group->lock);

fs/btrfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6083,7 +6083,7 @@ static int btrfs_dirty_inode(struct inode *inode)
60836083
return PTR_ERR(trans);
60846084

60856085
ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
6086-
if (ret && ret == -ENOSPC) {
6086+
if (ret && (ret == -ENOSPC || ret == -EDQUOT)) {
60876087
/* whoops, lets try again with the full transaction */
60886088
btrfs_end_transaction(trans);
60896089
trans = btrfs_start_transaction(root, 1);

fs/btrfs/ioctl.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1936,7 +1936,10 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
19361936
if (vol_args->flags & BTRFS_SUBVOL_RDONLY)
19371937
readonly = true;
19381938
if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
1939-
if (vol_args->size > PAGE_SIZE) {
1939+
u64 nums;
1940+
1941+
if (vol_args->size < sizeof(*inherit) ||
1942+
vol_args->size > PAGE_SIZE) {
19401943
ret = -EINVAL;
19411944
goto free_args;
19421945
}
@@ -1945,6 +1948,20 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
19451948
ret = PTR_ERR(inherit);
19461949
goto free_args;
19471950
}
1951+
1952+
if (inherit->num_qgroups > PAGE_SIZE ||
1953+
inherit->num_ref_copies > PAGE_SIZE ||
1954+
inherit->num_excl_copies > PAGE_SIZE) {
1955+
ret = -EINVAL;
1956+
goto free_inherit;
1957+
}
1958+
1959+
nums = inherit->num_qgroups + 2 * inherit->num_ref_copies +
1960+
2 * inherit->num_excl_copies;
1961+
if (vol_args->size != struct_size(inherit, qgroups, nums)) {
1962+
ret = -EINVAL;
1963+
goto free_inherit;
1964+
}
19481965
}
19491966

19501967
ret = __btrfs_ioctl_snap_create(file, vol_args->name, vol_args->fd,

fs/btrfs/qgroup.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3841,8 +3841,8 @@ static int sub_root_meta_rsv(struct btrfs_root *root, int num_bytes,
38413841
return num_bytes;
38423842
}
38433843

3844-
static int qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
3845-
enum btrfs_qgroup_rsv_type type, bool enforce)
3844+
int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
3845+
enum btrfs_qgroup_rsv_type type, bool enforce)
38463846
{
38473847
struct btrfs_fs_info *fs_info = root->fs_info;
38483848
int ret;
@@ -3873,14 +3873,14 @@ int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
38733873
{
38743874
int ret;
38753875

3876-
ret = qgroup_reserve_meta(root, num_bytes, type, enforce);
3876+
ret = btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce);
38773877
if (ret <= 0 && ret != -EDQUOT)
38783878
return ret;
38793879

38803880
ret = try_flush_qgroup(root);
38813881
if (ret < 0)
38823882
return ret;
3883-
return qgroup_reserve_meta(root, num_bytes, type, enforce);
3883+
return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce);
38843884
}
38853885

38863886
void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root)

fs/btrfs/qgroup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,8 @@ int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len);
361361
int btrfs_qgroup_free_data(struct btrfs_inode *inode,
362362
struct extent_changeset *reserved, u64 start,
363363
u64 len);
364+
int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
365+
enum btrfs_qgroup_rsv_type type, bool enforce);
364366
int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
365367
enum btrfs_qgroup_rsv_type type, bool enforce);
366368
/* Reserve metadata space for pertrans and prealloc type */

fs/btrfs/ref-verify.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ static void __print_stack_trace(struct btrfs_fs_info *fs_info,
218218
stack_trace_print(ra->trace, ra->trace_len, 2);
219219
}
220220
#else
221-
static void inline __save_stack_trace(struct ref_action *ra)
221+
static inline void __save_stack_trace(struct ref_action *ra)
222222
{
223223
}
224224

225-
static void inline __print_stack_trace(struct btrfs_fs_info *fs_info,
225+
static inline void __print_stack_trace(struct btrfs_fs_info *fs_info,
226226
struct ref_action *ra)
227227
{
228228
btrfs_err(fs_info, " ref-verify: no stacktrace support");

fs/btrfs/super.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,8 +1918,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
19181918
btrfs_resize_thread_pool(fs_info,
19191919
fs_info->thread_pool_size, old_thread_pool_size);
19201920

1921-
if (btrfs_test_opt(fs_info, FREE_SPACE_TREE) !=
1922-
btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
1921+
if ((bool)btrfs_test_opt(fs_info, FREE_SPACE_TREE) !=
1922+
(bool)btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
19231923
(!sb_rdonly(sb) || (*flags & SB_RDONLY))) {
19241924
btrfs_warn(fs_info,
19251925
"remount supports changing free space tree only from ro to rw");

0 commit comments

Comments
 (0)