Skip to content

Commit 4973ca2

Browse files
committed
Merge tag 'for-6.4-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Two fixes for NOCOW files, a regression fix in scrub and an assertion fix: - NOCOW fixes: - keep length of iomap direct io request in case of a failure - properly pass mode of extent reference checking, this can break some cases for swapfile - fix error value confusion when scrubbing a stripe - convert assertion to a proper error handling when loading global roots, reported by syzbot" * tag 'for-6.4-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: scrub: fix a return value overwrite in scrub_stripe() btrfs: do not ASSERT() on duplicated global roots btrfs: can_nocow_file_extent should pass down args->strict from callers btrfs: fix iomap_begin length for nocow writes
2 parents b9c1133 + b50f2d0 commit 4973ca2

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

fs/btrfs/disk-io.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -996,13 +996,18 @@ int btrfs_global_root_insert(struct btrfs_root *root)
996996
{
997997
struct btrfs_fs_info *fs_info = root->fs_info;
998998
struct rb_node *tmp;
999+
int ret = 0;
9991000

10001001
write_lock(&fs_info->global_root_lock);
10011002
tmp = rb_find_add(&root->rb_node, &fs_info->global_root_tree, global_root_cmp);
10021003
write_unlock(&fs_info->global_root_lock);
1003-
ASSERT(!tmp);
10041004

1005-
return tmp ? -EEXIST : 0;
1005+
if (tmp) {
1006+
ret = -EEXIST;
1007+
btrfs_warn(fs_info, "global root %llu %llu already exists",
1008+
root->root_key.objectid, root->root_key.offset);
1009+
}
1010+
return ret;
10061011
}
10071012

10081013
void btrfs_global_root_delete(struct btrfs_root *root)
@@ -2842,6 +2847,7 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
28422847
/* We can't trust the free space cache either */
28432848
btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE);
28442849

2850+
btrfs_warn(fs_info, "try to load backup roots slot %d", i);
28452851
ret = read_backup_root(fs_info, i);
28462852
backup_index = ret;
28472853
if (ret < 0)

fs/btrfs/inode.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,7 @@ static int can_nocow_file_extent(struct btrfs_path *path,
18641864

18651865
ret = btrfs_cross_ref_exist(root, btrfs_ino(inode),
18661866
key->offset - args->extent_offset,
1867-
args->disk_bytenr, false, path);
1867+
args->disk_bytenr, args->strict, path);
18681868
WARN_ON_ONCE(ret > 0 && is_freespace_inode);
18691869
if (ret != 0)
18701870
goto out;
@@ -7264,7 +7264,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
72647264
static int btrfs_get_blocks_direct_write(struct extent_map **map,
72657265
struct inode *inode,
72667266
struct btrfs_dio_data *dio_data,
7267-
u64 start, u64 len,
7267+
u64 start, u64 *lenp,
72687268
unsigned int iomap_flags)
72697269
{
72707270
const bool nowait = (iomap_flags & IOMAP_NOWAIT);
@@ -7275,6 +7275,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
72757275
struct btrfs_block_group *bg;
72767276
bool can_nocow = false;
72777277
bool space_reserved = false;
7278+
u64 len = *lenp;
72787279
u64 prev_len;
72797280
int ret = 0;
72807281

@@ -7345,15 +7346,19 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
73457346
free_extent_map(em);
73467347
*map = NULL;
73477348

7348-
if (nowait)
7349-
return -EAGAIN;
7349+
if (nowait) {
7350+
ret = -EAGAIN;
7351+
goto out;
7352+
}
73507353

73517354
/*
73527355
* If we could not allocate data space before locking the file
73537356
* range and we can't do a NOCOW write, then we have to fail.
73547357
*/
7355-
if (!dio_data->data_space_reserved)
7356-
return -ENOSPC;
7358+
if (!dio_data->data_space_reserved) {
7359+
ret = -ENOSPC;
7360+
goto out;
7361+
}
73577362

73587363
/*
73597364
* We have to COW and we have already reserved data space before,
@@ -7394,6 +7399,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
73947399
btrfs_delalloc_release_extents(BTRFS_I(inode), len);
73957400
btrfs_delalloc_release_metadata(BTRFS_I(inode), len, true);
73967401
}
7402+
*lenp = len;
73977403
return ret;
73987404
}
73997405

@@ -7570,7 +7576,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
75707576

75717577
if (write) {
75727578
ret = btrfs_get_blocks_direct_write(&em, inode, dio_data,
7573-
start, len, flags);
7579+
start, &len, flags);
75747580
if (ret < 0)
75757581
goto unlock_err;
75767582
unlock_extents = true;

fs/btrfs/scrub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2266,7 +2266,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
22662266
}
22672267
out:
22682268
ret2 = flush_scrub_stripes(sctx);
2269-
if (!ret2)
2269+
if (!ret)
22702270
ret = ret2;
22712271
if (sctx->raid56_data_stripes) {
22722272
for (int i = 0; i < nr_data_stripes(map); i++)

0 commit comments

Comments
 (0)