]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commit
ceph: fix generic/639 xfstests failure
authorViacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Fri, 6 Feb 2026 19:48:02 +0000 (11:48 -0800)
committerViacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Tue, 24 Feb 2026 22:30:04 +0000 (14:30 -0800)
commit712f4a43c1258070d29a784bd5f0c212504b234b
treed95c7c82df1aa20def36d4658f948fc6b696ab24
parent5924475dc9f38d6b3d91827cd15817ff5758a12c
ceph: fix generic/639 xfstests failure

The generic/639 xfstest fails for Ceph msgr2 protocol:

Ubuntu 22.04.5 LTS (GNU/Linux 6.17.0-rc7+ x86_64)

sudo mount -t ceph :/ /mnt/cephfs/ -o name=admin,fs=cephfs,ms_mode=secure

sudo ./check generic/639
FSTYP -- ceph
PLATFORM -- Linux/x86_64 ceph-0005 6.17.0-rc7+ #16 SMP PREEMPT_DYNAMIC Wed Nov 12 11:01:48 PST 2025
MKFS_OPTIONS -- 192.168.1.213:3300:/scratch
MOUNT_OPTIONS -- -o name=admin,ms_mode=secure 192.168.1.213:3300:/scratch /mnt/cephfs/scratch

generic/639 - output mismatch (see /home/slavad/XFSTESTS-2/xfstests-dev/results//generic/639.out.bad)

The simple way to reproduce the issue simply running these steps:

mount -t ceph :/ /mnt/cephfs/ -o name=admin,fs=cephfs,ms_mode=secure
xfs_io -f -c "pwrite -q 0 32" ./testfile251125-0004
umount /mnt/cephfs/
mount -t ceph :/ /mnt/cephfs/ -o name=admin,fs=cephfs,ms_mode=secure
xfs_io -c "pwrite -q 32 32" ./testfile251125-0004

Finally, we have the unexpected content of the file:

hexdump ./testfile251125-0004
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000020 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd
*
0000040

Initial analysis has shown that if we try to write out of
end of file, then ceph_write_begin() is responsible for
the issue because it calls netfs_write_begin() and we have
such logic:

int netfs_write_begin(struct netfs_inode *ctx,
              struct file *file, struct address_space *mapping,
              loff_t pos, unsigned int len, struct folio **_folio,
              void **_fsdata)
{
<skipped>

    folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
                    mapping_gfp_mask(mapping));

<skipped>

    if (folio_test_uptodate(folio))
        goto have_folio;

<skipped>
}

The reason of the issue that somehow we have folio in uptodate
state and netfs_write_begin() simply skips the logic of
reading existing file's content.

Futher analysis revealed that we call ceph_fill_inode() and
ceph_fill_inline_data() before ceph_write_begin().

void ceph_fill_inline_data(struct inode *inode, struct page *locked_page,
               char    *data, size_t len)
{
<skipped>

    if (page != locked_page) {
        if (len < PAGE_SIZE)
            zero_user_segment(page, len, PAGE_SIZE);
        else
            flush_dcache_page(page);

        SetPageUptodate(page); <--- We set page uptodate if len == 0!!!!
        unlock_page(page);
        put_page(page);
    }
}

This patch fixes the issue by checking the len argument and
setting memory page uptodate only if len > 0.

sudo ./check generic/639
FSTYP         -- ceph
PLATFORM      -- Linux/x86_64 ceph-0005 6.19.0-rc5+ #2 SMP PREEMPT_DYNAMIC Thu Feb  5 15:43:51 PST 2026
MKFS_OPTIONS  -- 192.168.1.213:3300:/scratch
MOUNT_OPTIONS -- -o name=admin,ms_mode=secure 192.168.1.213:3300:/scratch /mnt/cephfs/scratch

generic/639 6s ...  6s
Ran: generic/639
Passed all 1 tests

[1] https://tracker.ceph.com/issues/73829

Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
cc: Alex Markuze <amarkuze@redhat.com>
cc: Ilya Dryomov <idryomov@gmail.com>
cc: Patrick Donnelly <pdonnell@redhat.com>
cc: Ceph Development <ceph-devel@vger.kernel.org>
fs/ceph/addr.c