for-6.3-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmQKUxwACgkQxWXV+ddt WDtPMg//RHAnHYRm+sHkXfRhz/+kWhipPo1OskLE5aYZaP1MSpk0NfNc1c6ZYwcg FQNeNQOooqBIYFpLeery14vw/FpFc/tivw7OP4XmtH9Jeyj6mwgAQpP5Gho8jDmm u90jf2UMwA+7qo57e9qfioufiZPGMsNnmK1BwdrcbuUZIz5UEZZ6u6BVhVFnEDGa y08Uv03t9g5F7msXfh4iBaPeJRgdWL7kiZfhFyCa6OHKiGOT39hYXn0ov1pET/yG IMECrX+BKiunABExHDN9VbW1AVWGmsvGjFYpZQnAWCm37cr3Mc7ngIz1FBF8hm+L 9Cd07GhBOPaKzFI+uAzVJrA0QkKnI8Wgd1YT3LWWT0qj5gpPA5YL4G0V4KLzPBOt TBe4dW7g4o4EXsYBJzYwiLjHILZyydkPKEQ78Bt2mwjdGs4PYNBGwyl0I2bV/pV+ dKGv+KOsiX2euPFtwVaIG5u8gEBCCoiKSO+HwphtfWyxnEE5/uvw0fdSJlKNt1Yj 28f+qyzN9WuNK/aSxI+KfW4PAXvkoLi7w8tjyJp3vpj6VnSmaFf2EtGiKtGSmLVn 3uSY8WZ24FdOHNV5QaliABGt/SaLG0rbLC8uPocryh0aW9xkMpvVVYPfTJmyWmxy kc5dfDhUinp5I0wLTtjRH407bB0CdukgpxOrN6GELqPufm7YvQk= =rJlY -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
ae195ca1a8
|
@ -287,7 +287,7 @@ static void btrfs_log_dev_io_error(struct bio *bio, struct btrfs_device *dev)
|
|||
|
||||
if (btrfs_op(bio) == BTRFS_MAP_WRITE)
|
||||
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
|
||||
if (!(bio->bi_opf & REQ_RAHEAD))
|
||||
else if (!(bio->bi_opf & REQ_RAHEAD))
|
||||
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_READ_ERRS);
|
||||
if (bio->bi_opf & REQ_PREFLUSH)
|
||||
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_FLUSH_ERRS);
|
||||
|
|
|
@ -558,14 +558,15 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
|
|||
static int sample_block_group_extent_item(struct btrfs_caching_control *caching_ctl,
|
||||
struct btrfs_block_group *block_group,
|
||||
int index, int max_index,
|
||||
struct btrfs_key *key)
|
||||
struct btrfs_key *found_key)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = block_group->fs_info;
|
||||
struct btrfs_root *extent_root;
|
||||
int ret = 0;
|
||||
u64 search_offset;
|
||||
u64 search_end = block_group->start + block_group->length;
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_key search_key;
|
||||
int ret = 0;
|
||||
|
||||
ASSERT(index >= 0);
|
||||
ASSERT(index <= max_index);
|
||||
|
@ -585,37 +586,24 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_
|
|||
path->reada = READA_FORWARD;
|
||||
|
||||
search_offset = index * div_u64(block_group->length, max_index);
|
||||
key->objectid = block_group->start + search_offset;
|
||||
key->type = BTRFS_EXTENT_ITEM_KEY;
|
||||
key->offset = 0;
|
||||
search_key.objectid = block_group->start + search_offset;
|
||||
search_key.type = BTRFS_EXTENT_ITEM_KEY;
|
||||
search_key.offset = 0;
|
||||
|
||||
while (1) {
|
||||
ret = btrfs_search_forward(extent_root, key, path, 0);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
btrfs_for_each_slot(extent_root, &search_key, found_key, path, ret) {
|
||||
/* Success; sampled an extent item in the block group */
|
||||
if (key->type == BTRFS_EXTENT_ITEM_KEY &&
|
||||
key->objectid >= block_group->start &&
|
||||
key->objectid + key->offset <= search_end)
|
||||
goto out;
|
||||
if (found_key->type == BTRFS_EXTENT_ITEM_KEY &&
|
||||
found_key->objectid >= block_group->start &&
|
||||
found_key->objectid + found_key->offset <= search_end)
|
||||
break;
|
||||
|
||||
/* We can't possibly find a valid extent item anymore */
|
||||
if (key->objectid >= search_end) {
|
||||
if (found_key->objectid >= search_end) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
if (key->type < BTRFS_EXTENT_ITEM_KEY)
|
||||
key->type = BTRFS_EXTENT_ITEM_KEY;
|
||||
else
|
||||
key->objectid++;
|
||||
btrfs_release_path(path);
|
||||
up_read(&fs_info->commit_root_sem);
|
||||
mutex_unlock(&caching_ctl->mutex);
|
||||
cond_resched();
|
||||
mutex_lock(&caching_ctl->mutex);
|
||||
down_read(&fs_info->commit_root_sem);
|
||||
}
|
||||
out:
|
||||
|
||||
lockdep_assert_held(&caching_ctl->mutex);
|
||||
lockdep_assert_held_read(&fs_info->commit_root_sem);
|
||||
btrfs_free_path(path);
|
||||
|
@ -659,6 +647,7 @@ out:
|
|||
static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl,
|
||||
struct btrfs_block_group *block_group)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = block_group->fs_info;
|
||||
struct btrfs_key key;
|
||||
int i;
|
||||
u64 min_size = block_group->length;
|
||||
|
@ -668,6 +657,8 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
|
|||
if (!btrfs_block_group_should_use_size_class(block_group))
|
||||
return 0;
|
||||
|
||||
lockdep_assert_held(&caching_ctl->mutex);
|
||||
lockdep_assert_held_read(&fs_info->commit_root_sem);
|
||||
for (i = 0; i < 5; ++i) {
|
||||
ret = sample_block_group_extent_item(caching_ctl, block_group, i, 5, &key);
|
||||
if (ret < 0)
|
||||
|
@ -682,7 +673,6 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
|
|||
block_group->size_class = size_class;
|
||||
spin_unlock(&block_group->lock);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1836,7 +1826,8 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
|
|||
|
||||
btrfs_info(fs_info,
|
||||
"reclaiming chunk %llu with %llu%% used %llu%% unusable",
|
||||
bg->start, div_u64(bg->used * 100, bg->length),
|
||||
bg->start,
|
||||
div64_u64(bg->used * 100, bg->length),
|
||||
div64_u64(zone_unusable * 100, bg->length));
|
||||
trace_btrfs_reclaim_block_group(bg);
|
||||
ret = btrfs_relocate_chunk(fs_info, bg->start);
|
||||
|
@ -2493,18 +2484,29 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_block_group_item bgi;
|
||||
struct btrfs_root *root = btrfs_block_group_root(fs_info);
|
||||
struct btrfs_key key;
|
||||
u64 old_commit_used;
|
||||
int ret;
|
||||
|
||||
spin_lock(&block_group->lock);
|
||||
btrfs_set_stack_block_group_used(&bgi, block_group->used);
|
||||
btrfs_set_stack_block_group_chunk_objectid(&bgi,
|
||||
block_group->global_root_id);
|
||||
btrfs_set_stack_block_group_flags(&bgi, block_group->flags);
|
||||
old_commit_used = block_group->commit_used;
|
||||
block_group->commit_used = block_group->used;
|
||||
key.objectid = block_group->start;
|
||||
key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
|
||||
key.offset = block_group->length;
|
||||
spin_unlock(&block_group->lock);
|
||||
|
||||
return btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
|
||||
ret = btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
|
||||
if (ret < 0) {
|
||||
spin_lock(&block_group->lock);
|
||||
block_group->commit_used = old_commit_used;
|
||||
spin_unlock(&block_group->lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int insert_dev_extent(struct btrfs_trans_handle *trans,
|
||||
|
|
|
@ -1048,7 +1048,7 @@ again:
|
|||
* so there is only one iref. The case that several irefs are
|
||||
* in the same item doesn't exist.
|
||||
*/
|
||||
btrfs_del_item(trans, root, path);
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
out:
|
||||
btrfs_release_delayed_iref(node);
|
||||
btrfs_release_path(path);
|
||||
|
|
|
@ -763,7 +763,13 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
|
|||
goto next;
|
||||
}
|
||||
|
||||
flags = em->flags;
|
||||
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
|
||||
/*
|
||||
* In case we split the extent map, we want to preserve the
|
||||
* EXTENT_FLAG_LOGGING flag on our extent map, but we don't want
|
||||
* it on the new extent maps.
|
||||
*/
|
||||
clear_bit(EXTENT_FLAG_LOGGING, &flags);
|
||||
modified = !list_empty(&em->list);
|
||||
|
||||
|
@ -774,7 +780,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
|
|||
if (em->start >= start && em_end <= end)
|
||||
goto remove_em;
|
||||
|
||||
flags = em->flags;
|
||||
gen = em->generation;
|
||||
compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
||||
|
||||
|
|
|
@ -2859,6 +2859,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
|
|||
di_args->bytes_used = btrfs_device_get_bytes_used(dev);
|
||||
di_args->total_bytes = btrfs_device_get_total_bytes(dev);
|
||||
memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
|
||||
memcpy(di_args->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE);
|
||||
if (dev->name)
|
||||
strscpy(di_args->path, btrfs_dev_name(dev), sizeof(di_args->path));
|
||||
else
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/list.h>
|
||||
#include <crypto/hash.h>
|
||||
#include "messages.h"
|
||||
#include "ctree.h"
|
||||
|
@ -778,6 +779,45 @@ static ssize_t btrfs_chunk_size_store(struct kobject *kobj,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t btrfs_size_classes_show(struct kobject *kobj,
|
||||
struct kobj_attribute *a, char *buf)
|
||||
{
|
||||
struct btrfs_space_info *sinfo = to_space_info(kobj);
|
||||
struct btrfs_block_group *bg;
|
||||
u32 none = 0;
|
||||
u32 small = 0;
|
||||
u32 medium = 0;
|
||||
u32 large = 0;
|
||||
|
||||
for (int i = 0; i < BTRFS_NR_RAID_TYPES; ++i) {
|
||||
down_read(&sinfo->groups_sem);
|
||||
list_for_each_entry(bg, &sinfo->block_groups[i], list) {
|
||||
if (!btrfs_block_group_should_use_size_class(bg))
|
||||
continue;
|
||||
switch (bg->size_class) {
|
||||
case BTRFS_BG_SZ_NONE:
|
||||
none++;
|
||||
break;
|
||||
case BTRFS_BG_SZ_SMALL:
|
||||
small++;
|
||||
break;
|
||||
case BTRFS_BG_SZ_MEDIUM:
|
||||
medium++;
|
||||
break;
|
||||
case BTRFS_BG_SZ_LARGE:
|
||||
large++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
up_read(&sinfo->groups_sem);
|
||||
}
|
||||
return sysfs_emit(buf, "none %u\n"
|
||||
"small %u\n"
|
||||
"medium %u\n"
|
||||
"large %u\n",
|
||||
none, small, medium, large);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BTRFS_DEBUG
|
||||
/*
|
||||
* Request chunk allocation with current chunk size.
|
||||
|
@ -835,6 +875,7 @@ SPACE_INFO_ATTR(bytes_zone_unusable);
|
|||
SPACE_INFO_ATTR(disk_used);
|
||||
SPACE_INFO_ATTR(disk_total);
|
||||
BTRFS_ATTR_RW(space_info, chunk_size, btrfs_chunk_size_show, btrfs_chunk_size_store);
|
||||
BTRFS_ATTR(space_info, size_classes, btrfs_size_classes_show);
|
||||
|
||||
static ssize_t btrfs_sinfo_bg_reclaim_threshold_show(struct kobject *kobj,
|
||||
struct kobj_attribute *a,
|
||||
|
@ -887,6 +928,7 @@ static struct attribute *space_info_attrs[] = {
|
|||
BTRFS_ATTR_PTR(space_info, disk_total),
|
||||
BTRFS_ATTR_PTR(space_info, bg_reclaim_threshold),
|
||||
BTRFS_ATTR_PTR(space_info, chunk_size),
|
||||
BTRFS_ATTR_PTR(space_info, size_classes),
|
||||
#ifdef CONFIG_BTRFS_DEBUG
|
||||
BTRFS_ATTR_PTR(space_info, force_chunk_alloc),
|
||||
#endif
|
||||
|
|
|
@ -245,7 +245,17 @@ struct btrfs_ioctl_dev_info_args {
|
|||
__u8 uuid[BTRFS_UUID_SIZE]; /* in/out */
|
||||
__u64 bytes_used; /* out */
|
||||
__u64 total_bytes; /* out */
|
||||
__u64 unused[379]; /* pad to 4k */
|
||||
/*
|
||||
* Optional, out.
|
||||
*
|
||||
* Showing the fsid of the device, allowing user space to check if this
|
||||
* device is a seeding one.
|
||||
*
|
||||
* Introduced in v6.3, thus user space still needs to check if kernel
|
||||
* changed this value. Older kernel will not touch the values here.
|
||||
*/
|
||||
__u8 fsid[BTRFS_UUID_SIZE];
|
||||
__u64 unused[377]; /* pad to 4k */
|
||||
__u8 path[BTRFS_DEVICE_PATH_NAME_MAX]; /* out */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue