[Devel] [PATCH RH8 03/14] push_backup: Add pending_map

Kirill Tkhai ktkhai at virtuozzo.com
Mon Sep 6 18:34:24 MSK 2021


This is a map of clusters with pending requests.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-push-backup.c |   30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/md/dm-push-backup.c b/drivers/md/dm-push-backup.c
index b6b4beda422c..a9b5d264b493 100644
--- a/drivers/md/dm-push-backup.c
+++ b/drivers/md/dm-push-backup.c
@@ -35,6 +35,7 @@ struct push_backup {
 	bool suspended;
 	void *map;
 	u64 map_bits;
+	void *pending_map;
 
 	struct rb_root rb_root;
 	struct list_head pending;
@@ -248,6 +249,7 @@ static bool postpone_if_required_for_backup(struct push_backup *pb,
 	link_node_pbio(&pb->rb_root, pbio, clu);
 	first = list_empty(&pb->pending);
 	list_add_tail(&pbio->list, &pb->pending);
+	set_bit(clu, pb->pending_map);
 unlock:
 	spin_unlock_irqrestore(&pb->lock, flags);
 
@@ -302,8 +304,8 @@ static bool msg_wants_down_read(const char *cmd)
 static int setup_pb(struct push_backup *pb, void __user *mask, int timeout)
 {
 	u64 i, map_bits, clus = pb->nr_clus;
+	void *map, *pending_map;
 	size_t size;
-	void *map;
 
 	pb->deadline_jiffies = S64_MAX;
 	pb->timeout_in_jiffies = timeout * HZ;
@@ -312,8 +314,9 @@ static int setup_pb(struct push_backup *pb, void __user *mask, int timeout)
 	size = ALIGN(size, sizeof(unsigned long));
 
 	map = kvzalloc(size, GFP_KERNEL);
-	if (!map)
-		return -ENOMEM;
+	pending_map = kvzalloc(size, GFP_KERNEL);
+	if (!map || !pending_map)
+		goto err;
 
 	if (!mask) {
 		/* Full backup */
@@ -332,11 +335,13 @@ static int setup_pb(struct push_backup *pb, void __user *mask, int timeout)
 	spin_lock_irq(&pb->lock);
 	pb->map = map;
 	pb->map_bits = map_bits;
+	pb->pending_map = pending_map;
 	pb->alive = true;
 	spin_unlock_irq(&pb->lock);
 	return 0;
 err:
 	kvfree(map);
+	kvfree(pending_map);
 	return -EFAULT;
 }
 
@@ -360,7 +365,7 @@ static int push_backup_start(struct push_backup *pb, u64 timeout,
 static int push_backup_stop(struct push_backup *pb,
 			    char *result, unsigned int maxlen)
 {
-	void *map = NULL;
+	void *map = NULL, *pending_map = NULL;
 
 	if (!pb->map)
 		return -EBADF;
@@ -373,9 +378,11 @@ static int push_backup_stop(struct push_backup *pb,
 
 	spin_lock_irq(&pb->lock);
 	swap(pb->map, map);
+	swap(pb->pending_map, pending_map);
 	pb->timeout_in_jiffies = 0;
 	spin_unlock_irq(&pb->lock);
 	kvfree(map);
+	kvfree(pending_map);
 	return 0;
 }
 
@@ -458,9 +465,14 @@ static int push_backup_write(struct push_backup *pb,
 		return -ESTALE;
 	}
 
-	for (i = clu; i < clu + nr; i++)
-		clear_bit(i, pb->map);
-	pb->map_bits -= nr;
+	for (i = clu; i < clu + nr; i++) {
+		if (test_bit(i, pb->map)) {
+			clear_bit(i, pb->map);
+			clear_bit(i, pb->pending_map);
+			pb->map_bits--;
+		}
+	}
+
 	finished = (pb->map_bits == 0);
 
 	for (i = 0; i < nr; i++) {
@@ -574,8 +586,8 @@ static void pb_destroy(struct push_backup *pb)
 	del_timer_sync(&pb->deadline_timer);
 	if (pb->wq)
 		destroy_workqueue(pb->wq);
-	if (pb->map) /* stop was not called */
-		kvfree(pb->map);
+	kvfree(pb->map); /* Is's not zero if stop was not called */
+	kvfree(pb->pending_map);
 	if (pb->origin_dev)
 		dm_put_device(pb->ti, pb->origin_dev);
 	kfree(pb);




More information about the Devel mailing list