Patchwork lseek32 and lseek64

login
register
mail settings
Submitter Richard Genoud
Date Sept. 10, 2012, 12:59 p.m.
Message ID <CACQ1gAg_s8S8V5AWN4pR9XKqctyeYZpW_mtD3XczDde5Y+9Y4A@mail.gmail.com>
Download mbox | patch
Permalink /patch/182886/
State New
Headers show

Comments

Richard Genoud - Sept. 10, 2012, 12:59 p.m.
2012/9/10 Cheney Chen <cheneychencl2012@gmail.com>:
> You are right. ubiformat is used on mtd devices. This bug was found a few
> month ago, now I'm available and this bug is reported. But I make a mistake
> for ubiformat /dev/ubi0_0. I just retry it again and print some log for you.
>
> # mtd utility original file's bin
> # ./ubiformat /dev/mtd/mtd13
> ubiformat: mtd13 (nand), size 6375342080 bytes (5.9 GiB), 1520 eraseblocks
> of 4194304 bytes (4.0 MiB), min. I/O size 16384 bytes
> libscan: scanning eraseblock 512 -- 33 % complete  libmtd: error!: cannot
> seek mtd13 to offset 18446744071562067968
>         error 22 (Invalid argument)
> ubiformat: error!: failed to scan mtd13 (/dev/mtd/mtd13)
>
> # add my patch as bin
> # ./ubiformat /dev/mtd/mtd13
> ubiformat: mtd13 (nand), size 6375342080 bytes (5.9 GiB), 1520 eraseblocks
> of 4194304 bytes (4.0 MiB), min. I/O size 16384 bytes
> libscan: scanning eraseblock 1519 -- 100 % complete
> ubiformat: 1495 eraseblocks are supposedly empty
> ubiformat: 22 bad eraseblocks found, numbers: 166, 313, 359, 556, 623, 624,
> 625, 626, 627, 628, 877, 1313, 1317, 1353, 1512, 1513, 1514, 1515
> , 1516, 1517, 1518, 1519
> ubiformat: warning!: 3 of 1498 eraseblocks contain non-ubifs data
> ubiformat: continue? (yes/no)  yes
> ubiformat: warning!: only 0 of 1498 eraseblocks have valid erase counter
> ubiformat: erase counter 0 will be used for all eraseblocks
> ubiformat: note, arbitrary erase counter value may be specified using -e
> option
> ubiformat: continue? (yes/no)  yes
> ubiformat: use erase counter 0 for all eraseblocks
> ubiformat: formatting eraseblock 1519 -- 100 % complete
>
> The attachment is my patch as a reference.

Please, cc the linux-mtd ML in your emails.

I had a look at your patch, and maybe something like that is better:
 		goto out_free;
@@ -293,7 +293,7 @@ int ubigen_write_layout_vol(const struct
ubigen_info *ui, int peb1, int peb2,
 		goto out_free;
 	}

-	seek = peb2 * ui->peb_size;
+	seek = (off_t) peb2 * ui->peb_size;
 	if (lseek(fd, seek, SEEK_SET) != seek) {
 		sys_errmsg("cannot seek output file");
 		goto out_free;

because off_t is 64bits if _FILE_OFFSET_BITS=64, wich is the case by
default in common.mk
could you test it ?
Richard Genoud - Sept. 11, 2012, 7:10 a.m.
2012/9/11 Cheney Chen <cheneychencl2012@gmail.com>:
> I add the case _FILE_OFFSET_BITS=64 into the file Android.mk, compile them
> and try it again. it dose not work.
>
> + LOCAL_CFLAGS = -O2 -Wall -D_FILE_OFFSET_BITS=64
>
> Why not use uint64_t?
It seems that there's a problem somewhere in the android makefiles,
because you don't need to define _FILE_OFFSET_BITS yourself, it should
be enabled by common.mk (in mtd-utils), unless WITHOUT_LARGEFILE=1 is
set.
maybe try to grep WITHOUT_LARGEFILE in your project, and make the
mtd_utils with V=1.
you should see -D_FILE_OFFSET_BITS=64 in the compilation log. If not,
something in your project had disabled it.
(maybe you're using µClibc without large file support, or buildroot
which disables it for mtd-utils or...)

It's better to use off_t because the prototype of lseek is:
off_t lseek(int fd, off_t offset, int whence);
cf man lseek64:
lseek(2) uses the type off_t.  This is a 32-bit signed type on 32-bit
architectures, unless one compiles with
           #define _FILE_OFFSET_BITS 64
       in which case it is a 64-bit signed type.
(and off_t is signed, not unsigned)

Patch

diff --git a/ubi-utils/libubigen.c b/ubi-utils/libubigen.c
index 9eaa7f5..d2a949b 100644
--- a/ubi-utils/libubigen.c
+++ b/ubi-utils/libubigen.c
@@ -279,7 +279,7 @@  int ubigen_write_layout_vol(const struct
ubigen_info *ui, int peb1, int peb2,
 	memset(outbuf + ui->data_offs + ui->vtbl_size, 0xFF,
 	       ui->peb_size - ui->data_offs - ui->vtbl_size);

-	seek = peb1 * ui->peb_size;
+	seek = (off_t) peb1 * ui->peb_size;
 	if (lseek(fd, seek, SEEK_SET) != seek) {
 		sys_errmsg("cannot seek output file");