diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2009-12-10 18:51:59 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-10 18:51:59 -0500 |
commit | b09acf1aa79462bdacfe6744b469a17722a52702 (patch) | |
tree | 27ef83ed0d0bbf35938814f8ba3206e7881a170d /drivers/md/dm-log.c | |
parent | 4184153f9e483f9bb63339ed316e059962fe9794 (diff) |
dm raid1: split touched state into two
Split the variable "touched" into two, "touched_dirtied" and
"touched_cleaned", set when some region was dirtied or cleaned.
This will be used to optimize flushes.
After a transition from "dirty" to "clean" state we don't have flush hardware
cache on the log device. After a transition from "clean" to "dirty" the cache
must be flushed.
Before a transition from "clean" to "dirty" state we don't have to flush all
the raid legs. Before a transition from "dirty" to "clean" we must flush all
the legs to make sure that they are really in sync.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-log.c')
-rw-r--r-- | drivers/md/dm-log.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 9443896ede07..31dc33df95c7 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -208,7 +208,8 @@ struct log_header { | |||
208 | 208 | ||
209 | struct log_c { | 209 | struct log_c { |
210 | struct dm_target *ti; | 210 | struct dm_target *ti; |
211 | int touched; | 211 | int touched_dirtied; |
212 | int touched_cleaned; | ||
212 | uint32_t region_size; | 213 | uint32_t region_size; |
213 | unsigned int region_count; | 214 | unsigned int region_count; |
214 | region_t sync_count; | 215 | region_t sync_count; |
@@ -253,14 +254,14 @@ static inline void log_set_bit(struct log_c *l, | |||
253 | uint32_t *bs, unsigned bit) | 254 | uint32_t *bs, unsigned bit) |
254 | { | 255 | { |
255 | ext2_set_bit(bit, (unsigned long *) bs); | 256 | ext2_set_bit(bit, (unsigned long *) bs); |
256 | l->touched = 1; | 257 | l->touched_cleaned = 1; |
257 | } | 258 | } |
258 | 259 | ||
259 | static inline void log_clear_bit(struct log_c *l, | 260 | static inline void log_clear_bit(struct log_c *l, |
260 | uint32_t *bs, unsigned bit) | 261 | uint32_t *bs, unsigned bit) |
261 | { | 262 | { |
262 | ext2_clear_bit(bit, (unsigned long *) bs); | 263 | ext2_clear_bit(bit, (unsigned long *) bs); |
263 | l->touched = 1; | 264 | l->touched_dirtied = 1; |
264 | } | 265 | } |
265 | 266 | ||
266 | /*---------------------------------------------------------------- | 267 | /*---------------------------------------------------------------- |
@@ -378,7 +379,8 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, | |||
378 | } | 379 | } |
379 | 380 | ||
380 | lc->ti = ti; | 381 | lc->ti = ti; |
381 | lc->touched = 0; | 382 | lc->touched_dirtied = 0; |
383 | lc->touched_cleaned = 0; | ||
382 | lc->region_size = region_size; | 384 | lc->region_size = region_size; |
383 | lc->region_count = region_count; | 385 | lc->region_count = region_count; |
384 | lc->sync = sync; | 386 | lc->sync = sync; |
@@ -660,14 +662,16 @@ static int disk_flush(struct dm_dirty_log *log) | |||
660 | struct log_c *lc = (struct log_c *) log->context; | 662 | struct log_c *lc = (struct log_c *) log->context; |
661 | 663 | ||
662 | /* only write if the log has changed */ | 664 | /* only write if the log has changed */ |
663 | if (!lc->touched) | 665 | if (!lc->touched_cleaned && !lc->touched_dirtied) |
664 | return 0; | 666 | return 0; |
665 | 667 | ||
666 | r = rw_header(lc, WRITE); | 668 | r = rw_header(lc, WRITE); |
667 | if (r) | 669 | if (r) |
668 | fail_log_device(lc); | 670 | fail_log_device(lc); |
669 | else | 671 | else { |
670 | lc->touched = 0; | 672 | lc->touched_dirtied = 0; |
673 | lc->touched_cleaned = 0; | ||
674 | } | ||
671 | 675 | ||
672 | return r; | 676 | return r; |
673 | } | 677 | } |