[LU-15590] e2fsprogs direct IO raw_read_blk() issues Created: 23/Feb/22  Updated: 19/Jul/22  Resolved: 24/Feb/22

Status: Resolved
Project: Lustre
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: John Hammond Assignee: John Hammond
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Related
is related to LU-15591 ext2fs_open2() missing goto Closed
Severity: 3
Rank (Obsolete): 9223372036854775807

 Description   

In e2fsprogs (master=v1.46.2-9-g32fda1e5 and recent wc tags), there is a one line bug in the direct IO case of raw_read_blk().

bounce_read:
        if (channel->align == 0)
                channel->align = 1;
        if ((channel->block_size > channel->align) &&
            (channel->block_size % channel->align) == 0)
                align_size = channel->block_size;
        else
                align_size = channel->align;
        aligned_blk = location / align_size;
        offset = location % align_size;

        mutex_lock(data, BOUNCE_MTX);
        if (ext2fs_llseek(data->dev, aligned_blk * align_size, SEEK_SET) < 0) {
                retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
                goto error_unlock;
        }
        while (size > 0) {
                actual = read(data->dev, data->bounce, align_size);
                if (actual != align_size) {
                        mutex_unlock(data, BOUNCE_MTX);
                        actual = really_read;
                        buf -= really_read;
                        size += really_read;
                        goto short_read;
                }
                actual = size; /* HERE HIER AQUI ICI QUI TUK */
                if (actual > align_size)
                        actual = align_size;
                actual -= offset;
                memcpy(buf, data->bounce + offset, actual);

We should not be setting actual = size.

When this is called from ext2fs_open() to read the super block on devices with a 4KB logical block size and EXT2_FLAG_DIRECT_IO it mis-initializes the super block and ext2fs_open() fails with EXT2_ET_BAD_MAGIC.

This can be reproduced in a few ways.

  1. Get a recent version of losetup that supports the -b option to set the logical blocksize.
  2. Hack ext2fs_get_device_sectsize() to return 4K.
  3. Use a device with 4K blocks.

Note, that you need to use EXT2_FLAG_DIRECT_IO in any of these cases to reproduce the issue.

It looks like this was fixed by artem_blagodarenko's change

c0015961 libext2fs: fix unix_io's Direct I/O support

and then inadvertently reintroduced by

d557b965 libext2fs: fix potential races in unix_io

See https://marc.info/?l=linux-ext4&m=161461569206170&w=2



 Comments   
Comment by Gerrit Updater [ 23/Feb/22 ]

"John L. Hammond <jhammond@whamcloud.com>" uploaded a new patch: https://review.whamcloud.com/46601
Subject: LU-15590 libext2fs: fix direct I/O read
Project: tools/e2fsprogs
Branch: master-lustre
Current Patch Set: 1
Commit: 077102b72c3146305d5de24668298bcf26fa747b

Comment by Gerrit Updater [ 24/Feb/22 ]

"Andreas Dilger <adilger@whamcloud.com>" merged in patch https://review.whamcloud.com/46601/
Subject: LU-15590 libext2fs: fix direct I/O read
Project: tools/e2fsprogs
Branch: master-lustre
Current Patch Set:
Commit: 980a75706e0ea08efc3138727fde0bf9440bee1c

Comment by Andreas Dilger [ 24/Feb/22 ]

Patch will be included in e2fsprogs-1.46.2.wc5.

Generated at Sat Feb 10 03:19:37 UTC 2024 using Jira 9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c.