Skip to content

Commit 8379c0b

Browse files
committed
Merge tag 'for-6.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Fixes: - check that subvolume is writable when changing xattrs from security namespace - fix memory leak in device lookup helper - update generation of hole file extent item when merging holes - fix space cache corruption and potential double allocations; this is a rare bug but can be serious once it happens, stable backports and analysis tool will be provided - fix error handling when deleting root references - fix crash due to assert when attempting to cancel suspended device replace, add message what to do if mount fails due to missing replace item Regressions: - don't merge pages into bio if their page offset is not contiguous - don't allow large NOWAIT direct reads, this could lead to short reads eg. in io_uring" * tag 'for-6.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: add info when mount fails due to stale replace target btrfs: replace: drop assert for suspended replace btrfs: fix silent failure when deleting root reference btrfs: fix space cache corruption and potential double allocations btrfs: don't allow large NOWAIT direct reads btrfs: don't merge pages into bio if their page offset is not contiguous btrfs: update generation of hole file extent item when merging holes btrfs: fix possible memory leak in btrfs_get_dev_args_from_path() btrfs: check if root is readonly while setting security xattr
2 parents c7bb3fb + f2c3bec commit 8379c0b

File tree

11 files changed

+79
-70
lines changed

11 files changed

+79
-70
lines changed

fs/btrfs/block-group.c

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -440,39 +440,26 @@ void btrfs_wait_block_group_cache_progress(struct btrfs_block_group *cache,
440440
btrfs_put_caching_control(caching_ctl);
441441
}
442442

443-
int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache)
443+
static int btrfs_caching_ctl_wait_done(struct btrfs_block_group *cache,
444+
struct btrfs_caching_control *caching_ctl)
445+
{
446+
wait_event(caching_ctl->wait, btrfs_block_group_done(cache));
447+
return cache->cached == BTRFS_CACHE_ERROR ? -EIO : 0;
448+
}
449+
450+
static int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache)
444451
{
445452
struct btrfs_caching_control *caching_ctl;
446-
int ret = 0;
453+
int ret;
447454

448455
caching_ctl = btrfs_get_caching_control(cache);
449456
if (!caching_ctl)
450457
return (cache->cached == BTRFS_CACHE_ERROR) ? -EIO : 0;
451-
452-
wait_event(caching_ctl->wait, btrfs_block_group_done(cache));
453-
if (cache->cached == BTRFS_CACHE_ERROR)
454-
ret = -EIO;
458+
ret = btrfs_caching_ctl_wait_done(cache, caching_ctl);
455459
btrfs_put_caching_control(caching_ctl);
456460
return ret;
457461
}
458462

459-
static bool space_cache_v1_done(struct btrfs_block_group *cache)
460-
{
461-
bool ret;
462-
463-
spin_lock(&cache->lock);
464-
ret = cache->cached != BTRFS_CACHE_FAST;
465-
spin_unlock(&cache->lock);
466-
467-
return ret;
468-
}
469-
470-
void btrfs_wait_space_cache_v1_finished(struct btrfs_block_group *cache,
471-
struct btrfs_caching_control *caching_ctl)
472-
{
473-
wait_event(caching_ctl->wait, space_cache_v1_done(cache));
474-
}
475-
476463
#ifdef CONFIG_BTRFS_DEBUG
477464
static void fragment_free_space(struct btrfs_block_group *block_group)
478465
{
@@ -750,9 +737,8 @@ static noinline void caching_thread(struct btrfs_work *work)
750737
btrfs_put_block_group(block_group);
751738
}
752739

753-
int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only)
740+
int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait)
754741
{
755-
DEFINE_WAIT(wait);
756742
struct btrfs_fs_info *fs_info = cache->fs_info;
757743
struct btrfs_caching_control *caching_ctl = NULL;
758744
int ret = 0;
@@ -785,10 +771,7 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only
785771
}
786772
WARN_ON(cache->caching_ctl);
787773
cache->caching_ctl = caching_ctl;
788-
if (btrfs_test_opt(fs_info, SPACE_CACHE))
789-
cache->cached = BTRFS_CACHE_FAST;
790-
else
791-
cache->cached = BTRFS_CACHE_STARTED;
774+
cache->cached = BTRFS_CACHE_STARTED;
792775
cache->has_caching_ctl = 1;
793776
spin_unlock(&cache->lock);
794777

@@ -801,8 +784,8 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only
801784

802785
btrfs_queue_work(fs_info->caching_workers, &caching_ctl->work);
803786
out:
804-
if (load_cache_only && caching_ctl)
805-
btrfs_wait_space_cache_v1_finished(cache, caching_ctl);
787+
if (wait && caching_ctl)
788+
ret = btrfs_caching_ctl_wait_done(cache, caching_ctl);
806789
if (caching_ctl)
807790
btrfs_put_caching_control(caching_ctl);
808791

@@ -3312,7 +3295,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
33123295
* space back to the block group, otherwise we will leak space.
33133296
*/
33143297
if (!alloc && !btrfs_block_group_done(cache))
3315-
btrfs_cache_block_group(cache, 1);
3298+
btrfs_cache_block_group(cache, true);
33163299

33173300
byte_in_group = bytenr - cache->start;
33183301
WARN_ON(byte_in_group > cache->length);

fs/btrfs/block-group.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,7 @@ void btrfs_dec_nocow_writers(struct btrfs_block_group *bg);
263263
void btrfs_wait_nocow_writers(struct btrfs_block_group *bg);
264264
void btrfs_wait_block_group_cache_progress(struct btrfs_block_group *cache,
265265
u64 num_bytes);
266-
int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache);
267-
int btrfs_cache_block_group(struct btrfs_block_group *cache,
268-
int load_cache_only);
266+
int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait);
269267
void btrfs_put_caching_control(struct btrfs_caching_control *ctl);
270268
struct btrfs_caching_control *btrfs_get_caching_control(
271269
struct btrfs_block_group *cache);

fs/btrfs/ctree.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,6 @@ struct btrfs_free_cluster {
505505
enum btrfs_caching_type {
506506
BTRFS_CACHE_NO,
507507
BTRFS_CACHE_STARTED,
508-
BTRFS_CACHE_FAST,
509508
BTRFS_CACHE_FINISHED,
510509
BTRFS_CACHE_ERROR,
511510
};

fs/btrfs/dev-replace.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
165165
*/
166166
if (btrfs_find_device(fs_info->fs_devices, &args)) {
167167
btrfs_err(fs_info,
168-
"replace devid present without an active replace item");
168+
"replace without active item, run 'device scan --forget' on the target device");
169169
ret = -EUCLEAN;
170170
} else {
171171
dev_replace->srcdev = NULL;
@@ -1129,8 +1129,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
11291129
up_write(&dev_replace->rwsem);
11301130

11311131
/* Scrub for replace must not be running in suspended state */
1132-
ret = btrfs_scrub_cancel(fs_info);
1133-
ASSERT(ret != -ENOTCONN);
1132+
btrfs_scrub_cancel(fs_info);
11341133

11351134
trans = btrfs_start_transaction(root, 0);
11361135
if (IS_ERR(trans)) {

fs/btrfs/extent-tree.c

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2551,17 +2551,10 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
25512551
return -EINVAL;
25522552

25532553
/*
2554-
* pull in the free space cache (if any) so that our pin
2555-
* removes the free space from the cache. We have load_only set
2556-
* to one because the slow code to read in the free extents does check
2557-
* the pinned extents.
2554+
* Fully cache the free space first so that our pin removes the free space
2555+
* from the cache.
25582556
*/
2559-
btrfs_cache_block_group(cache, 1);
2560-
/*
2561-
* Make sure we wait until the cache is completely built in case it is
2562-
* missing or is invalid and therefore needs to be rebuilt.
2563-
*/
2564-
ret = btrfs_wait_block_group_cache_done(cache);
2557+
ret = btrfs_cache_block_group(cache, true);
25652558
if (ret)
25662559
goto out;
25672560

@@ -2584,12 +2577,7 @@ static int __exclude_logged_extent(struct btrfs_fs_info *fs_info,
25842577
if (!block_group)
25852578
return -EINVAL;
25862579

2587-
btrfs_cache_block_group(block_group, 1);
2588-
/*
2589-
* Make sure we wait until the cache is completely built in case it is
2590-
* missing or is invalid and therefore needs to be rebuilt.
2591-
*/
2592-
ret = btrfs_wait_block_group_cache_done(block_group);
2580+
ret = btrfs_cache_block_group(block_group, true);
25932581
if (ret)
25942582
goto out;
25952583

@@ -4399,7 +4387,7 @@ static noinline int find_free_extent(struct btrfs_root *root,
43994387
ffe_ctl->cached = btrfs_block_group_done(block_group);
44004388
if (unlikely(!ffe_ctl->cached)) {
44014389
ffe_ctl->have_caching_bg = true;
4402-
ret = btrfs_cache_block_group(block_group, 0);
4390+
ret = btrfs_cache_block_group(block_group, false);
44034391

44044392
/*
44054393
* If we get ENOMEM here or something else we want to
@@ -6169,13 +6157,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
61696157

61706158
if (end - start >= range->minlen) {
61716159
if (!btrfs_block_group_done(cache)) {
6172-
ret = btrfs_cache_block_group(cache, 0);
6173-
if (ret) {
6174-
bg_failed++;
6175-
bg_ret = ret;
6176-
continue;
6177-
}
6178-
ret = btrfs_wait_block_group_cache_done(cache);
6160+
ret = btrfs_cache_block_group(cache, true);
61796161
if (ret) {
61806162
bg_failed++;
61816163
bg_ret = ret;

fs/btrfs/extent_io.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,7 +3233,7 @@ static int btrfs_bio_add_page(struct btrfs_bio_ctrl *bio_ctrl,
32333233
u32 bio_size = bio->bi_iter.bi_size;
32343234
u32 real_size;
32353235
const sector_t sector = disk_bytenr >> SECTOR_SHIFT;
3236-
bool contig;
3236+
bool contig = false;
32373237
int ret;
32383238

32393239
ASSERT(bio);
@@ -3242,10 +3242,35 @@ static int btrfs_bio_add_page(struct btrfs_bio_ctrl *bio_ctrl,
32423242
if (bio_ctrl->compress_type != compress_type)
32433243
return 0;
32443244

3245-
if (bio_ctrl->compress_type != BTRFS_COMPRESS_NONE)
3245+
3246+
if (bio->bi_iter.bi_size == 0) {
3247+
/* We can always add a page into an empty bio. */
3248+
contig = true;
3249+
} else if (bio_ctrl->compress_type == BTRFS_COMPRESS_NONE) {
3250+
struct bio_vec *bvec = bio_last_bvec_all(bio);
3251+
3252+
/*
3253+
* The contig check requires the following conditions to be met:
3254+
* 1) The pages are belonging to the same inode
3255+
* This is implied by the call chain.
3256+
*
3257+
* 2) The range has adjacent logical bytenr
3258+
*
3259+
* 3) The range has adjacent file offset
3260+
* This is required for the usage of btrfs_bio->file_offset.
3261+
*/
3262+
if (bio_end_sector(bio) == sector &&
3263+
page_offset(bvec->bv_page) + bvec->bv_offset +
3264+
bvec->bv_len == page_offset(page) + pg_offset)
3265+
contig = true;
3266+
} else {
3267+
/*
3268+
* For compression, all IO should have its logical bytenr
3269+
* set to the starting bytenr of the compressed extent.
3270+
*/
32463271
contig = bio->bi_iter.bi_sector == sector;
3247-
else
3248-
contig = bio_end_sector(bio) == sector;
3272+
}
3273+
32493274
if (!contig)
32503275
return 0;
32513276

fs/btrfs/file.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
24822482
btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
24832483
btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
24842484
btrfs_set_file_extent_offset(leaf, fi, 0);
2485+
btrfs_set_file_extent_generation(leaf, fi, trans->transid);
24852486
btrfs_mark_buffer_dirty(leaf);
24862487
goto out;
24872488
}
@@ -2498,6 +2499,7 @@ static int fill_holes(struct btrfs_trans_handle *trans,
24982499
btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
24992500
btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
25002501
btrfs_set_file_extent_offset(leaf, fi, 0);
2502+
btrfs_set_file_extent_generation(leaf, fi, trans->transid);
25012503
btrfs_mark_buffer_dirty(leaf);
25022504
goto out;
25032505
}

fs/btrfs/inode.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7693,6 +7693,20 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
76937693
const u64 data_alloc_len = length;
76947694
bool unlock_extents = false;
76957695

7696+
/*
7697+
* We could potentially fault if we have a buffer > PAGE_SIZE, and if
7698+
* we're NOWAIT we may submit a bio for a partial range and return
7699+
* EIOCBQUEUED, which would result in an errant short read.
7700+
*
7701+
* The best way to handle this would be to allow for partial completions
7702+
* of iocb's, so we could submit the partial bio, return and fault in
7703+
* the rest of the pages, and then submit the io for the rest of the
7704+
* range. However we don't have that currently, so simply return
7705+
* -EAGAIN at this point so that the normal path is used.
7706+
*/
7707+
if (!write && (flags & IOMAP_NOWAIT) && length > PAGE_SIZE)
7708+
return -EAGAIN;
7709+
76967710
/*
76977711
* Cap the size of reads to that usually seen in buffered I/O as we need
76987712
* to allocate a contiguous array for the checksums.

fs/btrfs/root-tree.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,10 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
349349
key.offset = ref_id;
350350
again:
351351
ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
352-
if (ret < 0)
352+
if (ret < 0) {
353+
err = ret;
353354
goto out;
354-
if (ret == 0) {
355+
} else if (ret == 0) {
355356
leaf = path->nodes[0];
356357
ref = btrfs_item_ptr(leaf, path->slots[0],
357358
struct btrfs_root_ref);

fs/btrfs/volumes.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2345,8 +2345,11 @@ int btrfs_get_dev_args_from_path(struct btrfs_fs_info *fs_info,
23452345

23462346
ret = btrfs_get_bdev_and_sb(path, FMODE_READ, fs_info->bdev_holder, 0,
23472347
&bdev, &disk_super);
2348-
if (ret)
2348+
if (ret) {
2349+
btrfs_put_dev_args_from_path(args);
23492350
return ret;
2351+
}
2352+
23502353
args->devid = btrfs_stack_device_id(&disk_super->dev_item);
23512354
memcpy(args->uuid, disk_super->dev_item.uuid, BTRFS_UUID_SIZE);
23522355
if (btrfs_fs_incompat(fs_info, METADATA_UUID))

fs/btrfs/xattr.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
371371
const char *name, const void *buffer,
372372
size_t size, int flags)
373373
{
374+
if (btrfs_root_readonly(BTRFS_I(inode)->root))
375+
return -EROFS;
376+
374377
name = xattr_full_name(handler, name);
375378
return btrfs_setxattr_trans(inode, name, buffer, size, flags);
376379
}

0 commit comments

Comments
 (0)