[PATCH 7/7] nand-bb: implement lseek in readonly mode
Robert Jarzmik
robert.jarzmik at free.fr
Thu Dec 15 08:51:40 EST 2011
Sascha Hauer <s.hauer at pengutronix.de> writes:
> +static off_t nand_bb_lseek(struct cdev *cdev, off_t __offset)
> +{
> + struct nand_bb *bb = cdev->priv;
> + unsigned long raw_pos = 0;
> + uint32_t offset = __offset;
> + int ret;
> +
> + /* lseek only in readonly mode */
> + if (bb->flags & O_ACCMODE)
> + return -ENOSYS;
> +
> + while (raw_pos < bb->raw_size) {
> + off_t now = min(offset, bb->info.erasesize);
> +
> + ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, (void *)raw_pos);
> + if (ret < 0)
> + return ret;
> + if (!ret)
> + offset -= now;
> + raw_pos += now;
> + if (!offset) {
> + bb->offset = raw_pos;
> + return __offset;
> + }
> + }
Are you sure of this algorithm ?
I tried to check it with:
- erasesize=16 (silly I know, but it's simpler for my mind)
- bb->raw_size = +oo
- offset = 34
Let's assume we have eraseblock B0, B1, B2 and B3 of 16 bytes.
B0, B1 and B3 are good, B2 is a bad block.
+--------+--------+--------+--------+
| B0 | B1 |xxxB2xxx| B3 |
+--------+--------+--------+--------+
If I unroll the while loop:
- loop1:
now=16
ret=0 (B0 good)
offset = 18
raw_pos = 16
- loop2:
now=16
ret=0 (B1 good)
offset = 2
raw_pos = 32
- loop3:
now=2
ret=1 (B2 bad)
offset = 2
raw_pos = 34
- loop4:
now=2
ret=0 (B3 good)
offset = 0
raw_pos = 36
bb->offset = 36
return 34
So we end up with bb->offset = 36, which seems incorrect to me. I would have
understood a value of 50, but 36 ... I don't
Cheers.
--
Robert
More information about the barebox
mailing list