答复: [PATCH] mtd: cmdlinepart: allow fill-up partition at any point
Yanjiantao
yanjiantao at hisilicon.com
Tue Oct 13 01:53:04 PDT 2015
Hi,
In linux-3.10 and later kernel versions, block 'markbad' or 'checkbad' method is to mark or check 1st, 2nd/last page, which depends on chip->bbt_options:
markbad flows is as follows:
/* Write to first/last page(s) if necessary */
if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
wr_ofs += mtd->erasesize - mtd->writesize;
do {
res = nand_do_write_oob(mtd, wr_ofs, &ops);
if (!ret)
ret = res;
i++;
wr_ofs += mtd->writesize;
} while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
Check bad flows is the same.
1. when NAND_BBT_SCANLASTPAGE is set, markbad and checkbad on the last page only.
2. when NAND_BBT_SCAN2NDPAGE is set, markbad and checkbad on the 1st and 2nd page.
Questions:
1. for some NAND Flash, badblock marker is on 1st or 2nd or last page(spansion), in this case , check badblock my fail.
2. for some NAND Flash, bad block marker is on 1st or last page(hynix H27UBG8T2CTR) , in this case, check badblock may fail too.
3. set NAND_BBT_SCANLASTPAGE means only mark or check the last page, which is not compliant with SAMSUNG/ TOSHIBA/ HYNIX/MICRON/spansion. they claim bad block marker is on 1st/2nd, or 1st/last, or 1st/2nd/last, or the 1st only.
-----邮件原件-----
发件人: Caizhiyong
发送时间: 2015年10月13日 15:35
收件人: Yanjiantao
主题: FW: [PATCH] mtd: cmdlinepart: allow fill-up partition at any point
Looking forward to your feedback.
Best regards.
Cai Zhiyong.
http://www.huawei.com
> -----Original Message-----
> From: Brian Norris [mailto:computersforpeace at gmail.com]
> Sent: Wednesday, September 30, 2015 3:56 AM
> To: Ben Shelton
> Cc: dmw2 at infradead.org; linux-mtd at lists.infradead.org;
> linux-kernel at vger.kernel.org; Caizhiyong
> Subject: Re: [PATCH] mtd: cmdlinepart: allow fill-up partition at any point
>
> Sorry for delay... a lot of things came on my plate, so things got
> buried.
>
> I fixed up a few conflicts locally with some of my patches, but I have a
> few problems with your patch, so I'll have to request another revision.
>
> On Thu, May 07, 2015 at 09:57:41PM -0500, Ben Shelton wrote:
> > Currently, a fill-up partition (indicated by '-') must be the last
> > partition, and no other partitions can go after it. Change the
> > cmdlinepart parsing code to allow a fill-up partition at any point.
> > This is useful, for example, if you want to reserve a partition at the
> > end of the flash where the bad block table will go.
> >
> > Signed-off-by: Ben Shelton <ben.shelton at ni.com>
>
> For one, I think we need a little update to the parser documentation
> (i.e., code comments at the top) to show at least an example of this new
> allowed syntax.
>
> > ---
> > drivers/mtd/cmdlinepart.c | 33 ++++++++++++++++++++++++++-------
> > 1 file changed, 26 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
> > index c850300..2d0eda2 100644
> > --- a/drivers/mtd/cmdlinepart.c
> > +++ b/drivers/mtd/cmdlinepart.c
> > @@ -97,6 +97,7 @@ static struct mtd_partition * newpart(char *s,
> > char **retptr,
> > int *num_parts,
> > int this_part,
> > + int size_remaining_found,
> > unsigned char **extra_mem_ptr,
> > int extra_mem_size)
> > {
> > @@ -110,9 +111,16 @@ static struct mtd_partition * newpart(char *s,
> >
> > /* fetch the partition size */
> > if (*s == '-') {
> > + if (size_remaining_found) {
> > + printk(KERN_ERR ERRP
>
> Trivial: we can use pr_err() now (see l2-mtd.git).
>
> > + "more than one '-' partition specified\n");
> > + return ERR_PTR(-EINVAL);
> > + }
> > +
> > /* assign all remaining space to this partition */
> > size = SIZE_REMAINING;
> > s++;
> > + size_remaining_found = 1;
> > } else {
> > size = memparse(s, &s);
> > if (size < PAGE_SIZE) {
> > @@ -169,13 +177,10 @@ static struct mtd_partition * newpart(char *s,
> >
> > /* test if more partitions are following */
> > if (*s == ',') {
> > - if (size == SIZE_REMAINING) {
> > - printk(KERN_ERR ERRP "no partitions allowed after a fill-up
> partition\n");
> > - return ERR_PTR(-EINVAL);
> > - }
> > /* more partitions follow, parse them */
> > parts = newpart(s + 1, &s, num_parts, this_part + 1,
> > - &extra_mem, extra_mem_size);
> > + size_remaining_found, &extra_mem,
> > + extra_mem_size);
> > if (IS_ERR(parts))
> > return parts;
> > } else {
> > @@ -252,6 +257,7 @@ static int mtdpart_setup_real(char *s)
> > &s, /* out: updated cmdline ptr */
> > &num_parts, /* out: number of parts */
> > 0, /* first partition */
> > + 0, /* size_remaining not found */
> > (unsigned char**)&this_mtd, /* out: extra mem */
> > mtd_id_len + 1 + sizeof(*this_mtd) +
> > sizeof(void*)-1 /*alignment*/);
> > @@ -313,6 +319,7 @@ static int parse_cmdline_partitions(struct mtd_info
> *master,
> > int i, err;
> > struct cmdline_mtd_partition *part;
> > const char *mtd_id = master->name;
> > + int sr_part_num = -1;
> >
> > /* parse command line */
> > if (!cmdline_parsed) {
> > @@ -339,8 +346,10 @@ static int parse_cmdline_partitions(struct mtd_info
> *master,
> > else
> > offset = part->parts[i].offset;
> >
> > - if (part->parts[i].size == SIZE_REMAINING)
> > - part->parts[i].size = master->size - offset;
> > + if (part->parts[i].size == SIZE_REMAINING) {
> > + sr_part_num = i;
> > + continue;
> > + }
>
> Here, you are dropping this property for fill partitions:
>
> "if specified or truncated size is 0 the part is skipped"
>
> Since the size is no longer computed in this loop, it will never match
> the 'size == 0' check.
>
> >
> > if (offset + part->parts[i].size > master->size) {
> > printk(KERN_WARNING ERRP
> > @@ -361,6 +370,16 @@ static int parse_cmdline_partitions(struct mtd_info
> *master,
> > }
> > }
> >
> > + /* if a partition was marked as SIZE_REMAINING */
> > + if (sr_part_num != -1) {
> > + /* fix up the size of the SIZE_REMAINING partition */
> > + part->parts[sr_part_num].size = master->size - offset;
>
> The use of 'offset' doesn't look correct. At this point, 'offset' is the
> address of the end of the last partition. That looks like you're still
> sizing the fill partition to be only at the end of the flash, which is
> not the point of this patch. Am I missing something?
>
> > +
> > + /* fix up the offsets of the subsequent partitions */
> > + for (i = (sr_part_num + 1); i < part->num_parts; i++)
> > + part->parts[i].offset += part->parts[sr_part_num].size;
>
> Is this a legal adjustment? Is it possible to have fixed address (not
> OFFSET_CONTINUOUS) partitions after the fill partition? I see that would
> actually make this kind of ambiguous. So maybe you need to specify this
> in the documentation and check for it in the parsing -- see that once
> size_remaining_found > 0, we don't allow any more partitions
> '@<address'> (i.e., not OFFSET_CONTINUOUS).
>
> > + }
> > +
> > *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
> > GFP_KERNEL);
> > if (!*pparts)
>
> I think this patch speaks to our need for unit tests... that way we can
> clearly and definitively show pass/fail for any regressions.
>
> This reminds me of Cai Zhiyong's attempts to unify this parser with the
> new block/cmdline-parser, without getting any test results for the
> variety of existing MTD use cases...
>
> Brian
More information about the linux-mtd
mailing list