md: forbid a RAID5 from having both a bitmap and a journal.
authorNeilBrown <neilb@suse.com>
Tue, 17 Oct 2017 03:24:09 +0000 (14:24 +1100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Dec 2017 10:26:38 +0000 (11:26 +0100)
commit 230b55fa8d64007339319539f8f8e68114d08529 upstream.

Having both a bitmap and a journal is pointless.
Attempting to do so can corrupt the bitmap if the journal
replay happens before the bitmap is initialized.
Rather than try to avoid this corruption, simply
refuse to allow arrays with both a bitmap and a journal.
So:
 - if raid5_run sees both are present, fail.
 - if adding a bitmap finds a journal is present, fail
 - if adding a journal finds a bitmap is present, fail.

Signed-off-by: NeilBrown <neilb@suse.com>
Tested-by: Joshua Kinard <kumba@gentoo.org>
Acked-by: Joshua Kinard <kumba@gentoo.org>
Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/raid5.c

index cae57b5be817a230d4f2097cdbc2eaab0a94e5e1..f425905c97fa93c141673c6bc6d8fb0620a0fb09 100644 (file)
@@ -1816,6 +1816,12 @@ struct bitmap *bitmap_create(struct mddev *mddev, int slot)
 
        BUG_ON(file && mddev->bitmap_info.offset);
 
+       if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) {
+               pr_notice("md/raid:%s: array with journal cannot have bitmap\n",
+                         mdname(mddev));
+               return ERR_PTR(-EBUSY);
+       }
+
        bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
        if (!bitmap)
                return ERR_PTR(-ENOMEM);
index e019cf8c0d131ae392ef1429961dda98c99349f5..98ea86309ceb44e3681277f8796f8ff5c8fda141 100644 (file)
@@ -6362,7 +6362,7 @@ static int add_new_disk(struct mddev *mddev, mdu_disk_info_t *info)
                                        break;
                                }
                        }
-                       if (has_journal) {
+                       if (has_journal || mddev->bitmap) {
                                export_rdev(rdev);
                                return -EBUSY;
                        }
index 928e24a071338ab6e1fe7668c8caa42b2803ccfe..7aed69a4f6552944f021828c345af704fa1846cb 100644 (file)
@@ -7156,6 +7156,13 @@ static int raid5_run(struct mddev *mddev)
                        min_offset_diff = diff;
        }
 
+       if ((test_bit(MD_HAS_JOURNAL, &mddev->flags) || journal_dev) &&
+           (mddev->bitmap_info.offset || mddev->bitmap_info.file)) {
+               pr_notice("md/raid:%s: array cannot have both journal and bitmap\n",
+                         mdname(mddev));
+               return -EINVAL;
+       }
+
        if (mddev->reshape_position != MaxSector) {
                /* Check that we can continue the reshape.
                 * Difficulties arise if the stripe we would write to