Skip to content

Commit 4b97bac

Browse files
committed
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
2 parents adcffc1 + 3e1ad19 commit 4b97bac

File tree

4 files changed

+53
-34
lines changed

4 files changed

+53
-34
lines changed

fs/btrfs/disk-io.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3658,6 +3658,17 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
36583658
if (sectorsize < PAGE_SIZE) {
36593659
struct btrfs_subpage_info *subpage_info;
36603660

3661+
/*
3662+
* V1 space cache has some hardcoded PAGE_SIZE usage, and is
3663+
* going to be deprecated.
3664+
*
3665+
* Force to use v2 cache for subpage case.
3666+
*/
3667+
btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE);
3668+
btrfs_set_and_info(fs_info, FREE_SPACE_TREE,
3669+
"forcing free space tree for sector size %u with page size %lu",
3670+
sectorsize, PAGE_SIZE);
3671+
36613672
btrfs_warn(fs_info,
36623673
"read-write for sector size %u with page size %lu is experimental",
36633674
sectorsize, PAGE_SIZE);

fs/btrfs/sysfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,9 @@ static ssize_t btrfs_exclusive_operation_show(struct kobject *kobj,
922922
case BTRFS_EXCLOP_BALANCE:
923923
str = "balance\n";
924924
break;
925+
case BTRFS_EXCLOP_BALANCE_PAUSED:
926+
str = "balance paused\n";
927+
break;
925928
case BTRFS_EXCLOP_DEV_ADD:
926929
str = "device add\n";
927930
break;

fs/btrfs/tree-log.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,11 +3721,29 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
37213721
key.offset = first_offset;
37223722
key.type = BTRFS_DIR_LOG_INDEX_KEY;
37233723
ret = btrfs_insert_empty_item(trans, log, path, &key, sizeof(*item));
3724-
if (ret)
3724+
/*
3725+
* -EEXIST is fine and can happen sporadically when we are logging a
3726+
* directory and have concurrent insertions in the subvolume's tree for
3727+
* items from other inodes and that result in pushing off some dir items
3728+
* from one leaf to another in order to accommodate for the new items.
3729+
* This results in logging the same dir index range key.
3730+
*/
3731+
if (ret && ret != -EEXIST)
37253732
return ret;
37263733

37273734
item = btrfs_item_ptr(path->nodes[0], path->slots[0],
37283735
struct btrfs_dir_log_item);
3736+
if (ret == -EEXIST) {
3737+
const u64 curr_end = btrfs_dir_log_end(path->nodes[0], item);
3738+
3739+
/*
3740+
* btrfs_del_dir_entries_in_log() might have been called during
3741+
* an unlink between the initial insertion of this key and the
3742+
* current update, or we might be logging a single entry deletion
3743+
* during a rename, so set the new last_offset to the max value.
3744+
*/
3745+
last_offset = max(last_offset, curr_end);
3746+
}
37293747
btrfs_set_dir_log_end(path->nodes[0], item, last_offset);
37303748
btrfs_mark_buffer_dirty(path->nodes[0]);
37313749
btrfs_release_path(path);
@@ -3849,13 +3867,6 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
38493867
ret = insert_dir_log_key(trans, log, dst_path,
38503868
ino, *last_old_dentry_offset + 1,
38513869
key.offset - 1);
3852-
/*
3853-
* -EEXIST should never happen because when we
3854-
* log a directory in full mode (LOG_INODE_ALL)
3855-
* we drop all BTRFS_DIR_LOG_INDEX_KEY keys from
3856-
* the log tree.
3857-
*/
3858-
ASSERT(ret != -EEXIST);
38593870
if (ret < 0)
38603871
return ret;
38613872
}
@@ -7031,12 +7042,12 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans,
70317042
/*
70327043
* Other concurrent task might be logging the old directory,
70337044
* as it can be triggered when logging other inode that had or
7034-
* still has a dentry in the old directory. So take the old
7035-
* directory's log_mutex to prevent getting an -EEXIST when
7036-
* logging a key to record the deletion, or having that other
7037-
* task logging the old directory get an -EEXIST if it attempts
7038-
* to log the same key after we just did it. In both cases that
7039-
* would result in falling back to a transaction commit.
7045+
* still has a dentry in the old directory. We lock the old
7046+
* directory's log_mutex to ensure the deletion of the old
7047+
* name is persisted, because during directory logging we
7048+
* delete all BTRFS_DIR_LOG_INDEX_KEY keys and the deletion of
7049+
* the old name's dir index item is in the delayed items, so
7050+
* it could be missed by an in progress directory logging.
70407051
*/
70417052
mutex_lock(&old_dir->log_mutex);
70427053
ret = del_logged_dentry(trans, log, path, btrfs_ino(old_dir),

fs/btrfs/zoned.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,42 +1835,36 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
18351835
goto out_unlock;
18361836
}
18371837

1838+
/* No space left */
1839+
if (block_group->alloc_offset == block_group->zone_capacity) {
1840+
ret = false;
1841+
goto out_unlock;
1842+
}
1843+
18381844
for (i = 0; i < map->num_stripes; i++) {
18391845
device = map->stripes[i].dev;
18401846
physical = map->stripes[i].physical;
18411847

18421848
if (device->zone_info->max_active_zones == 0)
18431849
continue;
18441850

1845-
/* No space left */
1846-
if (block_group->alloc_offset == block_group->zone_capacity) {
1847-
ret = false;
1848-
goto out_unlock;
1849-
}
1850-
18511851
if (!btrfs_dev_set_active_zone(device, physical)) {
18521852
/* Cannot activate the zone */
18531853
ret = false;
18541854
goto out_unlock;
18551855
}
1856-
1857-
/* Successfully activated all the zones */
1858-
if (i == map->num_stripes - 1)
1859-
block_group->zone_is_active = 1;
1860-
1861-
18621856
}
1857+
1858+
/* Successfully activated all the zones */
1859+
block_group->zone_is_active = 1;
18631860
spin_unlock(&block_group->lock);
18641861

1865-
if (block_group->zone_is_active) {
1866-
/* For the active block group list */
1867-
btrfs_get_block_group(block_group);
1862+
/* For the active block group list */
1863+
btrfs_get_block_group(block_group);
18681864

1869-
spin_lock(&fs_info->zone_active_bgs_lock);
1870-
list_add_tail(&block_group->active_bg_list,
1871-
&fs_info->zone_active_bgs);
1872-
spin_unlock(&fs_info->zone_active_bgs_lock);
1873-
}
1865+
spin_lock(&fs_info->zone_active_bgs_lock);
1866+
list_add_tail(&block_group->active_bg_list, &fs_info->zone_active_bgs);
1867+
spin_unlock(&fs_info->zone_active_bgs_lock);
18741868

18751869
return true;
18761870

0 commit comments

Comments
 (0)