On 5.09.23 11:59, Andrey Zhadchenko wrote:
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>

---
v3: remove edge case handling as it is now done by generic blockdev
helper

  drivers/md/dm-ploop-map.c    | 42 ++++++++++++++++++++++++++++++++++++
  drivers/md/dm-ploop-target.c |  1 +
  drivers/md/dm-ploop.h        |  1 +
  3 files changed, 44 insertions(+)

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 3f0803cb8e47..e806cf531b2f 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -1989,3 +1989,45 @@ 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);
+       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 */


LGTM

--
Regards,
Alexander Atanasov

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to