]> www.infradead.org Git - mtd-utils.git/commitdiff
flash_{lock, unlock}: fix off-by-one error for "entire device" length
authorSteven Miao <realmz6@gmail.com>
Mon, 6 Jun 2011 04:09:14 +0000 (00:09 -0400)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Mon, 6 Jun 2011 12:36:25 +0000 (15:36 +0300)
This basically reverts commit 43feb39f35a9ee0ed3 which changed the full
length calculation to be one less than one sector.  I don't understand
the logic in the commit message where it states that the length should
be one sector smaller as this results in misbehavior at runtime.

For example, with a mtd device with total size 0x400000 and erase block
size of 0x20000 (which gives us a total of 32 sectors), this new logic
results in:
mtdLockInfo.start = 0;
mtdLockInfo.length = 0x3e0000; /* (32 - 1) * 0x20000 */

Calling MEMLOCK/MEMUNLOCK on the device with this range leaves the last
sector unchanged which is certainly not what we want.  So drop this -1
part of the calculation.

To look at it another way, if we only attempt to lock one sector, this
calculation would end up with the .length set to 0.  Calling MEMLOCK
with a length of 0 does not lock the sector as this simple code shows:
int main(int argc, char *argv[]) {
erase_info_t e0 = { 0, 0 }, e1 = { 0, 0x20000 };
int fd = open(argv[1], O_RDONLY);
ioctl(fd, MEMUNLOCK, &e1);
printf("%i\n", ioctl(fd, MEMISLOCKED, &e1));
ioctl(fd, MEMLOCK, &e0);
printf("%i\n", ioctl(fd, MEMISLOCKED, &e1));
}
MEMISLOCKED returns 0 both times.  If we change the argument to MEMLOCK
to e1, then MEMISLOCKED returns 1.

Signed-off-by: Steven Miao <realmz6@gmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
flash_unlock.c

index 3bb33819aeb88306e38880a0a620665a4807b978..1cc8c2ff2d9bbd916c2340a7634512bba801eb6b 100644 (file)
@@ -71,11 +71,11 @@ int main(int argc, char *argv[])
        if (argc > 3) {
                count = strtol(argv[3], NULL, 0);
                if (count == -1)
-                       mtdLockInfo.length = mtdInfo.size - mtdInfo.erasesize;
+                       mtdLockInfo.length = mtdInfo.size;
                else
                        mtdLockInfo.length = mtdInfo.erasesize * count;
        } else
-               mtdLockInfo.length = mtdInfo.size - mtdInfo.erasesize;
+               mtdLockInfo.length = mtdInfo.size;
        if (mtdLockInfo.start + mtdLockInfo.length > mtdInfo.size)
                errmsg_die("range is more than device supports: %#x + %#x > %#x",
                        mtdLockInfo.start, mtdLockInfo.length, mtdInfo.size);