From 4c3ddd1b8634c06579a4f4e77d93584076e1c5e1 Mon Sep 17 00:00:00 2001 From: Patrick Farrell <pfarrell@whamcloud.com> Date: Thu, 30 Nov 2023 11:54:34 -0500 Subject: [PATCH] LU-16897 tgt: note 'hole' pages In order to do sparse reads, we must know which pages correspond to holes, so we note this when the page is read from disk. Note something unusual: We store the hole information in the lnb, which is a per-IO struct. This means the hole information is not present when a page is reused in cache. So when a region with a hole is first read from disk, the hole annotation is available for the transfer code, but if the page cache is in use, this information is not available on subsequent reads from the same pages. This can't be avoided because the server does not have any per-page private information for page cache pages (and ZFS would not support this). This isn't too costly for two reasons: 1. We default page cache to off on flash systems 2. Most data is only read once rather than many times in quick succession NB: It's not clear how we can efficiently get hole information from ZFS so this is only for ldiskfs for now. Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com> Change-Id: I54b1b0abeb6889163f36b315292d8b6e760d6f78 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53297 Tested-by: Maloo <maloo@whamcloud.com> Tested-by: jenkins <devops@whamcloud.com> Reviewed-by: Cyril Bordage <cbordage@whamcloud.com> Reviewed-by: Andreas Dilger <adilger@whamcloud.com> Reviewed-by: Oleg Drokin <green@whamcloud.com> --- lustre/include/obd.h | 2 ++ lustre/osd-ldiskfs/osd_io.c | 8 ++++++++ lustre/target/tgt_handler.c | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 8e24a98..fc397e0 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -467,6 +467,8 @@ struct niobuf_local { __u16 lnb_guard_disk:1; /* separate unlock for read path to allow shared access */ __u16 lnb_locked:1; + /* this lnb corresponds to a hole in the file */ + __u16 lnb_hole:1; }; struct tgt_thread_big_cache { diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 9c768d2..b3de147 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -421,6 +421,13 @@ static int osd_do_bio(struct osd_device *osd, struct inode *inode, nblocks = 1; if (blocks[block_idx + i] == 0) { /* hole */ + struct niobuf_local *lnb = + iobuf->dr_lnbs[page_idx]; + CDEBUG(D_INODE, + "hole at page_idx %d, block_idx %d, at offset %llu\n", + page_idx, block_idx, + lnb->lnb_file_offset); + lnb->lnb_hole = 1; LASSERTF(iobuf->dr_rw == 0, "page_idx %u, block_idx %u, i %u," "start_blocks: %llu, count: %llu, npages: %d\n", @@ -537,6 +544,7 @@ static int osd_map_remote_to_local(loff_t offset, ssize_t len, int *nrpages, lnb->lnb_guard_rpc = 0; lnb->lnb_guard_disk = 0; lnb->lnb_locked = 0; + lnb->lnb_hole = 0; LASSERTF(plen <= len, "plen %u, len %lld\n", plen, (long long) len); diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index c8f24db..27e33a1 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -2420,6 +2420,10 @@ int tgt_brw_read(struct tgt_session_info *tsi) nob += page_rc; if (page_rc != 0 && desc != NULL) { /* some data! */ LASSERT(local_nb[i].lnb_page != NULL); + CDEBUG(D_INODE, + "lnb %d, at offset %llu, hole %d\n", i, + local_nb[i].lnb_file_offset, + local_nb[i].lnb_hole); desc->bd_frag_ops->add_kiov_frag (desc, local_nb[i].lnb_page, local_nb[i].lnb_page_offset & ~PAGE_MASK, -- 1.8.3.1