Blame SOURCES/0015-thin-Clear-superblock-flags-in-restored-metadata.patch

5a5b1b
From 637fc5ec0869145d1b5272ee0e1e51e21517be79 Mon Sep 17 00:00:00 2001
5a5b1b
From: Ming-Hung Tsai <mtsai@redhat.com>
5a5b1b
Date: Mon, 7 Jun 2021 14:54:04 +0800
5a5b1b
Subject: [PATCH] [thin] Clear superblock flags in restored metadata
5a5b1b
5a5b1b
The needs_check flag is unnecessary for a restored metadata since
5a5b1b
it is assumed clean and has no errors
5a5b1b
5a5b1b
(cherry picked from commit 62536defc86f12363e4178ee5a2cefc40fa416d9)
5a5b1b
---
5a5b1b
 ft-lib/bcache.c                            | 20 ++++++++++---
5a5b1b
 functional-tests/thin-functional-tests.scm | 46 ++++++++++++++++++++++++++++++
5a5b1b
 functional-tests/thin/xml.scm              |  4 +--
5a5b1b
 thin-provisioning/restore_emitter.cc       |  2 +-
5a5b1b
 4 files changed, 65 insertions(+), 7 deletions(-)
5a5b1b
5a5b1b
diff --git a/ft-lib/bcache.c b/ft-lib/bcache.c
5a5b1b
index ee5b6c5..1c63377 100644
5a5b1b
--- a/ft-lib/bcache.c
5a5b1b
+++ b/ft-lib/bcache.c
5a5b1b
@@ -201,8 +201,10 @@ static int engine_issue(struct io_engine *e, int fd, enum dir d,
5a5b1b
 
5a5b1b
 	cb_array[0] = &cb->cb;
5a5b1b
 	r = io_submit(e->aio_context, 1, cb_array);
5a5b1b
-	if (r < 0)
5a5b1b
+	if (r < 0) {
5a5b1b
+		warn("io_submit failed, ret=%d\n", r);
5a5b1b
 		cb_free(e->cbs, cb);
5a5b1b
+	}
5a5b1b
 
5a5b1b
 	return r;
5a5b1b
 }
5a5b1b
@@ -219,7 +221,7 @@ static int engine_wait(struct io_engine *e, struct timespec *ts, complete_fn fn)
5a5b1b
 	memset(&event, 0, sizeof(event));
5a5b1b
 	r = io_getevents(e->aio_context, 1, MAX_IO, event, ts);
5a5b1b
 	if (r < 0) {
5a5b1b
-		warn("io_getevents failed");
5a5b1b
+		warn("io_getevents failed, ret=%d\n", r);
5a5b1b
 		return r;
5a5b1b
 	}
5a5b1b
 
5a5b1b
@@ -514,12 +516,22 @@ static void relink(struct block *b)
5a5b1b
  */
5a5b1b
 static int issue_low_level(struct block *b, enum dir d)
5a5b1b
 {
5a5b1b
+	int r;
5a5b1b
 	struct bcache *cache = b->cache;
5a5b1b
 	sector_t sb = b->index * cache->block_sectors;
5a5b1b
 	sector_t se = sb + cache->block_sectors;
5a5b1b
 	set_flags(b, BF_IO_PENDING);
5a5b1b
+	cache->nr_io_pending++;
5a5b1b
+	list_add_tail(&b->list, &cache->io_pending);
5a5b1b
 
5a5b1b
-	return engine_issue(cache->engine, cache->fd, d, sb, se, b->data, b);
5a5b1b
+	r = engine_issue(cache->engine, cache->fd, d, sb, se, b->data, b);
5a5b1b
+	if (r < 0) {
5a5b1b
+		list_del(&b->list);
5a5b1b
+		cache->nr_io_pending--;
5a5b1b
+		clear_flags(b, BF_IO_PENDING);
5a5b1b
+		return r;
5a5b1b
+	}
5a5b1b
+	return 0;
5a5b1b
 }
5a5b1b
 
5a5b1b
 static void issue_read(struct block *b)
5a5b1b
@@ -709,7 +721,7 @@ struct bcache *bcache_simple(const char *path, unsigned nr_cache_blocks)
5a5b1b
 	int r;
5a5b1b
 	struct stat info;
5a5b1b
 	struct bcache *cache;
5a5b1b
-	int fd = open(path, O_DIRECT | O_EXCL | O_RDONLY);
5a5b1b
+	int fd = open(path, O_DIRECT | O_EXCL | O_RDWR);
5a5b1b
 	uint64_t s;
5a5b1b
 
5a5b1b
 	if (fd < 0) {
5a5b1b
diff --git a/functional-tests/thin-functional-tests.scm b/functional-tests/thin-functional-tests.scm
5a5b1b
index 55b0e60..fcabddf 100644
5a5b1b
--- a/functional-tests/thin-functional-tests.scm
5a5b1b
+++ b/functional-tests/thin-functional-tests.scm
5a5b1b
@@ -12,6 +12,7 @@
5a5b1b
     (process)
5a5b1b
     (scenario-string-constants)
5a5b1b
     (temp-file)
5a5b1b
+    (thin metadata)
5a5b1b
     (thin xml)
5a5b1b
     (srfi s8 receive))
5a5b1b
 
5a5b1b
@@ -30,6 +31,12 @@
5a5b1b
        (with-temp-file-containing ((v "thin.xml" (fmt #f (generate-xml 10 1000))))
5a5b1b
                                   b1 b2 ...))))
5a5b1b
 
5a5b1b
+  (define-syntax with-needs-check-thin-xml
5a5b1b
+    (syntax-rules ()
5a5b1b
+      ((_ (v) b1 b2 ...)
5a5b1b
+       (with-temp-file-containing ((v "thin.xml" (fmt #f (generate-xml 10 1000 1))))
5a5b1b
+                                  b1 b2 ...))))
5a5b1b
+
5a5b1b
   (define-syntax with-valid-metadata
5a5b1b
     (syntax-rules ()
5a5b1b
       ((_ (md) b1 b2 ...)
5a5b1b
@@ -63,6 +70,28 @@
5a5b1b
          (damage-superblock md)
5a5b1b
          b1 b2 ...))))
5a5b1b
 
5a5b1b
+  (define superblock-salt 160774)
5a5b1b
+  (define (set-needs-check-flag md)
5a5b1b
+    (with-bcache (cache md 1)
5a5b1b
+      (with-block (b cache 0 (get-flags dirty))
5a5b1b
+        (let ((sb (block->superblock b)))
5a5b1b
+          (ftype-set! ThinSuperblock (flags) sb 1)
5a5b1b
+          ;;;;;; Update the csum manually since the block validator for ft-lib is not ready
5a5b1b
+          (let ((csum (checksum-block b (ftype-sizeof unsigned-32) superblock-salt)))
5a5b1b
+            (ftype-set! ThinSuperblock (csum) sb csum))))))
5a5b1b
+
5a5b1b
+  (define (get-superblock-flags md)
5a5b1b
+    (with-bcache (cache md 1)
5a5b1b
+      (with-block (b cache 0 (get-flags))
5a5b1b
+        (let ((sb (block->superblock b)))
5a5b1b
+          (ftype-ref ThinSuperblock (flags) sb)))))
5a5b1b
+
5a5b1b
+  (define (assert-metadata-needs-check md)
5a5b1b
+    (assert-equal (get-superblock-flags md) 1))
5a5b1b
+
5a5b1b
+  (define (assert-metadata-clean md)
5a5b1b
+    (assert-equal (get-superblock-flags md) 0))
5a5b1b
+
5a5b1b
   ;; We have to export something that forces all the initialisation expressions
5a5b1b
   ;; to run.
5a5b1b
   (define (register-thin-tests) #t)
5a5b1b
@@ -173,6 +202,13 @@
5a5b1b
   ;;;-----------------------------------------------------------
5a5b1b
   ;;; thin_restore scenarios
5a5b1b
   ;;;-----------------------------------------------------------
5a5b1b
+  (define-scenario (thin-restore clear-needs-check-flag)
5a5b1b
+    "thin_restore should clear the needs-check flag"
5a5b1b
+    (with-empty-metadata (md)
5a5b1b
+      (with-needs-check-thin-xml (xml)
5a5b1b
+        (run-ok-rcv (stdout _) (thin-restore "-i" xml "-o" md "-q")
5a5b1b
+          (assert-eof stdout)))
5a5b1b
+      (assert-metadata-clean md)))
5a5b1b
 
5a5b1b
   (define-scenario (thin-restore print-version-v)
5a5b1b
     "print help (-V)"
5a5b1b
@@ -439,6 +475,16 @@
5a5b1b
   ;;;-----------------------------------------------------------
5a5b1b
   ;;; thin_repair scenarios
5a5b1b
   ;;;-----------------------------------------------------------
5a5b1b
+  (define-scenario (thin-repair clear-needs-check-flag)
5a5b1b
+    "thin_repair should clear the needs-check flag"
5a5b1b
+    (with-valid-metadata (md1)
5a5b1b
+      (set-needs-check-flag md1)
5a5b1b
+      (assert-metadata-needs-check md1)
5a5b1b
+      (with-empty-metadata (md2)
5a5b1b
+        (run-ok-rcv (stdout stderr) (thin-repair "-i" md1 "-o" md2)
5a5b1b
+          (assert-eof stderr))
5a5b1b
+        (assert-metadata-clean md2))))
5a5b1b
+
5a5b1b
   (define-scenario (thin-repair dont-repair-xml)
5a5b1b
     "Fails gracefully if run on XML rather than metadata"
5a5b1b
     (with-thin-xml (xml)
5a5b1b
diff --git a/functional-tests/thin/xml.scm b/functional-tests/thin/xml.scm
5a5b1b
index 551a536..7d9314b 100644
5a5b1b
--- a/functional-tests/thin/xml.scm
5a5b1b
+++ b/functional-tests/thin/xml.scm
5a5b1b
@@ -22,7 +22,7 @@
5a5b1b
                                (length . ,nr-mappings)
5a5b1b
                                (time . 1)))))
5a5b1b
 
5a5b1b
-  (define (generate-xml max-thins max-mappings)
5a5b1b
+  (define (generate-xml max-thins max-mappings . needs-check)
5a5b1b
     (let ((nr-thins ((make-uniform-generator 1 max-thins)))
5a5b1b
           (nr-mappings-g (make-uniform-generator (div-down max-mappings 2)
5a5b1b
                                                  max-mappings)))
5a5b1b
@@ -30,7 +30,7 @@
5a5b1b
        (tag 'superblock `((uuid . "")
5a5b1b
                          (time . 1)
5a5b1b
                          (transaction . 1)
5a5b1b
-                         (flags . 0)
5a5b1b
+                         (flags . ,(if (null? needs-check) 0 (car needs-check)))
5a5b1b
                          (version . 2)
5a5b1b
                          (data-block-size . 128)
5a5b1b
                          (nr-data-blocks . ,(apply + nr-mappings)))
5a5b1b
diff --git a/thin-provisioning/restore_emitter.cc b/thin-provisioning/restore_emitter.cc
5a5b1b
index 6e95a53..114ba4f 100644
5a5b1b
--- a/thin-provisioning/restore_emitter.cc
5a5b1b
+++ b/thin-provisioning/restore_emitter.cc
5a5b1b
@@ -57,7 +57,7 @@ namespace {
5a5b1b
 			memcpy(&sb.uuid_, uuid.c_str(), std::min(sizeof(sb.uuid_), uuid.length()));
5a5b1b
 			sb.time_ = time;
5a5b1b
 			sb.trans_id_ = trans_id;
5a5b1b
-			sb.flags_ = flags ? *flags : 0;
5a5b1b
+			sb.flags_ = 0;
5a5b1b
 			sb.version_ = version ? *version : 1;
5a5b1b
 			sb.data_block_size_ = data_block_size;
5a5b1b
 			sb.metadata_snap_ = metadata_snap ? *metadata_snap : 0;
5a5b1b
-- 
5a5b1b
1.8.3.1
5a5b1b