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)
committerShaohua Li <shli@fb.com>
Thu, 2 Nov 2017 04:32:18 +0000 (21:32 -0700)
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.

Cc: stable@vger.kernel.org (4.10+)
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>
drivers/md/md-bitmap.c
drivers/md/md.c
drivers/md/raid5.c

index b843b53b0f65a8184c79782db58aa404e7785e49..d1b3b60669ea6380efccd13c27eef7904b9fa8a0 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 97afb28c6f511968c69a0b507c2437e836561d0a..6f25e3f1a1cfc64d92b3941190e525a61702984a 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 a21dbd22a2fb85fc56c35ebfa7b0cf0e332c8341..a8732955f130285a11f32cb4092e2dd273242150 100644 (file)
@@ -7159,6 +7159,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