aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2011-03-22 03:35:35 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-03-22 03:35:35 -0400
commit1e9bb8808ac11094d711d20d580e7b45a4992d0c (patch)
treed0e228b619664b7f507e37e5eba4a5ebeef103a0
parent5e84ea3a9c662dc2d7a48703a4468fad954a3b7f (diff)
block: fix non-atomic access to genhd inflight structures
After the stack plugging introduction, these are called lockless. Ensure that the counters are updated atomically. Signed-off-by: Shaohua Li<shaohua.li@intel.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r--drivers/md/dm.c7
-rw-r--r--fs/partitions/check.c3
-rw-r--r--include/linux/genhd.h12
3 files changed, 12 insertions, 10 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 88820704a191..0cf68b478878 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -477,7 +477,8 @@ static void start_io_acct(struct dm_io *io)
477 cpu = part_stat_lock(); 477 cpu = part_stat_lock();
478 part_round_stats(cpu, &dm_disk(md)->part0); 478 part_round_stats(cpu, &dm_disk(md)->part0);
479 part_stat_unlock(); 479 part_stat_unlock();
480 dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); 480 atomic_set(&dm_disk(md)->part0.in_flight[rw],
481 atomic_inc_return(&md->pending[rw]));
481} 482}
482 483
483static void end_io_acct(struct dm_io *io) 484static void end_io_acct(struct dm_io *io)
@@ -497,8 +498,8 @@ static void end_io_acct(struct dm_io *io)
497 * After this is decremented the bio must not be touched if it is 498 * After this is decremented the bio must not be touched if it is
498 * a flush. 499 * a flush.
499 */ 500 */
500 dm_disk(md)->part0.in_flight[rw] = pending = 501 pending = atomic_dec_return(&md->pending[rw]);
501 atomic_dec_return(&md->pending[rw]); 502 atomic_set(&dm_disk(md)->part0.in_flight[rw], pending);
502 pending += atomic_read(&md->pending[rw^0x1]); 503 pending += atomic_read(&md->pending[rw^0x1]);
503 504
504 /* nudge anyone waiting on suspend queue */ 505 /* nudge anyone waiting on suspend queue */
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 9c21119512b9..ac546975031f 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -290,7 +290,8 @@ ssize_t part_inflight_show(struct device *dev,
290{ 290{
291 struct hd_struct *p = dev_to_part(dev); 291 struct hd_struct *p = dev_to_part(dev);
292 292
293 return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); 293 return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]),
294 atomic_read(&p->in_flight[1]));
294} 295}
295 296
296#ifdef CONFIG_FAIL_MAKE_REQUEST 297#ifdef CONFIG_FAIL_MAKE_REQUEST
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index c0d5f6945c1e..d764a426e9fd 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -109,7 +109,7 @@ struct hd_struct {
109 int make_it_fail; 109 int make_it_fail;
110#endif 110#endif
111 unsigned long stamp; 111 unsigned long stamp;
112 int in_flight[2]; 112 atomic_t in_flight[2];
113#ifdef CONFIG_SMP 113#ifdef CONFIG_SMP
114 struct disk_stats __percpu *dkstats; 114 struct disk_stats __percpu *dkstats;
115#else 115#else
@@ -370,21 +370,21 @@ static inline void free_part_stats(struct hd_struct *part)
370 370
371static inline void part_inc_in_flight(struct hd_struct *part, int rw) 371static inline void part_inc_in_flight(struct hd_struct *part, int rw)
372{ 372{
373 part->in_flight[rw]++; 373 atomic_inc(&part->in_flight[rw]);
374 if (part->partno) 374 if (part->partno)
375 part_to_disk(part)->part0.in_flight[rw]++; 375 atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
376} 376}
377 377
378static inline void part_dec_in_flight(struct hd_struct *part, int rw) 378static inline void part_dec_in_flight(struct hd_struct *part, int rw)
379{ 379{
380 part->in_flight[rw]--; 380 atomic_dec(&part->in_flight[rw]);
381 if (part->partno) 381 if (part->partno)
382 part_to_disk(part)->part0.in_flight[rw]--; 382 atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
383} 383}
384 384
385static inline int part_in_flight(struct hd_struct *part) 385static inline int part_in_flight(struct hd_struct *part)
386{ 386{
387 return part->in_flight[0] + part->in_flight[1]; 387 return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]);
388} 388}
389 389
390static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk) 390static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)