Implement find_hole() for dm-ploop target. Iterate over clusters until we find hole or data by using ploop_bat_entries() which will do all our work
Feature: dm: implement SEEK_HOLE for dm-qcow2 and dm-ploop https://jira.vzint.dev/browse/PSBM-145746 Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com> --- drivers/md/dm-ploop-map.c | 50 ++++++++++++++++++++++++++++++++++++ drivers/md/dm-ploop-target.c | 1 + drivers/md/dm-ploop.h | 1 + 3 files changed, 52 insertions(+) diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c index 3f0803cb8e47..6fa146f8fe9a 100644 --- a/drivers/md/dm-ploop-map.c +++ b/drivers/md/dm-ploop-map.c @@ -1989,3 +1989,53 @@ int ploop_prepare_reloc_index_wb(struct ploop *ploop, return err; } ALLOW_ERROR_INJECTION(ploop_prepare_reloc_index_wb, ERRNO); + +loff_t ploop_llseek_hole(struct dm_target *ti, loff_t offset, int whence) +{ + struct ploop *ploop = ti->private; + u32 clu, dst_clu; + loff_t result; + + clu = SEC_TO_CLU(ploop, to_sector(offset) + ploop->skip_off); + + while (clu < ploop->nr_bat_entries) { + + /* + * Assume a locked cluster to have a data. + * In worst case someone will read zeroes + */ + if (ploop_postpone_if_cluster_locked(ploop, NULL, clu)) { + if (whence & SEEK_DATA) + break; + if (whence & SEEK_HOLE) { + clu++; + continue; + } + } + + /* + * It *may* be possible to speed this up by iterating over clusters + * in mapped metadata page, but this is a bit problematic + * since we want to check if cluster is locked + */ + dst_clu = ploop_bat_entries(ploop, clu, NULL, NULL); + + if (whence & SEEK_DATA && dst_clu != BAT_ENTRY_NONE) + break; + if (whence & SEEK_HOLE && dst_clu == BAT_ENTRY_NONE) + break; + + clu++; + } + + result = to_bytes(CLU_TO_SEC(ploop, clu) - ploop->skip_off); + if (result < offset) + result = offset; + + if (clu >= ploop->nr_bat_entries) { + if (whence & SEEK_DATA) + result = -ENXIO; + } + + return result; +} diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c index 647716ad47ba..416e0c215392 100644 --- a/drivers/md/dm-ploop-target.c +++ b/drivers/md/dm-ploop-target.c @@ -619,6 +619,7 @@ static struct target_type ploop_target = { .preresume = ploop_preresume, .clone_and_map_rq = ploop_clone_and_map, .status = ploop_status, + .llseek_hole = ploop_llseek_hole, }; static int __init dm_ploop_init(void) diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h index 9c9fc16a0de5..c52ca5d3f4ce 100644 --- a/drivers/md/dm-ploop.h +++ b/drivers/md/dm-ploop.h @@ -599,4 +599,5 @@ extern void ploop_index_wb_init(struct ploop_index_wb *piwb, extern void ploop_call_rw_iter(struct file *file, loff_t pos, unsigned rw, struct iov_iter *iter, struct pio *pio); extern void ploop_enospc_timer(struct timer_list *timer); +extern loff_t ploop_llseek_hole(struct dm_target *ti, loff_t offset, int whence); #endif /* __DM_PLOOP_H */ -- 2.39.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel