Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a537df4 authored by NeilBrown's avatar NeilBrown
Browse files

md/bitmap: rename and tidy up BITMAP_PAGE_CLEAN



The flag 'BITMAP_PAGE_CLEAN' has a confusing name as it doesn't mean
that the page is clean, but rather that there are counters in the page
which allow bits in the bitmap to be cleared - i.e. maybe cleaning can
happen.

So change it to BITMAP_PAGE_PENDING and fix some irregularities:
 - Don't set it in bitmap_init_from_disk as bitmap_set_memory_bits
   sets it when needed
 - in bitmap_daemon_work, if we find a counter that is '1', but
   need_sync is set, then set BITMAP_PAGE_PENDING again (it was
   recently cleared) to ensure we don't forget about this bit.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 01f96c0a
Loading
Loading
Loading
Loading
+19 −19
Original line number Original line Diff line number Diff line
@@ -868,7 +868,8 @@ static void bitmap_file_kick(struct bitmap *bitmap)


enum bitmap_page_attr {
enum bitmap_page_attr {
	BITMAP_PAGE_DIRTY = 0,     /* there are set bits that need to be synced */
	BITMAP_PAGE_DIRTY = 0,     /* there are set bits that need to be synced */
	BITMAP_PAGE_CLEAN = 1,     /* there are bits that might need to be cleared */
	BITMAP_PAGE_PENDING = 1,   /* there are bits that are being cleaned.
				    * i.e. counter is 1 or 2. */
	BITMAP_PAGE_NEEDWRITE = 2, /* there are cleared bits that need to be synced */
	BITMAP_PAGE_NEEDWRITE = 2, /* there are cleared bits that need to be synced */
};
};


@@ -1111,7 +1112,6 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
					       (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap),
					       (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap),
					       needed);
					       needed);
			bit_cnt++;
			bit_cnt++;
			set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
		}
		}
	}
	}


@@ -1204,7 +1204,7 @@ void bitmap_daemon_work(mddev_t *mddev)


		if (page != lastpage) {
		if (page != lastpage) {
			/* skip this page unless it's marked as needing cleaning */
			/* skip this page unless it's marked as needing cleaning */
			if (!test_page_attr(bitmap, page, BITMAP_PAGE_CLEAN)) {
			if (!test_page_attr(bitmap, page, BITMAP_PAGE_PENDING)) {
				int need_write = test_page_attr(bitmap, page,
				int need_write = test_page_attr(bitmap, page,
								BITMAP_PAGE_NEEDWRITE);
								BITMAP_PAGE_NEEDWRITE);
				if (need_write)
				if (need_write)
@@ -1249,19 +1249,17 @@ void bitmap_daemon_work(mddev_t *mddev)
			}
			}
			spin_lock_irqsave(&bitmap->lock, flags);
			spin_lock_irqsave(&bitmap->lock, flags);
			if (!bitmap->need_sync)
			if (!bitmap->need_sync)
				clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
				clear_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
		}
		}
		bmc = bitmap_get_counter(bitmap,
		bmc = bitmap_get_counter(bitmap,
					 (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
					 (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
					 &blocks, 0);
					 &blocks, 0);
		if (bmc) {
		if (!bmc)
			if (*bmc)
			j |= PAGE_COUNTER_MASK;
		else if (*bmc) {
			bitmap->allclean = 0;
			bitmap->allclean = 0;


			if (*bmc == 2) {
			if (*bmc == 1 && !bitmap->need_sync) {
				*bmc = 1; /* maybe clear the bit next time */
				set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
			} else if (*bmc == 1 && !bitmap->need_sync) {
				/* we can clear the bit */
				/* we can clear the bit */
				*bmc = 0;
				*bmc = 0;
				bitmap_count_page(bitmap,
				bitmap_count_page(bitmap,
@@ -1279,9 +1277,11 @@ void bitmap_daemon_work(mddev_t *mddev)
								 j),
								 j),
						paddr);
						paddr);
				kunmap_atomic(paddr, KM_USER0);
				kunmap_atomic(paddr, KM_USER0);
			} else if (*bmc <= 2) {
				*bmc = 1; /* maybe clear the bit next time */
				set_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
			}
		}
		}
		} else
			j |= PAGE_COUNTER_MASK;
	}
	}
	spin_unlock_irqrestore(&bitmap->lock, flags);
	spin_unlock_irqrestore(&bitmap->lock, flags);


@@ -1458,7 +1458,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
				      filemap_get_page(
				      filemap_get_page(
					      bitmap,
					      bitmap,
					      offset >> CHUNK_BLOCK_SHIFT(bitmap)),
					      offset >> CHUNK_BLOCK_SHIFT(bitmap)),
				      BITMAP_PAGE_CLEAN);
				      BITMAP_PAGE_PENDING);


		spin_unlock_irqrestore(&bitmap->lock, flags);
		spin_unlock_irqrestore(&bitmap->lock, flags);
		offset += blocks;
		offset += blocks;
@@ -1546,7 +1546,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, i
			if (*bmc <= 2)
			if (*bmc <= 2)
				set_page_attr(bitmap,
				set_page_attr(bitmap,
					      filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
					      filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
					      BITMAP_PAGE_CLEAN);
					      BITMAP_PAGE_PENDING);
		}
		}
	}
	}
 unlock:
 unlock:
@@ -1622,7 +1622,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
		*bmc = 1 | (needed ? NEEDED_MASK : 0);
		*bmc = 1 | (needed ? NEEDED_MASK : 0);
		bitmap_count_page(bitmap, offset, 1);
		bitmap_count_page(bitmap, offset, 1);
		page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
		page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
		set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
		set_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
	}
	}
	spin_unlock_irq(&bitmap->lock);
	spin_unlock_irq(&bitmap->lock);
	bitmap->allclean = 0;
	bitmap->allclean = 0;