for-5.18-rc5-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmJ1X+YACgkQxWXV+ddt WDs75g/8DsrDBe/Sbn/bDLRw30D0StC5xRhaVJLNcAhSfIyyoBo0EKifd2nXdNSn rdc3pvRToPh2X1YQ/5FmtxuYW12N4pVOfWtXKdoFFXabMVJetDBSnS8KNzxBd9Ys OkiKj2qb8H+1uNwWVLxfbFBNWWPyCQLe/2DDmePxOAszs4YUPvwxffyA8oclyHb5 wW0qOJAC76Lz6y5Wo/GJrtAdlvWwb3t8+IDUKgGPT1BEIOE/fna+MhvEwqvCdY9F PPU5sWIXkAv3addgrcBHVX5HdAzRC0jAv2lHsttfu4dEOmTzw8dCTUh/IzSRa3fj IVy7AIGR+ZR++d4tOhAEZBe1KAqntY3UVmXY19cKTHOLLWFjv4XkKw8KJzsDiHUt rczedAFdgRRo9QIgwSsAU9Zi8DSG56BSenxsqFzqiL5BDDX1bUFXCegNYR42GfB/ 8E89eYkBCXxP6XeA1+44EOalCdqLKuQOyEijTUxn0UDGdqHHB1Gd/IUQDU5fpCqo kX6gdgMhNmjGJ/zETfOdFrYZaHYJUiiIRc6z8SCgM3JIPBgVw0FAa99Hs8Pl+eJn idmpfnHn6Xvmq46FISVRWgolkuj7VzTEOM65rNgOY3889Vk9Qt2qjI/DvYPGDs9Y 9PQI1FY+2E+ZqbNY8dZpXDii+6y36aAmGR1B10x3545+C36CA/0= =S4KK -----END PGP SIGNATURE----- Merge tag 'for-5.18-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: "Regression fixes in zone activation: - move a loop invariant out of the loop to avoid checking space status - properly handle unlimited activation Other fixes: - for subpage, force the free space v2 mount to avoid a warning and make it easy to switch a filesystem on different page size systems - export sysfs status of exclusive operation 'balance paused', so the user space tools can recognize it and allow adding a device with paused balance - fix assertion failure when logging directory key range item" * tag 'for-5.18-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: sysfs: export the balance paused state of exclusive operation btrfs: fix assertion failure when logging directory key range item btrfs: zoned: activate block group properly on unlimited active zone device btrfs: zoned: move non-changing condition check out of the loop btrfs: force v2 space cache usage for subpage mount
This commit is contained in:
commit
4b97bac075
|
@ -3658,6 +3658,17 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||||
if (sectorsize < PAGE_SIZE) {
|
if (sectorsize < PAGE_SIZE) {
|
||||||
struct btrfs_subpage_info *subpage_info;
|
struct btrfs_subpage_info *subpage_info;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* V1 space cache has some hardcoded PAGE_SIZE usage, and is
|
||||||
|
* going to be deprecated.
|
||||||
|
*
|
||||||
|
* Force to use v2 cache for subpage case.
|
||||||
|
*/
|
||||||
|
btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE);
|
||||||
|
btrfs_set_and_info(fs_info, FREE_SPACE_TREE,
|
||||||
|
"forcing free space tree for sector size %u with page size %lu",
|
||||||
|
sectorsize, PAGE_SIZE);
|
||||||
|
|
||||||
btrfs_warn(fs_info,
|
btrfs_warn(fs_info,
|
||||||
"read-write for sector size %u with page size %lu is experimental",
|
"read-write for sector size %u with page size %lu is experimental",
|
||||||
sectorsize, PAGE_SIZE);
|
sectorsize, PAGE_SIZE);
|
||||||
|
|
|
@ -922,6 +922,9 @@ static ssize_t btrfs_exclusive_operation_show(struct kobject *kobj,
|
||||||
case BTRFS_EXCLOP_BALANCE:
|
case BTRFS_EXCLOP_BALANCE:
|
||||||
str = "balance\n";
|
str = "balance\n";
|
||||||
break;
|
break;
|
||||||
|
case BTRFS_EXCLOP_BALANCE_PAUSED:
|
||||||
|
str = "balance paused\n";
|
||||||
|
break;
|
||||||
case BTRFS_EXCLOP_DEV_ADD:
|
case BTRFS_EXCLOP_DEV_ADD:
|
||||||
str = "device add\n";
|
str = "device add\n";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3721,11 +3721,29 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
|
||||||
key.offset = first_offset;
|
key.offset = first_offset;
|
||||||
key.type = BTRFS_DIR_LOG_INDEX_KEY;
|
key.type = BTRFS_DIR_LOG_INDEX_KEY;
|
||||||
ret = btrfs_insert_empty_item(trans, log, path, &key, sizeof(*item));
|
ret = btrfs_insert_empty_item(trans, log, path, &key, sizeof(*item));
|
||||||
if (ret)
|
/*
|
||||||
|
* -EEXIST is fine and can happen sporadically when we are logging a
|
||||||
|
* directory and have concurrent insertions in the subvolume's tree for
|
||||||
|
* items from other inodes and that result in pushing off some dir items
|
||||||
|
* from one leaf to another in order to accommodate for the new items.
|
||||||
|
* This results in logging the same dir index range key.
|
||||||
|
*/
|
||||||
|
if (ret && ret != -EEXIST)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
item = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
item = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
||||||
struct btrfs_dir_log_item);
|
struct btrfs_dir_log_item);
|
||||||
|
if (ret == -EEXIST) {
|
||||||
|
const u64 curr_end = btrfs_dir_log_end(path->nodes[0], item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* btrfs_del_dir_entries_in_log() might have been called during
|
||||||
|
* an unlink between the initial insertion of this key and the
|
||||||
|
* current update, or we might be logging a single entry deletion
|
||||||
|
* during a rename, so set the new last_offset to the max value.
|
||||||
|
*/
|
||||||
|
last_offset = max(last_offset, curr_end);
|
||||||
|
}
|
||||||
btrfs_set_dir_log_end(path->nodes[0], item, last_offset);
|
btrfs_set_dir_log_end(path->nodes[0], item, last_offset);
|
||||||
btrfs_mark_buffer_dirty(path->nodes[0]);
|
btrfs_mark_buffer_dirty(path->nodes[0]);
|
||||||
btrfs_release_path(path);
|
btrfs_release_path(path);
|
||||||
|
@ -3849,13 +3867,6 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
|
||||||
ret = insert_dir_log_key(trans, log, dst_path,
|
ret = insert_dir_log_key(trans, log, dst_path,
|
||||||
ino, *last_old_dentry_offset + 1,
|
ino, *last_old_dentry_offset + 1,
|
||||||
key.offset - 1);
|
key.offset - 1);
|
||||||
/*
|
|
||||||
* -EEXIST should never happen because when we
|
|
||||||
* log a directory in full mode (LOG_INODE_ALL)
|
|
||||||
* we drop all BTRFS_DIR_LOG_INDEX_KEY keys from
|
|
||||||
* the log tree.
|
|
||||||
*/
|
|
||||||
ASSERT(ret != -EEXIST);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -7031,12 +7042,12 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans,
|
||||||
/*
|
/*
|
||||||
* Other concurrent task might be logging the old directory,
|
* Other concurrent task might be logging the old directory,
|
||||||
* as it can be triggered when logging other inode that had or
|
* as it can be triggered when logging other inode that had or
|
||||||
* still has a dentry in the old directory. So take the old
|
* still has a dentry in the old directory. We lock the old
|
||||||
* directory's log_mutex to prevent getting an -EEXIST when
|
* directory's log_mutex to ensure the deletion of the old
|
||||||
* logging a key to record the deletion, or having that other
|
* name is persisted, because during directory logging we
|
||||||
* task logging the old directory get an -EEXIST if it attempts
|
* delete all BTRFS_DIR_LOG_INDEX_KEY keys and the deletion of
|
||||||
* to log the same key after we just did it. In both cases that
|
* the old name's dir index item is in the delayed items, so
|
||||||
* would result in falling back to a transaction commit.
|
* it could be missed by an in progress directory logging.
|
||||||
*/
|
*/
|
||||||
mutex_lock(&old_dir->log_mutex);
|
mutex_lock(&old_dir->log_mutex);
|
||||||
ret = del_logged_dentry(trans, log, path, btrfs_ino(old_dir),
|
ret = del_logged_dentry(trans, log, path, btrfs_ino(old_dir),
|
||||||
|
|
|
@ -1835,6 +1835,12 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No space left */
|
||||||
|
if (block_group->alloc_offset == block_group->zone_capacity) {
|
||||||
|
ret = false;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < map->num_stripes; i++) {
|
for (i = 0; i < map->num_stripes; i++) {
|
||||||
device = map->stripes[i].dev;
|
device = map->stripes[i].dev;
|
||||||
physical = map->stripes[i].physical;
|
physical = map->stripes[i].physical;
|
||||||
|
@ -1842,35 +1848,23 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
|
||||||
if (device->zone_info->max_active_zones == 0)
|
if (device->zone_info->max_active_zones == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* No space left */
|
|
||||||
if (block_group->alloc_offset == block_group->zone_capacity) {
|
|
||||||
ret = false;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!btrfs_dev_set_active_zone(device, physical)) {
|
if (!btrfs_dev_set_active_zone(device, physical)) {
|
||||||
/* Cannot activate the zone */
|
/* Cannot activate the zone */
|
||||||
ret = false;
|
ret = false;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Successfully activated all the zones */
|
|
||||||
if (i == map->num_stripes - 1)
|
|
||||||
block_group->zone_is_active = 1;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Successfully activated all the zones */
|
||||||
|
block_group->zone_is_active = 1;
|
||||||
spin_unlock(&block_group->lock);
|
spin_unlock(&block_group->lock);
|
||||||
|
|
||||||
if (block_group->zone_is_active) {
|
/* For the active block group list */
|
||||||
/* For the active block group list */
|
btrfs_get_block_group(block_group);
|
||||||
btrfs_get_block_group(block_group);
|
|
||||||
|
|
||||||
spin_lock(&fs_info->zone_active_bgs_lock);
|
spin_lock(&fs_info->zone_active_bgs_lock);
|
||||||
list_add_tail(&block_group->active_bg_list,
|
list_add_tail(&block_group->active_bg_list, &fs_info->zone_active_bgs);
|
||||||
&fs_info->zone_active_bgs);
|
spin_unlock(&fs_info->zone_active_bgs_lock);
|
||||||
spin_unlock(&fs_info->zone_active_bgs_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue