|
29 | 29 | #include <linux/seq_file.h> |
30 | 30 | #include <trace/events/block.h> |
31 | 31 | #include "md.h" |
32 | | -#include "bitmap.h" |
| 32 | +#include "md-bitmap.h" |
33 | 33 |
|
34 | 34 | static inline char *bmname(struct bitmap *bitmap) |
35 | 35 | { |
@@ -459,7 +459,11 @@ void bitmap_update_sb(struct bitmap *bitmap) |
459 | 459 | /* rocking back to read-only */ |
460 | 460 | bitmap->events_cleared = bitmap->mddev->events; |
461 | 461 | sb->events_cleared = cpu_to_le64(bitmap->events_cleared); |
462 | | - sb->state = cpu_to_le32(bitmap->flags); |
| 462 | + /* |
| 463 | + * clear BITMAP_WRITE_ERROR bit to protect against the case that |
| 464 | + * a bitmap write error occurred but the later writes succeeded. |
| 465 | + */ |
| 466 | + sb->state = cpu_to_le32(bitmap->flags & ~BIT(BITMAP_WRITE_ERROR)); |
463 | 467 | /* Just in case these have been changed via sysfs: */ |
464 | 468 | sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ); |
465 | 469 | sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind); |
@@ -625,7 +629,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) |
625 | 629 | err = read_sb_page(bitmap->mddev, |
626 | 630 | offset, |
627 | 631 | sb_page, |
628 | | - 0, PAGE_SIZE); |
| 632 | + 0, sizeof(bitmap_super_t)); |
629 | 633 | } |
630 | 634 | if (err) |
631 | 635 | return err; |
@@ -1816,6 +1820,12 @@ struct bitmap *bitmap_create(struct mddev *mddev, int slot) |
1816 | 1820 |
|
1817 | 1821 | BUG_ON(file && mddev->bitmap_info.offset); |
1818 | 1822 |
|
| 1823 | + if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) { |
| 1824 | + pr_notice("md/raid:%s: array with journal cannot have bitmap\n", |
| 1825 | + mdname(mddev)); |
| 1826 | + return ERR_PTR(-EBUSY); |
| 1827 | + } |
| 1828 | + |
1819 | 1829 | bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL); |
1820 | 1830 | if (!bitmap) |
1821 | 1831 | return ERR_PTR(-ENOMEM); |
@@ -2123,7 +2133,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, |
2123 | 2133 | if (store.sb_page && bitmap->storage.sb_page) |
2124 | 2134 | memcpy(page_address(store.sb_page), |
2125 | 2135 | page_address(bitmap->storage.sb_page), |
2126 | | - PAGE_SIZE); |
| 2136 | + sizeof(bitmap_super_t)); |
2127 | 2137 | bitmap_file_unmap(&bitmap->storage); |
2128 | 2138 | bitmap->storage = store; |
2129 | 2139 |
|
@@ -2152,6 +2162,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, |
2152 | 2162 | for (k = 0; k < page; k++) { |
2153 | 2163 | kfree(new_bp[k].map); |
2154 | 2164 | } |
| 2165 | + kfree(new_bp); |
2155 | 2166 |
|
2156 | 2167 | /* restore some fields from old_counts */ |
2157 | 2168 | bitmap->counts.bp = old_counts.bp; |
@@ -2202,6 +2213,14 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, |
2202 | 2213 | block += old_blocks; |
2203 | 2214 | } |
2204 | 2215 |
|
| 2216 | + if (bitmap->counts.bp != old_counts.bp) { |
| 2217 | + unsigned long k; |
| 2218 | + for (k = 0; k < old_counts.pages; k++) |
| 2219 | + if (!old_counts.bp[k].hijacked) |
| 2220 | + kfree(old_counts.bp[k].map); |
| 2221 | + kfree(old_counts.bp); |
| 2222 | + } |
| 2223 | + |
2205 | 2224 | if (!init) { |
2206 | 2225 | int i; |
2207 | 2226 | while (block < (chunks << chunkshift)) { |
|
0 commit comments