| From fe067853b0945a2ae18004e0a58023694e0779b9 Mon Sep 17 00:00:00 2001 |
| From: joerg jungermann <jj@borkum.net> |
| Date: Thu, 25 Sep 2014 22:05:12 -0700 |
| Subject: [PATCH] mkfs.f2fs: possible endianes bug in mkfs.f2fs roll-forward |
| speed |
| |
| I might found a bug in mkfs.f2fs. while experimenting with f2fs on my big |
| endian MIPS32 device (platform lantiq, 14.07-rc3, uclibc). |
| |
| I ran into an issue that mkfs.f2fs, was not able to format block devices if I |
| did not specify the sector count manually. |
| |
| I hunted it down to lib/libf2fs.c. |
| After I found that the detected sector count equals to the wanted sector count |
| shifted left (32+9) times. |
| |
| I found two issues: |
| Firstly it uses ioctl BLKGETSIZE, which writes to an uint32_t the size of the |
| device. |
| As c->total_sectors is of type uint64_t, the value is written in to the first |
| 4 bytes. |
| That explained the left shift of 32 bits. |
| |
| Secondly BLKGETSIZE determines the size of the device in bytes (AFAIK, learned |
| by observation). |
| In the first branch of the if-block patched below, the c->total_sectors is |
| calculated by |
| c->total_sectors = stat_buf.st_size / c->sector_size; |
| The else branch omits the devision. sector_sice is mostly 512, that explained |
| the left shift by 9 bytes. |
| |
| * fixes sector count calculation |
| * uses BLKGETSIZE64 if avail |
| |
| Signed-off-by: joerg jungermann <jj@borkum.net> |
| Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
| Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar> |
| --- |
| lib/libf2fs.c | 16 ++++++++++++++-- |
| 1 file changed, 14 insertions(+), 2 deletions(-) |
| |
| diff --git a/lib/libf2fs.c b/lib/libf2fs.c |
| index 01ef4e9..73c551b 100644 |
| --- a/lib/libf2fs.c |
| +++ b/lib/libf2fs.c |
| @@ -422,6 +422,9 @@ int f2fs_get_device_info(struct f2fs_configuration *c) |
| { |
| int32_t fd = 0; |
| uint32_t sector_size; |
| +#ifndef BLKGETSIZE64 |
| + uint32_t total_sectors; |
| +#endif |
| struct stat stat_buf; |
| struct hd_geometry geom; |
| u_int64_t wanted_total_sectors = c->total_sectors; |
| @@ -454,11 +457,20 @@ int f2fs_get_device_info(struct f2fs_configuration *c) |
| } |
| } |
| |
| - if (ioctl(fd, BLKGETSIZE, &c->total_sectors) < 0) { |
| +#ifdef BLKGETSIZE64 |
| + if (ioctl(fd, BLKGETSIZE64, &c->total_sectors) < 0) { |
| MSG(0, "\tError: Cannot get the device size\n"); |
| return -1; |
| } |
| - |
| + c->total_sectors /= c->sector_size; |
| +#else |
| + if (ioctl(fd, BLKGETSIZE, &total_sectors) < 0) { |
| + MSG(0, "\tError: Cannot get the device size\n"); |
| + return -1; |
| + } |
| + total_sectors /= c->sector_size; |
| + c->total_sectors = total_sectors; |
| +#endif |
| if (ioctl(fd, HDIO_GETGEO, &geom) < 0) |
| c->start_sector = 0; |
| else |
| -- |
| 2.0.4 |
| |