@@ -209,76 +209,81 @@ static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mdde
209209 return NULL ;
210210}
211211
212- static int write_sb_page (struct bitmap * bitmap , struct page * page , int wait )
212+ static int __write_sb_page (struct md_rdev * rdev , struct bitmap * bitmap ,
213+ struct page * page )
213214{
214- struct md_rdev * rdev ;
215215 struct block_device * bdev ;
216216 struct mddev * mddev = bitmap -> mddev ;
217217 struct bitmap_storage * store = & bitmap -> storage ;
218+ loff_t offset = mddev -> bitmap_info .offset ;
219+ int size = PAGE_SIZE ;
220+
221+ bdev = (rdev -> meta_bdev ) ? rdev -> meta_bdev : rdev -> bdev ;
222+ if (page -> index == store -> file_pages - 1 ) {
223+ int last_page_size = store -> bytes & (PAGE_SIZE - 1 );
224+
225+ if (last_page_size == 0 )
226+ last_page_size = PAGE_SIZE ;
227+ size = roundup (last_page_size ,
228+ bdev_logical_block_size (bdev ));
229+ }
230+
231+ /* Just make sure we aren't corrupting data or metadata */
232+ if (mddev -> external ) {
233+ /* Bitmap could be anywhere. */
234+ if (rdev -> sb_start + offset
235+ + (page -> index * (PAGE_SIZE / SECTOR_SIZE ))
236+ > rdev -> data_offset &&
237+ rdev -> sb_start + offset
238+ < (rdev -> data_offset + mddev -> dev_sectors
239+ + (PAGE_SIZE / SECTOR_SIZE )))
240+ return - EINVAL ;
241+ } else if (offset < 0 ) {
242+ /* DATA BITMAP METADATA */
243+ if (offset
244+ + (long )(page -> index * (PAGE_SIZE / SECTOR_SIZE ))
245+ + size / SECTOR_SIZE > 0 )
246+ /* bitmap runs in to metadata */
247+ return - EINVAL ;
248+
249+ if (rdev -> data_offset + mddev -> dev_sectors
250+ > rdev -> sb_start + offset )
251+ /* data runs in to bitmap */
252+ return - EINVAL ;
253+ } else if (rdev -> sb_start < rdev -> data_offset ) {
254+ /* METADATA BITMAP DATA */
255+ if (rdev -> sb_start + offset
256+ + page -> index * (PAGE_SIZE / SECTOR_SIZE )
257+ + size / SECTOR_SIZE > rdev -> data_offset )
258+ /* bitmap runs in to data */
259+ return - EINVAL ;
260+ } else {
261+ /* DATA METADATA BITMAP - no problems */
262+ }
218263
219- restart :
220- rdev = NULL ;
221- while ((rdev = next_active_rdev (rdev , mddev )) != NULL ) {
222- int size = PAGE_SIZE ;
223- loff_t offset = mddev -> bitmap_info .offset ;
264+ md_super_write (mddev , rdev ,
265+ rdev -> sb_start + offset
266+ + page -> index * (PAGE_SIZE / SECTOR_SIZE ),
267+ size , page );
268+ return 0 ;
269+ }
224270
225- bdev = (rdev -> meta_bdev ) ? rdev -> meta_bdev : rdev -> bdev ;
271+ static int write_sb_page (struct bitmap * bitmap , struct page * page , int wait )
272+ {
273+ struct md_rdev * rdev ;
274+ struct mddev * mddev = bitmap -> mddev ;
275+ int ret ;
226276
227- if (page -> index == store -> file_pages - 1 ) {
228- int last_page_size = store -> bytes & (PAGE_SIZE - 1 );
229- if (last_page_size == 0 )
230- last_page_size = PAGE_SIZE ;
231- size = roundup (last_page_size ,
232- bdev_logical_block_size (bdev ));
233- }
234- /* Just make sure we aren't corrupting data or
235- * metadata
236- */
237- if (mddev -> external ) {
238- /* Bitmap could be anywhere. */
239- if (rdev -> sb_start + offset + (page -> index
240- * (PAGE_SIZE /512 ))
241- > rdev -> data_offset
242- &&
243- rdev -> sb_start + offset
244- < (rdev -> data_offset + mddev -> dev_sectors
245- + (PAGE_SIZE /512 )))
246- goto bad_alignment ;
247- } else if (offset < 0 ) {
248- /* DATA BITMAP METADATA */
249- if (offset
250- + (long )(page -> index * (PAGE_SIZE /512 ))
251- + size /512 > 0 )
252- /* bitmap runs in to metadata */
253- goto bad_alignment ;
254- if (rdev -> data_offset + mddev -> dev_sectors
255- > rdev -> sb_start + offset )
256- /* data runs in to bitmap */
257- goto bad_alignment ;
258- } else if (rdev -> sb_start < rdev -> data_offset ) {
259- /* METADATA BITMAP DATA */
260- if (rdev -> sb_start
261- + offset
262- + page -> index * (PAGE_SIZE /512 ) + size /512
263- > rdev -> data_offset )
264- /* bitmap runs in to data */
265- goto bad_alignment ;
266- } else {
267- /* DATA METADATA BITMAP - no problems */
277+ do {
278+ rdev = NULL ;
279+ while ((rdev = next_active_rdev (rdev , mddev )) != NULL ) {
280+ ret = __write_sb_page (rdev , bitmap , page );
281+ if (ret )
282+ return ret ;
268283 }
269- md_super_write (mddev , rdev ,
270- rdev -> sb_start + offset
271- + page -> index * (PAGE_SIZE /512 ),
272- size ,
273- page );
274- }
284+ } while (wait && md_super_wait (mddev ) < 0 );
275285
276- if (wait && md_super_wait (mddev ) < 0 )
277- goto restart ;
278286 return 0 ;
279-
280- bad_alignment :
281- return - EINVAL ;
282287}
283288
284289static void md_bitmap_file_kick (struct bitmap * bitmap );
0 commit comments