Skip to content

Commit ae195ca

Browse files
committed
Merge tag 'for-6.3-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "First batch of fixes. Among them there are two updates to sysfs and ioctl which are not strictly fixes but are used for testing so there's no reason to delay them. - fix block group item corruption after inserting new block group - fix extent map logging bit not cleared for split maps after dropping range - fix calculation of unusable block group space reporting bogus values due to 32/64b division - fix unnecessary increment of read error stat on write error - improve error handling in inode update - export per-device fsid in DEV_INFO ioctl to distinguish seeding devices, needed for testing - allocator size classes: - fix potential dead lock in size class loading logic - print sysfs stats for the allocation classes" * tag 'for-6.3-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix block group item corruption after inserting new block group btrfs: fix extent map logging bit not cleared for split maps after dropping range btrfs: fix percent calculation for bg reclaim message btrfs: fix unnecessary increment of read error stat on write error btrfs: handle btrfs_del_item errors in __btrfs_update_delayed_inode btrfs: ioctl: return device fsid from DEV_INFO ioctl btrfs: fix potential dead lock in size class loading logic btrfs: sysfs: add size class stats
2 parents f331c5d + 675dfe1 commit ae195ca

File tree

7 files changed

+92
-32
lines changed

7 files changed

+92
-32
lines changed

fs/btrfs/bio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ static void btrfs_log_dev_io_error(struct bio *bio, struct btrfs_device *dev)
287287

288288
if (btrfs_op(bio) == BTRFS_MAP_WRITE)
289289
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
290-
if (!(bio->bi_opf & REQ_RAHEAD))
290+
else if (!(bio->bi_opf & REQ_RAHEAD))
291291
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_READ_ERRS);
292292
if (bio->bi_opf & REQ_PREFLUSH)
293293
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_FLUSH_ERRS);

fs/btrfs/block-group.c

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -558,14 +558,15 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
558558
static int sample_block_group_extent_item(struct btrfs_caching_control *caching_ctl,
559559
struct btrfs_block_group *block_group,
560560
int index, int max_index,
561-
struct btrfs_key *key)
561+
struct btrfs_key *found_key)
562562
{
563563
struct btrfs_fs_info *fs_info = block_group->fs_info;
564564
struct btrfs_root *extent_root;
565-
int ret = 0;
566565
u64 search_offset;
567566
u64 search_end = block_group->start + block_group->length;
568567
struct btrfs_path *path;
568+
struct btrfs_key search_key;
569+
int ret = 0;
569570

570571
ASSERT(index >= 0);
571572
ASSERT(index <= max_index);
@@ -585,37 +586,24 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_
585586
path->reada = READA_FORWARD;
586587

587588
search_offset = index * div_u64(block_group->length, max_index);
588-
key->objectid = block_group->start + search_offset;
589-
key->type = BTRFS_EXTENT_ITEM_KEY;
590-
key->offset = 0;
589+
search_key.objectid = block_group->start + search_offset;
590+
search_key.type = BTRFS_EXTENT_ITEM_KEY;
591+
search_key.offset = 0;
591592

592-
while (1) {
593-
ret = btrfs_search_forward(extent_root, key, path, 0);
594-
if (ret != 0)
595-
goto out;
593+
btrfs_for_each_slot(extent_root, &search_key, found_key, path, ret) {
596594
/* Success; sampled an extent item in the block group */
597-
if (key->type == BTRFS_EXTENT_ITEM_KEY &&
598-
key->objectid >= block_group->start &&
599-
key->objectid + key->offset <= search_end)
600-
goto out;
595+
if (found_key->type == BTRFS_EXTENT_ITEM_KEY &&
596+
found_key->objectid >= block_group->start &&
597+
found_key->objectid + found_key->offset <= search_end)
598+
break;
601599

602600
/* We can't possibly find a valid extent item anymore */
603-
if (key->objectid >= search_end) {
601+
if (found_key->objectid >= search_end) {
604602
ret = 1;
605603
break;
606604
}
607-
if (key->type < BTRFS_EXTENT_ITEM_KEY)
608-
key->type = BTRFS_EXTENT_ITEM_KEY;
609-
else
610-
key->objectid++;
611-
btrfs_release_path(path);
612-
up_read(&fs_info->commit_root_sem);
613-
mutex_unlock(&caching_ctl->mutex);
614-
cond_resched();
615-
mutex_lock(&caching_ctl->mutex);
616-
down_read(&fs_info->commit_root_sem);
617605
}
618-
out:
606+
619607
lockdep_assert_held(&caching_ctl->mutex);
620608
lockdep_assert_held_read(&fs_info->commit_root_sem);
621609
btrfs_free_path(path);
@@ -659,6 +647,7 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_
659647
static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl,
660648
struct btrfs_block_group *block_group)
661649
{
650+
struct btrfs_fs_info *fs_info = block_group->fs_info;
662651
struct btrfs_key key;
663652
int i;
664653
u64 min_size = block_group->length;
@@ -668,6 +657,8 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
668657
if (!btrfs_block_group_should_use_size_class(block_group))
669658
return 0;
670659

660+
lockdep_assert_held(&caching_ctl->mutex);
661+
lockdep_assert_held_read(&fs_info->commit_root_sem);
671662
for (i = 0; i < 5; ++i) {
672663
ret = sample_block_group_extent_item(caching_ctl, block_group, i, 5, &key);
673664
if (ret < 0)
@@ -682,7 +673,6 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
682673
block_group->size_class = size_class;
683674
spin_unlock(&block_group->lock);
684675
}
685-
686676
out:
687677
return ret;
688678
}
@@ -1836,7 +1826,8 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
18361826

18371827
btrfs_info(fs_info,
18381828
"reclaiming chunk %llu with %llu%% used %llu%% unusable",
1839-
bg->start, div_u64(bg->used * 100, bg->length),
1829+
bg->start,
1830+
div64_u64(bg->used * 100, bg->length),
18401831
div64_u64(zone_unusable * 100, bg->length));
18411832
trace_btrfs_reclaim_block_group(bg);
18421833
ret = btrfs_relocate_chunk(fs_info, bg->start);
@@ -2493,18 +2484,29 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
24932484
struct btrfs_block_group_item bgi;
24942485
struct btrfs_root *root = btrfs_block_group_root(fs_info);
24952486
struct btrfs_key key;
2487+
u64 old_commit_used;
2488+
int ret;
24962489

24972490
spin_lock(&block_group->lock);
24982491
btrfs_set_stack_block_group_used(&bgi, block_group->used);
24992492
btrfs_set_stack_block_group_chunk_objectid(&bgi,
25002493
block_group->global_root_id);
25012494
btrfs_set_stack_block_group_flags(&bgi, block_group->flags);
2495+
old_commit_used = block_group->commit_used;
2496+
block_group->commit_used = block_group->used;
25022497
key.objectid = block_group->start;
25032498
key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
25042499
key.offset = block_group->length;
25052500
spin_unlock(&block_group->lock);
25062501

2507-
return btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
2502+
ret = btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
2503+
if (ret < 0) {
2504+
spin_lock(&block_group->lock);
2505+
block_group->commit_used = old_commit_used;
2506+
spin_unlock(&block_group->lock);
2507+
}
2508+
2509+
return ret;
25082510
}
25092511

25102512
static int insert_dev_extent(struct btrfs_trans_handle *trans,

fs/btrfs/delayed-inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
10481048
* so there is only one iref. The case that several irefs are
10491049
* in the same item doesn't exist.
10501050
*/
1051-
btrfs_del_item(trans, root, path);
1051+
ret = btrfs_del_item(trans, root, path);
10521052
out:
10531053
btrfs_release_delayed_iref(node);
10541054
btrfs_release_path(path);

fs/btrfs/extent_map.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,13 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
763763
goto next;
764764
}
765765

766+
flags = em->flags;
766767
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
768+
/*
769+
* In case we split the extent map, we want to preserve the
770+
* EXTENT_FLAG_LOGGING flag on our extent map, but we don't want
771+
* it on the new extent maps.
772+
*/
767773
clear_bit(EXTENT_FLAG_LOGGING, &flags);
768774
modified = !list_empty(&em->list);
769775

@@ -774,7 +780,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
774780
if (em->start >= start && em_end <= end)
775781
goto remove_em;
776782

777-
flags = em->flags;
778783
gen = em->generation;
779784
compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
780785

fs/btrfs/ioctl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2859,6 +2859,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
28592859
di_args->bytes_used = btrfs_device_get_bytes_used(dev);
28602860
di_args->total_bytes = btrfs_device_get_total_bytes(dev);
28612861
memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
2862+
memcpy(di_args->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE);
28622863
if (dev->name)
28632864
strscpy(di_args->path, btrfs_dev_name(dev), sizeof(di_args->path));
28642865
else

fs/btrfs/sysfs.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/spinlock.h>
1010
#include <linux/completion.h>
1111
#include <linux/bug.h>
12+
#include <linux/list.h>
1213
#include <crypto/hash.h>
1314
#include "messages.h"
1415
#include "ctree.h"
@@ -778,6 +779,45 @@ static ssize_t btrfs_chunk_size_store(struct kobject *kobj,
778779
return len;
779780
}
780781

782+
static ssize_t btrfs_size_classes_show(struct kobject *kobj,
783+
struct kobj_attribute *a, char *buf)
784+
{
785+
struct btrfs_space_info *sinfo = to_space_info(kobj);
786+
struct btrfs_block_group *bg;
787+
u32 none = 0;
788+
u32 small = 0;
789+
u32 medium = 0;
790+
u32 large = 0;
791+
792+
for (int i = 0; i < BTRFS_NR_RAID_TYPES; ++i) {
793+
down_read(&sinfo->groups_sem);
794+
list_for_each_entry(bg, &sinfo->block_groups[i], list) {
795+
if (!btrfs_block_group_should_use_size_class(bg))
796+
continue;
797+
switch (bg->size_class) {
798+
case BTRFS_BG_SZ_NONE:
799+
none++;
800+
break;
801+
case BTRFS_BG_SZ_SMALL:
802+
small++;
803+
break;
804+
case BTRFS_BG_SZ_MEDIUM:
805+
medium++;
806+
break;
807+
case BTRFS_BG_SZ_LARGE:
808+
large++;
809+
break;
810+
}
811+
}
812+
up_read(&sinfo->groups_sem);
813+
}
814+
return sysfs_emit(buf, "none %u\n"
815+
"small %u\n"
816+
"medium %u\n"
817+
"large %u\n",
818+
none, small, medium, large);
819+
}
820+
781821
#ifdef CONFIG_BTRFS_DEBUG
782822
/*
783823
* Request chunk allocation with current chunk size.
@@ -835,6 +875,7 @@ SPACE_INFO_ATTR(bytes_zone_unusable);
835875
SPACE_INFO_ATTR(disk_used);
836876
SPACE_INFO_ATTR(disk_total);
837877
BTRFS_ATTR_RW(space_info, chunk_size, btrfs_chunk_size_show, btrfs_chunk_size_store);
878+
BTRFS_ATTR(space_info, size_classes, btrfs_size_classes_show);
838879

839880
static ssize_t btrfs_sinfo_bg_reclaim_threshold_show(struct kobject *kobj,
840881
struct kobj_attribute *a,
@@ -887,6 +928,7 @@ static struct attribute *space_info_attrs[] = {
887928
BTRFS_ATTR_PTR(space_info, disk_total),
888929
BTRFS_ATTR_PTR(space_info, bg_reclaim_threshold),
889930
BTRFS_ATTR_PTR(space_info, chunk_size),
931+
BTRFS_ATTR_PTR(space_info, size_classes),
890932
#ifdef CONFIG_BTRFS_DEBUG
891933
BTRFS_ATTR_PTR(space_info, force_chunk_alloc),
892934
#endif

include/uapi/linux/btrfs.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,17 @@ struct btrfs_ioctl_dev_info_args {
245245
__u8 uuid[BTRFS_UUID_SIZE]; /* in/out */
246246
__u64 bytes_used; /* out */
247247
__u64 total_bytes; /* out */
248-
__u64 unused[379]; /* pad to 4k */
248+
/*
249+
* Optional, out.
250+
*
251+
* Showing the fsid of the device, allowing user space to check if this
252+
* device is a seeding one.
253+
*
254+
* Introduced in v6.3, thus user space still needs to check if kernel
255+
* changed this value. Older kernel will not touch the values here.
256+
*/
257+
__u8 fsid[BTRFS_UUID_SIZE];
258+
__u64 unused[377]; /* pad to 4k */
249259
__u8 path[BTRFS_DEVICE_PATH_NAME_MAX]; /* out */
250260
};
251261

0 commit comments

Comments
 (0)