Re: [PATCH 3/3] dm array: fix cursor index when skipping across block boundaries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Reviewed-by: thornber@xxxxxxxxxx

On Tue, Dec 3, 2024 at 5:50 PM Ming-Hung Tsai <mtsai@xxxxxxxxxx> wrote:
>
> dm_array_cursor_skip() seeks to the target position by loading array
> blocks iteratively until the specified number of entries to skip is
> reached. When seeking across block boundaries, it uses
> dm_array_cursor_next() to step into the next block.
> dm_array_cursor_skip() must first move the cursor index to the end
> of the current block; otherwise, the cursor position could incorrectly
> remain in the same block, causing the actual number of skipped entries
> to be much smaller than expected.
>
> This bug affects cache resizing in v2 metadata and could lead to data
> loss if the fast device is shrunk during the first-time resume. For
> example:
>
> 1. create a cache metadata consists of 32768 blocks, with a dirty block
>    assigned to the second bitmap block. cache_restore v1.0 is required.
>
> cat <<EOF >> cmeta.xml
> <superblock uuid="" block_size="64" nr_cache_blocks="32768" \
> policy="smq" hint_width="4">
>   <mappings>
>     <mapping cache_block="32767" origin_block="0" dirty="true"/>
>   </mappings>
> </superblock>
> EOF
> dmsetup create cmeta --table "0 8192 linear /dev/sdc 0"
> cache_restore -i cmeta.xml -o /dev/mapper/cmeta --metadata-version=2
>
> 2. bring up the cache while attempt to discard all the blocks belonging
>    to the second bitmap block (block# 32576 to 32767). The last command
>    is expected to fail, but it actually succeeds.
>
> dmsetup create cdata --table "0 2084864 linear /dev/sdc 8192"
> dmsetup create corig --table "0 65536 linear /dev/sdc 2105344"
> dmsetup create cache --table "0 65536 cache /dev/mapper/cmeta \
> /dev/mapper/cdata /dev/mapper/corig 64 2 metadata2 writeback smq \
> 2 migration_threshold 0"
>
> Signed-off-by: Ming-Hung Tsai <mtsai@xxxxxxxxxx>
> Fixes: 9b696229aa7d ("dm persistent data: add cursor skip functions to the cursor APIs")
> ---
>  drivers/md/persistent-data/dm-array.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c
> index 1c3af717ee4f..b293da766fb1 100644
> --- a/drivers/md/persistent-data/dm-array.c
> +++ b/drivers/md/persistent-data/dm-array.c
> @@ -1004,6 +1004,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count)
>                 }
>
>                 count -= remaining;
> +               c->index += (remaining - 1);
>                 r = dm_array_cursor_next(c);
>
>         } while (!r);
> --
> 2.47.0
>






[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux