Skip to content

Commit c757ec9

Browse files
liu-song-6shligit
authored andcommitted
md/r5cache: Check array size in r5l_init_log
Currently, r5l_write_stripe checks meta size for each stripe write, which is not necessary. With this patch, r5l_init_log checks maximal meta size of the array, which is (r5l_meta_block + raid_disks x r5l_payload_data_parity). If this is too big to fit in one page, r5l_init_log aborts. With current meta data, r5l_log support raid_disks up to 203. Signed-off-by: Song Liu <songliubraving@fb.com> Signed-off-by: Shaohua Li <shli@fb.com>
1 parent 504634f commit c757ec9

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

drivers/md/raid5-cache.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,6 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
441441
{
442442
int write_disks = 0;
443443
int data_pages, parity_pages;
444-
int meta_size;
445444
int reserve;
446445
int i;
447446
int ret = 0;
@@ -473,15 +472,6 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
473472
parity_pages = 1 + !!(sh->qd_idx >= 0);
474473
data_pages = write_disks - parity_pages;
475474

476-
meta_size =
477-
((sizeof(struct r5l_payload_data_parity) + sizeof(__le32))
478-
* data_pages) +
479-
sizeof(struct r5l_payload_data_parity) +
480-
sizeof(__le32) * parity_pages;
481-
/* Doesn't work with very big raid array */
482-
if (meta_size + sizeof(struct r5l_meta_block) > PAGE_SIZE)
483-
return -EINVAL;
484-
485475
set_bit(STRIPE_LOG_TRAPPED, &sh->state);
486476
/*
487477
* The stripe must enter state machine again to finish the write, so
@@ -1197,6 +1187,22 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
11971187

11981188
if (PAGE_SIZE != 4096)
11991189
return -EINVAL;
1190+
1191+
/*
1192+
* The PAGE_SIZE must be big enough to hold 1 r5l_meta_block and
1193+
* raid_disks r5l_payload_data_parity.
1194+
*
1195+
* Write journal and cache does not work for very big array
1196+
* (raid_disks > 203)
1197+
*/
1198+
if (sizeof(struct r5l_meta_block) +
1199+
((sizeof(struct r5l_payload_data_parity) + sizeof(__le32)) *
1200+
conf->raid_disks) > PAGE_SIZE) {
1201+
pr_err("md/raid:%s: write journal/cache doesn't work for array with %d disks\n",
1202+
mdname(conf->mddev), conf->raid_disks);
1203+
return -EINVAL;
1204+
}
1205+
12001206
log = kzalloc(sizeof(*log), GFP_KERNEL);
12011207
if (!log)
12021208
return -ENOMEM;

0 commit comments

Comments
 (0)