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>

authored by Shaohua Li and committed by Jens Axboe 1e9bb880 5e84ea3a

+12 -10
+4 -3
drivers/md/dm.c
··· 477 cpu = part_stat_lock(); 478 part_round_stats(cpu, &dm_disk(md)->part0); 479 part_stat_unlock(); 480 - dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); 481 } 482 483 static void end_io_acct(struct dm_io *io) ··· 498 * After this is decremented the bio must not be touched if it is 499 * a flush. 500 */ 501 - dm_disk(md)->part0.in_flight[rw] = pending = 502 - atomic_dec_return(&md->pending[rw]); 503 pending += atomic_read(&md->pending[rw^0x1]); 504 505 /* nudge anyone waiting on suspend queue */
··· 477 cpu = part_stat_lock(); 478 part_round_stats(cpu, &dm_disk(md)->part0); 479 part_stat_unlock(); 480 + atomic_set(&dm_disk(md)->part0.in_flight[rw], 481 + atomic_inc_return(&md->pending[rw])); 482 } 483 484 static void end_io_acct(struct dm_io *io) ··· 497 * After this is decremented the bio must not be touched if it is 498 * a flush. 499 */ 500 + pending = atomic_dec_return(&md->pending[rw]); 501 + atomic_set(&dm_disk(md)->part0.in_flight[rw], pending); 502 pending += atomic_read(&md->pending[rw^0x1]); 503 504 /* nudge anyone waiting on suspend queue */
+2 -1
fs/partitions/check.c
··· 290 { 291 struct hd_struct *p = dev_to_part(dev); 292 293 - return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); 294 } 295 296 #ifdef CONFIG_FAIL_MAKE_REQUEST
··· 290 { 291 struct hd_struct *p = dev_to_part(dev); 292 293 + return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]), 294 + atomic_read(&p->in_flight[1])); 295 } 296 297 #ifdef CONFIG_FAIL_MAKE_REQUEST
+6 -6
include/linux/genhd.h
··· 109 int make_it_fail; 110 #endif 111 unsigned long stamp; 112 - int in_flight[2]; 113 #ifdef CONFIG_SMP 114 struct disk_stats __percpu *dkstats; 115 #else ··· 370 371 static inline void part_inc_in_flight(struct hd_struct *part, int rw) 372 { 373 - part->in_flight[rw]++; 374 if (part->partno) 375 - part_to_disk(part)->part0.in_flight[rw]++; 376 } 377 378 static inline void part_dec_in_flight(struct hd_struct *part, int rw) 379 { 380 - part->in_flight[rw]--; 381 if (part->partno) 382 - part_to_disk(part)->part0.in_flight[rw]--; 383 } 384 385 static inline int part_in_flight(struct hd_struct *part) 386 { 387 - return part->in_flight[0] + part->in_flight[1]; 388 } 389 390 static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)
··· 109 int make_it_fail; 110 #endif 111 unsigned long stamp; 112 + atomic_t in_flight[2]; 113 #ifdef CONFIG_SMP 114 struct disk_stats __percpu *dkstats; 115 #else ··· 370 371 static inline void part_inc_in_flight(struct hd_struct *part, int rw) 372 { 373 + atomic_inc(&part->in_flight[rw]); 374 if (part->partno) 375 + atomic_inc(&part_to_disk(part)->part0.in_flight[rw]); 376 } 377 378 static inline void part_dec_in_flight(struct hd_struct *part, int rw) 379 { 380 + atomic_dec(&part->in_flight[rw]); 381 if (part->partno) 382 + atomic_dec(&part_to_disk(part)->part0.in_flight[rw]); 383 } 384 385 static inline int part_in_flight(struct hd_struct *part) 386 { 387 + return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]); 388 } 389 390 static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)