[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