The code was checking for a non-existent macro `HDIO_GETGIO` instead of
`HDIO_GETGEO`, which caused the ioctl() call to never be executed.
This resulted in start_sector always being set to 0, even when the
partition actually starts at a different sector (e.g., 2048).

This bug affects:
- lib/libf2fs.c: get_device_info() function (lines 967, 1076)
- tools/fibmap.c: stat_bdev() function (lines 91, 108)

Reproducer:
1. Create a partition starting at sector 2048:
   # parted -s /dev/sdb mklabel gpt
   # parted -s /dev/sdb mkpart primary 2048s 32GiB

2. Verify the partition start sector:
   # cat /sys/block/sdb/sdb1/start
   2048

3. Format with f2fs-tools (before fix) and verify incorrect calculation:
   # mkfs.f2fs /dev/sdb1
   # Info: zone aligned segment0 blkaddr: 512

   The calculation happens in
   mkfs/f2fs_format.c:f2fs_prepare_super_block():

   With default values:
   - blk_size_bytes = 4096
   - c.blks_per_seg = 512
   - c.segs_per_sec = 1
   - c.secs_per_zone = 1
   - zone_size_bytes = blk_size_bytes * c.secs_per_zone
                       * c.segs_per_sec * c.blks_per_seg
                     = 4096 * 1 * 1 * 512 = 2,097,152 bytes (2MB)
   - alignment_bytes = zone_size_bytes (for non-zoned or single device)

   With c.start_sector = 0 (bug case):
   - zone_align_start_offset
       = ((c.start_sector * DEFAULT_SECTOR_SIZE +
          2 * F2FS_BLKSIZE + alignment_bytes - 1) /
          alignment_bytes * alignment_bytes) -
          (c.start_sector * DEFAULT_SECTOR_SIZE)
       = ((0 * 512 + 2 * 4096 + 2,097,152 - 1) /
          2,097,152 * 2,097,152) - (0 * 512)
       = ((8,192 + 2,097,152 - 1) / 2,097,152 * 2,097,152) - 0
       = 2,097,152 - 0 = 2,097,152 bytes (2MB)
   - segment0_blkaddr = zone_align_start_offset / blk_size_bytes
       = 2,097,152 / 4,096 = 512 blocks

   This matches the output "segment0 blkaddr: 512".

   With c.start_sector = 2048 (correct case):
   - zone_align_start_offset
       = ((2048 * 512 + 2 * 4096 + 2,097,152 - 1) /
          2,097,152 * 2,097,152) - (2048 * 512)
       = ((1,048,576 + 8,192 + 2,097,152 - 1) /
          2,097,152 * 2,097,152) - 1,048,576
       = 2,097,152 - 1,048,576 = 1,048,576 bytes (1MB)
   - segment0_blkaddr = zone_align_start_offset / blk_size_bytes
       = 1,048,576 / 4,096 = 256 blocks

4. Confirm the bug with gdb:
   So the correct output should be "segment0 blkaddr: 256", not 512.

   # gdb --args mkfs.f2fs /dev/sdb1
   (gdb) b lib/libf2fs.c:1075
   (gdb) run
   1075                    if (i == 0) {
   (gdb) l
   1075                    if (i == 0) {
   1076    #ifdef HDIO_GETGIO
   1077                            if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
   1078                                    c.start_sector = 0;
   1079                            else
   1080                                    c.start_sector = geom.start;
   1081    #else
   1082                            c.start_sector = 0;
   1083    #endif
   1084                    }
   (gdb) n
   1082                            c.start_sector = 0;
   # At line 1076: #ifdef HDIO_GETGIO (bug - this macro doesn't exist)
   # The ioctl() call at line 1077 is skipped, and execution goes
   # directly to line 1082, setting c.start_sector = 0

After fix:
   mkfs.f2fs output:
   Info: zone aligned segment0 blkaddr: 256

   gdb output:
   (gdb) p c.start_sector
   $1 = 2048

   The ioctl() correctly retrieves the partition start sector (2048),
   and zone_align_start_offset is calculated correctly, resulting in
   segment0_blkaddr = 256.

Fixes: 43bb7b6c99fa ("f2fs-tools: build binaries in Mac")
Signed-off-by: Xiaole He <[email protected]>
---
 lib/libf2fs.c  | 4 ++--
 tools/fibmap.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 1a496b7..a3508c8 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -964,7 +964,7 @@ int get_device_info(int i)
        uint32_t total_sectors;
 #endif
        struct stat *stat_buf;
-#ifdef HDIO_GETGIO
+#ifdef HDIO_GETGEO
        struct hd_geometry geom;
 #endif
 #if !defined(WITH_ANDROID) && defined(__linux__)
@@ -1073,7 +1073,7 @@ int get_device_info(int i)
                dev->total_sectors /= dev->sector_size;
 
                if (i == 0) {
-#ifdef HDIO_GETGIO
+#ifdef HDIO_GETGEO
                        if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
                                c.start_sector = 0;
                        else
diff --git a/tools/fibmap.c b/tools/fibmap.c
index 3acc77b..0a92551 100644
--- a/tools/fibmap.c
+++ b/tools/fibmap.c
@@ -88,7 +88,7 @@ static void stat_bdev(struct stat *st, unsigned int 
*start_lba)
 #endif
 {
        struct stat bdev_stat;
-#ifdef HDIO_GETGIO
+#ifdef HDIO_GETGEO
        struct hd_geometry geom;
 #endif
        char devname[32] = { 0, };
@@ -105,7 +105,7 @@ static void stat_bdev(struct stat *st, unsigned int 
*start_lba)
                goto out;
 
        if (S_ISBLK(bdev_stat.st_mode)) {
-#ifdef HDIO_GETGIO
+#ifdef HDIO_GETGEO
                if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
                        *start_lba = 0;
                else
-- 
2.43.0



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to