aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-21 23:55:06 -0400
committerNeilBrown <neilb@suse.de>2012-05-21 23:55:06 -0400
commitbf07bb7d5be813630d3530be274b3324f85e310c (patch)
tree22fc12593b6d377ceb7b94c42d346f2946319c48 /drivers/md/bitmap.c
parentbc0934f0477d0a2350a478004799d9c064923b7b (diff)
md/bitmap: disentangle two different 'pending' flags.
There are two different 'pending' concepts in the handling of the write intent bitmap. Firstly, a 'page' from the bitmap (which container PAGE_SIZE*8 bits) may have changes (bits cleared) that should be written in due course. There is no hurry for these and the page will transition from PENDING to NEEDWRITE and will then be written, though if it ever becomes DIRTY it will be written much sooner and PENDING will be cleared. Secondly, a page of counters - which contains PAGE_SIZE/2 counters, one for each bit, can usefully have a 'pending' flag which indicates if any of the counters are low (2 or 1) and ready to be processed by bitmap_daemon_work(). If this flag is clear we can skip the whole page. These two concepts are currently combined in the bitmap-file flag. This causes a tighter connection between the counters and the bitmap file than I would like - as I want to add some flexibility to the bitmap file. So introduce a new flag with the page-of-counters, and rewrite bitmap_daemon_work() so that it handles the two different 'pending' concepts separately. This also allows us to clear BITMAP_PAGE_PENDING when we write out a dirty page, which may occasionally reduce the number of times we write a page. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c213
1 files changed, 112 insertions, 101 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 17e2b472e16d..c7784a985676 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -883,6 +883,8 @@ void bitmap_unplug(struct bitmap *bitmap)
883 need_write = test_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); 883 need_write = test_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
884 clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY); 884 clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
885 clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); 885 clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
886 if (dirty || need_write)
887 clear_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
886 if (dirty) 888 if (dirty)
887 wait = 1; 889 wait = 1;
888 spin_unlock_irqrestore(&bitmap->lock, flags); 890 spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1086,6 +1088,17 @@ static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc)
1086 bitmap->bp[page].count += inc; 1088 bitmap->bp[page].count += inc;
1087 bitmap_checkfree(bitmap, page); 1089 bitmap_checkfree(bitmap, page);
1088} 1090}
1091
1092static void bitmap_set_pending(struct bitmap *bitmap, sector_t offset)
1093{
1094 sector_t chunk = offset >> bitmap->chunkshift;
1095 unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
1096 struct bitmap_page *bp = &bitmap->bp[page];
1097
1098 if (!bp->pending)
1099 bp->pending = 1;
1100}
1101
1089static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, 1102static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
1090 sector_t offset, sector_t *blocks, 1103 sector_t offset, sector_t *blocks,
1091 int create); 1104 int create);
@@ -1099,8 +1112,8 @@ void bitmap_daemon_work(struct mddev *mddev)
1099{ 1112{
1100 struct bitmap *bitmap; 1113 struct bitmap *bitmap;
1101 unsigned long j; 1114 unsigned long j;
1115 unsigned long nextpage;
1102 unsigned long flags; 1116 unsigned long flags;
1103 struct page *page = NULL, *lastpage = NULL;
1104 sector_t blocks; 1117 sector_t blocks;
1105 void *paddr; 1118 void *paddr;
1106 1119
@@ -1124,114 +1137,120 @@ void bitmap_daemon_work(struct mddev *mddev)
1124 } 1137 }
1125 bitmap->allclean = 1; 1138 bitmap->allclean = 1;
1126 1139
1140 /* Any file-page which is PENDING now needs to be written.
1141 * So set NEEDWRITE now, then after we make any last-minute changes
1142 * we will write it.
1143 */
1127 spin_lock_irqsave(&bitmap->lock, flags); 1144 spin_lock_irqsave(&bitmap->lock, flags);
1145 if (!bitmap->filemap)
1146 /* error or shutdown */
1147 goto out;
1148
1149 for (j = 0; j < bitmap->file_pages; j++)
1150 if (test_page_attr(bitmap, bitmap->filemap[j],
1151 BITMAP_PAGE_PENDING)) {
1152 set_page_attr(bitmap, bitmap->filemap[j],
1153 BITMAP_PAGE_NEEDWRITE);
1154 clear_page_attr(bitmap, bitmap->filemap[j],
1155 BITMAP_PAGE_PENDING);
1156 }
1157
1158 if (bitmap->need_sync &&
1159 mddev->bitmap_info.external == 0) {
1160 /* Arrange for superblock update as well as
1161 * other changes */
1162 bitmap_super_t *sb;
1163 bitmap->need_sync = 0;
1164 sb = kmap_atomic(bitmap->sb_page);
1165 sb->events_cleared =
1166 cpu_to_le64(bitmap->events_cleared);
1167 kunmap_atomic(sb);
1168 set_page_attr(bitmap, bitmap->sb_page, BITMAP_PAGE_NEEDWRITE);
1169 }
1170 /* Now look at the bitmap counters and if any are '2' or '1',
1171 * decrement and handle accordingly.
1172 */
1173 nextpage = 0;
1128 for (j = 0; j < bitmap->chunks; j++) { 1174 for (j = 0; j < bitmap->chunks; j++) {
1129 bitmap_counter_t *bmc; 1175 bitmap_counter_t *bmc;
1130 if (!bitmap->filemap)
1131 /* error or shutdown */
1132 break;
1133 1176
1134 page = filemap_get_page(bitmap, j); 1177 if (j == nextpage) {
1135 1178 nextpage += PAGE_COUNTER_RATIO;
1136 if (page != lastpage) { 1179 if (!bitmap->bp[j >> PAGE_COUNTER_SHIFT].pending) {
1137 /* skip this page unless it's marked as needing cleaning */ 1180 j |= PAGE_COUNTER_MASK;
1138 if (!test_page_attr(bitmap, page, BITMAP_PAGE_PENDING)) {
1139 int need_write = test_page_attr(bitmap, page,
1140 BITMAP_PAGE_NEEDWRITE);
1141 if (need_write)
1142 clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
1143
1144 spin_unlock_irqrestore(&bitmap->lock, flags);
1145 if (need_write)
1146 write_page(bitmap, page, 0);
1147 spin_lock_irqsave(&bitmap->lock, flags);
1148 j |= (PAGE_BITS - 1);
1149 continue; 1181 continue;
1150 } 1182 }
1151 1183 bitmap->bp[j >> PAGE_COUNTER_SHIFT].pending = 0;
1152 /* grab the new page, sync and release the old */
1153 if (lastpage != NULL) {
1154 if (test_page_attr(bitmap, lastpage,
1155 BITMAP_PAGE_NEEDWRITE)) {
1156 clear_page_attr(bitmap, lastpage,
1157 BITMAP_PAGE_NEEDWRITE);
1158 spin_unlock_irqrestore(&bitmap->lock, flags);
1159 write_page(bitmap, lastpage, 0);
1160 } else {
1161 set_page_attr(bitmap, lastpage,
1162 BITMAP_PAGE_NEEDWRITE);
1163 bitmap->allclean = 0;
1164 spin_unlock_irqrestore(&bitmap->lock, flags);
1165 }
1166 } else
1167 spin_unlock_irqrestore(&bitmap->lock, flags);
1168 lastpage = page;
1169
1170 /* We are possibly going to clear some bits, so make
1171 * sure that events_cleared is up-to-date.
1172 */
1173 if (bitmap->need_sync &&
1174 mddev->bitmap_info.external == 0) {
1175 bitmap_super_t *sb;
1176 bitmap->need_sync = 0;
1177 sb = kmap_atomic(bitmap->sb_page);
1178 sb->events_cleared =
1179 cpu_to_le64(bitmap->events_cleared);
1180 kunmap_atomic(sb);
1181 write_page(bitmap, bitmap->sb_page, 1);
1182 }
1183 spin_lock_irqsave(&bitmap->lock, flags);
1184 if (!bitmap->need_sync)
1185 clear_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
1186 else
1187 bitmap->allclean = 0;
1188 } 1184 }
1189 bmc = bitmap_get_counter(bitmap, 1185 bmc = bitmap_get_counter(bitmap,
1190 (sector_t)j << bitmap->chunkshift, 1186 (sector_t)j << bitmap->chunkshift,
1191 &blocks, 0); 1187 &blocks, 0);
1192 if (!bmc) 1188
1189 if (!bmc) {
1193 j |= PAGE_COUNTER_MASK; 1190 j |= PAGE_COUNTER_MASK;
1194 else if (*bmc) { 1191 continue;
1195 if (*bmc == 1 && !bitmap->need_sync) { 1192 }
1196 /* we can clear the bit */ 1193 if (*bmc == 1 && !bitmap->need_sync) {
1197 *bmc = 0; 1194 /* We can clear the bit */
1198 bitmap_count_page(bitmap, 1195 struct page *page;
1199 (sector_t)j << bitmap->chunkshift, 1196 *bmc = 0;
1200 -1); 1197 bitmap_count_page(
1201 1198 bitmap,
1202 /* clear the bit */ 1199 (sector_t)j << bitmap->chunkshift,
1203 paddr = kmap_atomic(page); 1200 -1);
1204 if (bitmap->flags & BITMAP_HOSTENDIAN) 1201
1205 clear_bit(file_page_offset(bitmap, j), 1202 page = filemap_get_page(bitmap, j);
1206 paddr); 1203 paddr = kmap_atomic(page);
1207 else 1204 if (bitmap->flags & BITMAP_HOSTENDIAN)
1208 __clear_bit_le( 1205 clear_bit(file_page_offset(bitmap, j),
1209 file_page_offset(bitmap, 1206 paddr);
1210 j), 1207 else
1211 paddr); 1208 __clear_bit_le(file_page_offset(bitmap, j),
1212 kunmap_atomic(paddr); 1209 paddr);
1213 } else if (*bmc <= 2) { 1210 kunmap_atomic(paddr);
1214 *bmc = 1; /* maybe clear the bit next time */ 1211 if (!test_page_attr(bitmap, page,
1215 set_page_attr(bitmap, page, BITMAP_PAGE_PENDING); 1212 BITMAP_PAGE_NEEDWRITE)) {
1213 set_page_attr(bitmap, page,
1214 BITMAP_PAGE_PENDING);
1216 bitmap->allclean = 0; 1215 bitmap->allclean = 0;
1217 } 1216 }
1217 } else if (*bmc && *bmc <= 2) {
1218 *bmc = 1;
1219 bitmap_set_pending(
1220 bitmap,
1221 (sector_t)j << bitmap->chunkshift);
1222 bitmap->allclean = 0;
1218 } 1223 }
1219 } 1224 }
1220 spin_unlock_irqrestore(&bitmap->lock, flags);
1221 1225
1222 /* now sync the final page */ 1226 /* Now start writeout on any page in NEEDWRITE that isn't DIRTY.
1223 if (lastpage != NULL) { 1227 * DIRTY pages need to be written by bitmap_unplug so it can wait
1224 spin_lock_irqsave(&bitmap->lock, flags); 1228 * for them.
1225 if (test_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE)) { 1229 * If we find any DIRTY page we stop there and let bitmap_unplug
1226 clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); 1230 * handle all the rest. This is important in the case where
1227 spin_unlock_irqrestore(&bitmap->lock, flags); 1231 * the first blocking holds the superblock and it has been updated.
1228 write_page(bitmap, lastpage, 0); 1232 * We mustn't write any other blocks before the superblock.
1229 } else { 1233 */
1230 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); 1234 for (j = 0; j < bitmap->file_pages; j++) {
1231 bitmap->allclean = 0; 1235 struct page *page = bitmap->filemap[j];
1236
1237 if (test_page_attr(bitmap, page,
1238 BITMAP_PAGE_DIRTY))
1239 /* bitmap_unplug will handle the rest */
1240 break;
1241 if (test_page_attr(bitmap, page,
1242 BITMAP_PAGE_NEEDWRITE)) {
1243 clear_page_attr(bitmap, page,
1244 BITMAP_PAGE_NEEDWRITE);
1232 spin_unlock_irqrestore(&bitmap->lock, flags); 1245 spin_unlock_irqrestore(&bitmap->lock, flags);
1246 write_page(bitmap, page, 0);
1247 spin_lock_irqsave(&bitmap->lock, flags);
1248 if (!bitmap->filemap)
1249 break;
1233 } 1250 }
1234 } 1251 }
1252out:
1253 spin_unlock_irqrestore(&bitmap->lock, flags);
1235 1254
1236 done: 1255 done:
1237 if (bitmap->allclean == 0) 1256 if (bitmap->allclean == 0)
@@ -1386,11 +1405,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
1386 1405
1387 (*bmc)--; 1406 (*bmc)--;
1388 if (*bmc <= 2) { 1407 if (*bmc <= 2) {
1389 set_page_attr(bitmap, 1408 bitmap_set_pending(bitmap, offset);
1390 filemap_get_page(
1391 bitmap,
1392 offset >> bitmap->chunkshift),
1393 BITMAP_PAGE_PENDING);
1394 bitmap->allclean = 0; 1409 bitmap->allclean = 0;
1395 } 1410 }
1396 spin_unlock_irqrestore(&bitmap->lock, flags); 1411 spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1476,9 +1491,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, i
1476 *bmc |= NEEDED_MASK; 1491 *bmc |= NEEDED_MASK;
1477 else { 1492 else {
1478 if (*bmc <= 2) { 1493 if (*bmc <= 2) {
1479 set_page_attr(bitmap, 1494 bitmap_set_pending(bitmap, offset);
1480 filemap_get_page(bitmap, offset >> bitmap->chunkshift),
1481 BITMAP_PAGE_PENDING);
1482 bitmap->allclean = 0; 1495 bitmap->allclean = 0;
1483 } 1496 }
1484 } 1497 }
@@ -1551,11 +1564,9 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
1551 return; 1564 return;
1552 } 1565 }
1553 if (!*bmc) { 1566 if (!*bmc) {
1554 struct page *page;
1555 *bmc = 2 | (needed ? NEEDED_MASK : 0); 1567 *bmc = 2 | (needed ? NEEDED_MASK : 0);
1556 bitmap_count_page(bitmap, offset, 1); 1568 bitmap_count_page(bitmap, offset, 1);
1557 page = filemap_get_page(bitmap, offset >> bitmap->chunkshift); 1569 bitmap_set_pending(bitmap, offset);
1558 set_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
1559 bitmap->allclean = 0; 1570 bitmap->allclean = 0;
1560 } 1571 }
1561 spin_unlock_irq(&bitmap->lock); 1572 spin_unlock_irq(&bitmap->lock);