Skip to content

Commit be1a1d7

Browse files
naotakdave
authored andcommitted
btrfs: zoned: finish fully written block group
If we have written to the zone capacity, the device automatically deactivates the zone. Sync up block group side (the active BG list and zone_is_active flag) with it. We need to do it both on data BGs and metadata BGs. On data side, we add a hook to btrfs_finish_ordered_io(). On metadata side, we use end_extent_buffer_writeback(). To reduce excess lookup of a block group, we mark the last extent buffer in a block group with EXTENT_BUFFER_ZONE_FINISH flag. This cannot be done for data (ordered_extent), because the address may change due to REQ_OP_ZONE_APPEND. Signed-off-by: Naohiro Aota <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent a85f05e commit be1a1d7

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed

fs/btrfs/extent_io.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4159,6 +4159,9 @@ void wait_on_extent_buffer_writeback(struct extent_buffer *eb)
41594159

41604160
static void end_extent_buffer_writeback(struct extent_buffer *eb)
41614161
{
4162+
if (test_bit(EXTENT_BUFFER_ZONE_FINISH, &eb->bflags))
4163+
btrfs_zone_finish_endio(eb->fs_info, eb->start, eb->len);
4164+
41624165
clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
41634166
smp_mb__after_atomic();
41644167
wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
@@ -4760,8 +4763,13 @@ static int submit_eb_page(struct page *page, struct writeback_control *wbc,
47604763
free_extent_buffer(eb);
47614764
return ret;
47624765
}
4763-
if (cache)
4766+
if (cache) {
4767+
/* Impiles write in zoned mode */
47644768
btrfs_put_block_group(cache);
4769+
/* Mark the last eb in a block group */
4770+
if (cache->seq_zone && eb->start + eb->len == cache->zone_capacity)
4771+
set_bit(EXTENT_BUFFER_ZONE_FINISH, &eb->bflags);
4772+
}
47654773
ret = write_one_eb(eb, wbc, epd);
47664774
free_extent_buffer(eb);
47674775
if (ret < 0)

fs/btrfs/extent_io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum {
3232
/* write IO error */
3333
EXTENT_BUFFER_WRITE_ERR,
3434
EXTENT_BUFFER_NO_CHECK,
35+
EXTENT_BUFFER_ZONE_FINISH,
3536
};
3637

3738
/* these are flags for __process_pages_contig */

fs/btrfs/inode.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3010,8 +3010,12 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
30103010
goto out;
30113011
}
30123012

3013-
if (ordered_extent->bdev)
3013+
/* A valid bdev implies a write on a sequential zone */
3014+
if (ordered_extent->bdev) {
30143015
btrfs_rewrite_logical_zoned(ordered_extent);
3016+
btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
3017+
ordered_extent->disk_num_bytes);
3018+
}
30153019

30163020
btrfs_free_io_failure_record(inode, start, end);
30173021

fs/btrfs/zoned.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,3 +1904,53 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, int raid_index
19041904

19051905
return ret;
19061906
}
1907+
1908+
void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 length)
1909+
{
1910+
struct btrfs_block_group *block_group;
1911+
struct map_lookup *map;
1912+
struct btrfs_device *device;
1913+
u64 physical;
1914+
1915+
if (!btrfs_is_zoned(fs_info))
1916+
return;
1917+
1918+
block_group = btrfs_lookup_block_group(fs_info, logical);
1919+
ASSERT(block_group);
1920+
1921+
if (logical + length < block_group->start + block_group->zone_capacity)
1922+
goto out;
1923+
1924+
spin_lock(&block_group->lock);
1925+
1926+
if (!block_group->zone_is_active) {
1927+
spin_unlock(&block_group->lock);
1928+
goto out;
1929+
}
1930+
1931+
block_group->zone_is_active = 0;
1932+
/* We should have consumed all the free space */
1933+
ASSERT(block_group->alloc_offset == block_group->zone_capacity);
1934+
ASSERT(block_group->free_space_ctl->free_space == 0);
1935+
btrfs_clear_treelog_bg(block_group);
1936+
spin_unlock(&block_group->lock);
1937+
1938+
map = block_group->physical_map;
1939+
device = map->stripes[0].dev;
1940+
physical = map->stripes[0].physical;
1941+
1942+
if (!device->zone_info->max_active_zones)
1943+
goto out;
1944+
1945+
btrfs_dev_clear_active_zone(device, physical);
1946+
1947+
spin_lock(&fs_info->zone_active_bgs_lock);
1948+
ASSERT(!list_empty(&block_group->active_bg_list));
1949+
list_del_init(&block_group->active_bg_list);
1950+
spin_unlock(&fs_info->zone_active_bgs_lock);
1951+
1952+
btrfs_put_block_group(block_group);
1953+
1954+
out:
1955+
btrfs_put_block_group(block_group);
1956+
}

fs/btrfs/zoned.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group);
7373
int btrfs_zone_finish(struct btrfs_block_group *block_group);
7474
bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices,
7575
int raid_index);
76+
void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical,
77+
u64 length);
7678
#else /* CONFIG_BLK_DEV_ZONED */
7779
static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
7880
struct blk_zone *zone)
@@ -224,6 +226,9 @@ static inline bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices,
224226
return true;
225227
}
226228

229+
static inline void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info,
230+
u64 logical, u64 length) { }
231+
227232
#endif
228233

229234
static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)

0 commit comments

Comments
 (0)