aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-08-15 04:56:11 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:03 -0400
commit5b99c2ffa980528a197f26c7d876cceeccce8dd5 (patch)
tree65e3bbbccb3f796f0569c47fcfc00e222cd3066e
parent960e739d9e9f1c2346d8bdc65299ee2e1ed42218 (diff)
block: make bi_phys_segments an unsigned int instead of short
raid5 can overflow with more than 255 stripes, and we can increase it to an int for free on both 32 and 64-bit archs due to the padding. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--drivers/md/raid5.c12
-rw-r--r--include/linux/bio.h2
2 files changed, 7 insertions, 7 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 05b22925cce4..37e546528f9c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -102,17 +102,17 @@ const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
102#endif 102#endif
103 103
104/* 104/*
105 * We maintain a biased count of active stripes in the bottom 8 bits of 105 * We maintain a biased count of active stripes in the bottom 16 bits of
106 * bi_phys_segments, and a count of processed stripes in the upper 8 bits 106 * bi_phys_segments, and a count of processed stripes in the upper 16 bits
107 */ 107 */
108static inline int raid5_bi_phys_segments(struct bio *bio) 108static inline int raid5_bi_phys_segments(struct bio *bio)
109{ 109{
110 return bio->bi_phys_segments & 0xff; 110 return bio->bi_phys_segments & 0xffff;
111} 111}
112 112
113static inline int raid5_bi_hw_segments(struct bio *bio) 113static inline int raid5_bi_hw_segments(struct bio *bio)
114{ 114{
115 return (bio->bi_phys_segments >> 8) & 0xff; 115 return (bio->bi_phys_segments >> 16) & 0xffff;
116} 116}
117 117
118static inline int raid5_dec_bi_phys_segments(struct bio *bio) 118static inline int raid5_dec_bi_phys_segments(struct bio *bio)
@@ -126,13 +126,13 @@ static inline int raid5_dec_bi_hw_segments(struct bio *bio)
126 unsigned short val = raid5_bi_hw_segments(bio); 126 unsigned short val = raid5_bi_hw_segments(bio);
127 127
128 --val; 128 --val;
129 bio->bi_phys_segments = (val << 8) | raid5_bi_phys_segments(bio); 129 bio->bi_phys_segments = (val << 16) | raid5_bi_phys_segments(bio);
130 return val; 130 return val;
131} 131}
132 132
133static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt) 133static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt)
134{ 134{
135 bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 8); 135 bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
136} 136}
137 137
138static inline int raid6_next_disk(int disk, int raid_disks) 138static inline int raid6_next_disk(int disk, int raid_disks)
diff --git a/include/linux/bio.h b/include/linux/bio.h
index dfc3556d311c..2c0c09034fd2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -75,7 +75,7 @@ struct bio {
75 /* Number of segments in this BIO after 75 /* Number of segments in this BIO after
76 * physical address coalescing is performed. 76 * physical address coalescing is performed.
77 */ 77 */
78 unsigned short bi_phys_segments; 78 unsigned int bi_phys_segments;
79 79
80 unsigned int bi_size; /* residual I/O count */ 80 unsigned int bi_size; /* residual I/O count */
81 81