Skip to content

Commit 328e17d

Browse files
Jon Derrickliu-song-6
authored andcommitted
md: Move sb writer loop to its own function
Preparatory patch for optimal I/O size calculation. Move the sb writer loop routine into its own function for clarity. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jon Derrick <jonathan.derrick@linux.dev> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20230224183323.638-2-jonathan.derrick@linux.dev
1 parent dccb8ad commit 328e17d

1 file changed

Lines changed: 65 additions & 60 deletions

File tree

drivers/md/md-bitmap.c

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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

284289
static void md_bitmap_file_kick(struct bitmap *bitmap);

0 commit comments

Comments
 (0)