[Devel] [PATCH vz9] ploop: add interface to request write out BAT
Alexander Atanasov
alexander.atanasov at virtuozzo.com
Mon May 20 14:49:26 MSK 2024
It is possible that BAT is corrupted on disk but
we have a good copy of it in RAM. Add dmsetup
message to write it out to file write_bat_to_file.
This is very basic interface and it must be used
as a last resort.
https://virtuozzo.atlassian.net/browse/PSBM-156501
Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
---
drivers/md/dm-ploop-cmd.c | 48 +++++++++++++++++++++++++++++++++++++++
drivers/md/dm-ploop-map.c | 4 ++--
drivers/md/dm-ploop.h | 3 +++
3 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index 88519f590148b..71f854c509f82 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -280,6 +280,45 @@ static void ploop_make_md_wb(struct ploop *ploop, struct md_page *md)
write_unlock_irq(&ploop->bat_rwlock);
}
+/* write all md to disk */
+static u32 ploop_rewrite_bat_from_memory(struct ploop *ploop)
+{
+ struct rb_node *node;
+ struct md_page *md;
+ struct ploop_index_wb *piwb;
+ blk_status_t bi_status;
+ DECLARE_COMPLETION_ONSTACK(comp);
+ int err;
+
+ ploop_suspend_submitting_pios(ploop);
+ ploop_for_each_md_page(ploop, md, node) {
+ /* we have the page and want to write so prepare bat update */
+ err = ploop_prepare_bat_update(ploop, md, PIWB_TYPE_ALLOC);
+ /* does wb_init ploop_index_wb_init */
+ if (err) {
+ /* most likely no memory, notify user he may retry */
+ printk(KERN_ERR "MD prepare WB failed: %d\n", err);
+ }
+ /* mark md for writeback */
+ ploop_make_md_wb(ploop, md);
+ /* piwb is prepared in md->piwb */
+ piwb = md->piwb;
+ init_completion(&comp);
+ piwb->comp = ∁
+ piwb->comp_bi_status = &bi_status;
+ /* Write index to disk */
+ ploop_index_wb_submit(ploop, piwb);
+ wait_for_completion(&comp);
+ /* piwb is freed on completion */
+ if (bi_status) {
+ printk(KERN_ERR "MD WB failed: %d\n", blk_status_to_errno(bi_status));
+ }
+ }
+ ploop_resume_submitting_pios(ploop);
+
+ return 0;
+}
+
static int ploop_grow_relocate_cluster(struct ploop *ploop,
struct ploop_cmd *cmd)
{
@@ -1086,6 +1125,11 @@ static int ploop_check_delta_before_flip(struct ploop *ploop, struct file *file)
return ret;
}
+static int ploop_write_bat_to_file(struct ploop *ploop)
+{
+ return ploop_rewrite_bat_from_memory(ploop);
+}
+
static int ploop_flip_upper_deltas(struct ploop *ploop)
{
struct file *file;
@@ -1197,6 +1241,10 @@ int ploop_message(struct dm_target *ti, unsigned int argc, char **argv,
if (argc != 1)
goto unlock;
ret = ploop_flip_upper_deltas(ploop);
+ } else if (!strcmp(argv[0], "write_bat_to_file")) {
+ if (argc != 1)
+ goto unlock;
+ ret = ploop_write_bat_to_file(ploop);
} else {
ret = -ENOTSUPP;
}
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index ea04b3e53567e..7e16005f1e5c9 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -813,7 +813,7 @@ static void ploop_advance_local_after_bat_wb(struct ploop *ploop,
ploop_dispatch_pios(ploop, NULL, &list);
}
-static void ploop_free_piwb(struct ploop_index_wb *piwb)
+void ploop_free_piwb(struct ploop_index_wb *piwb)
{
ploop_free_pio(piwb->ploop, piwb->pio);
put_page(piwb->bat_page);
@@ -889,7 +889,7 @@ static void ploop_bat_write_complete(struct ploop_index_wb *piwb,
ploop_put_piwb(piwb);
}
-static int ploop_prepare_bat_update(struct ploop *ploop, struct md_page *md,
+int ploop_prepare_bat_update(struct ploop *ploop, struct md_page *md,
enum piwb_type type)
{
u32 i, off, last, *bat_entries;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index db36687c81696..67dbf8abd4e41 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -559,6 +559,8 @@ extern void ploop_free_md_page(struct md_page *md);
extern void ploop_free_md_pages_tree(struct rb_root *root);
extern bool ploop_try_update_bat_entry(struct ploop *ploop, u32 clu,
u8 level, u32 dst_clu);
+extern int ploop_prepare_bat_update(struct ploop *ploop, struct md_page *md,
+ enum piwb_type type);
extern int ploop_add_delta(struct ploop *ploop, u32 level,
struct file *file, bool is_raw);
@@ -597,6 +599,7 @@ extern int ploop_read_delta_metadata(struct ploop *ploop, struct file *file,
struct rb_root *md_root, u32 *delta_nr_be);
extern void ploop_index_wb_init(struct ploop_index_wb *piwb,
struct ploop *ploop);
+extern void ploop_free_piwb(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);
--
2.43.0
More information about the Devel
mailing list