]> Gentwo Git Trees - linux/.git/commitdiff
ext4: pass out extent seq counter when mapping blocks
authorZhang Yi <yi.zhang@huawei.com>
Mon, 13 Oct 2025 01:51:20 +0000 (09:51 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 6 Nov 2025 15:44:39 +0000 (10:44 -0500)
When creating or querying mapping blocks using the ext4_map_blocks() and
ext4_map_{query|create}_blocks() helpers, also pass out the extent
sequence number of the block mapping info through the ext4_map_blocks
structure. This sequence number can later serve as a valid cookie within
iomap infrastructure and the move extents procedure.

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Message-ID: <20251013015128.499308-5-yi.zhang@huaweicloud.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/ext4.h
fs/ext4/inode.c

index eff97b3a1093566d504cdfed1ea5f908146cb510..9f127aedbaeeb054341ae1c454225cf16054d692 100644 (file)
@@ -260,6 +260,7 @@ struct ext4_map_blocks {
        ext4_lblk_t m_lblk;
        unsigned int m_len;
        unsigned int m_flags;
+       u64 m_seq;
 };
 
 /*
index b62c1a87ed6bf22483cadd5096015985cd50a362..783c883d4d5ef4e775e79f735d0f308b85be3ede 100644 (file)
@@ -550,10 +550,13 @@ static int ext4_map_query_blocks(handle_t *handle, struct inode *inode,
                retval = ext4_ext_map_blocks(handle, inode, map, flags);
        else
                retval = ext4_ind_map_blocks(handle, inode, map, flags);
-
-       if (retval <= 0)
+       if (retval < 0)
                return retval;
 
+       /* A hole? */
+       if (retval == 0)
+               goto out;
+
        if (unlikely(retval != map->m_len)) {
                ext4_warning(inode->i_sb,
                             "ES len assertion failed for inode "
@@ -573,11 +576,13 @@ static int ext4_map_query_blocks(handle_t *handle, struct inode *inode,
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
                ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
                                      map->m_pblk, status, false);
-               return retval;
+       } else {
+               retval = ext4_map_query_blocks_next_in_leaf(handle, inode, map,
+                                                           orig_mlen);
        }
-
-       return ext4_map_query_blocks_next_in_leaf(handle, inode, map,
-                                                 orig_mlen);
+out:
+       map->m_seq = READ_ONCE(EXT4_I(inode)->i_es_seq);
+       return retval;
 }
 
 static int ext4_map_create_blocks(handle_t *handle, struct inode *inode,
@@ -649,7 +654,7 @@ static int ext4_map_create_blocks(handle_t *handle, struct inode *inode,
         * extent status tree.
         */
        if (flags & EXT4_GET_BLOCKS_PRE_IO &&
-           ext4_es_lookup_extent(inode, map->m_lblk, NULL, &es, NULL)) {
+           ext4_es_lookup_extent(inode, map->m_lblk, NULL, &es, &map->m_seq)) {
                if (ext4_es_is_written(&es))
                        return retval;
        }
@@ -658,6 +663,7 @@ static int ext4_map_create_blocks(handle_t *handle, struct inode *inode,
                        EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
        ext4_es_insert_extent(inode, map->m_lblk, map->m_len, map->m_pblk,
                              status, flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE);
+       map->m_seq = READ_ONCE(EXT4_I(inode)->i_es_seq);
 
        return retval;
 }
@@ -723,7 +729,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                ext4_check_map_extents_env(inode);
 
        /* Lookup extent status tree firstly */
-       if (ext4_es_lookup_extent(inode, map->m_lblk, NULL, &es, NULL)) {
+       if (ext4_es_lookup_extent(inode, map->m_lblk, NULL, &es, &map->m_seq)) {
                if (ext4_es_is_written(&es) || ext4_es_is_unwritten(&es)) {
                        map->m_pblk = ext4_es_pblock(&es) +
                                        map->m_lblk - es.es_lblk;
@@ -1979,6 +1985,8 @@ static int ext4_da_map_blocks(struct inode *inode, struct ext4_map_blocks *map)
 
        map->m_flags |= EXT4_MAP_DELAYED;
        retval = ext4_insert_delayed_blocks(inode, map->m_lblk, map->m_len);
+       if (!retval)
+               map->m_seq = READ_ONCE(EXT4_I(inode)->i_es_seq);
        up_write(&EXT4_I(inode)->i_data_sem);
 
        return retval;