]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/md/md-bitmap.c
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md
[mirror_ubuntu-bionic-kernel.git] / drivers / md / md-bitmap.c
index b843b53b0f65a8184c79782db58aa404e7785e49..239c7bb3929ba0ac58df67ae9b213ceb62cd7d41 100644 (file)
@@ -368,7 +368,7 @@ static int read_page(struct file *file, unsigned long index,
        pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
                 (unsigned long long)index << PAGE_SHIFT);
 
-       bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0);
+       bh = alloc_page_buffers(page, 1<<inode->i_blkbits, false);
        if (!bh) {
                ret = -ENOMEM;
                goto out;
@@ -459,7 +459,11 @@ void bitmap_update_sb(struct bitmap *bitmap)
                /* rocking back to read-only */
                bitmap->events_cleared = bitmap->mddev->events;
        sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
-       sb->state = cpu_to_le32(bitmap->flags);
+       /*
+        * clear BITMAP_WRITE_ERROR bit to protect against the case that
+        * a bitmap write error occurred but the later writes succeeded.
+        */
+       sb->state = cpu_to_le32(bitmap->flags & ~BIT(BITMAP_WRITE_ERROR));
        /* Just in case these have been changed via sysfs: */
        sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
        sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
@@ -1816,6 +1820,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);
@@ -2152,6 +2162,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
                                for (k = 0; k < page; k++) {
                                        kfree(new_bp[k].map);
                                }
+                               kfree(new_bp);
 
                                /* restore some fields from old_counts */
                                bitmap->counts.bp = old_counts.bp;
@@ -2202,6 +2213,14 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
                block += old_blocks;
        }
 
+       if (bitmap->counts.bp != old_counts.bp) {
+               unsigned long k;
+               for (k = 0; k < old_counts.pages; k++)
+                       if (!old_counts.bp[k].hijacked)
+                               kfree(old_counts.bp[k].map);
+               kfree(old_counts.bp);
+       }
+
        if (!init) {
                int i;
                while (block < (chunks << chunkshift)) {