tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Issues with lseek(2) on a block device



On Wed, 21 Feb 2024 12:48:34 -0800
Jason Thorpe <thorpej%me.com@localhost> wrote:

> 
> > On Feb 21, 2024, at 2:52 AM, Sad Clouds <cryintothebluesky%gmail.com@localhost> wrote:
> > 
> > Hello, for most operating systems determining the size of a block
> > device can be done with:
> > 
> > lseek(fd, 0, SEEK_END);
> 
> On what operating systems does this do what you claim?
> 
> > However, on NetBSD this does not seem to work.
> 
> It doesn’t work on macOS, either:
> 
> thorpej-mbp:thorpej 541$ sudo ./lseek /dev/disk4
> Password:
> lseek(fd, 4096, SEEK_SET) = 4096 bytes
> lseek(fd, 0, SEEK_END)    = 0 bytes
> thorpej-mbp:thorpej 542$ 
> 
> -- thorpej
> 

Hello, it works on Linux, FreeBSD, Solaris and it also works on NetBSD
but only with ld(4) driver, with SCSI or SATA drives, lseek returns
bogus size of 0 bytes, even though the kernel knows the size of block
device, otherwise partition formatting would be impossible.

Specifically for NetBSD:

# uname -mps
NetBSD evbarm earmv7hf

# dmesg | grep ld0
[     1.768438] ld0 at sdmmc0: <0x03:0x5344:SE16G:0x80:0x08834ec0:0x0d8>
[     1.768438] ld0: 15193 MB, 7717 cyl, 64 head, 63 sec, 512 bytes/sect x 31116288 sectors
[     1.798199] ld0: 4-bit width, High-Speed/SDR25, 50.000 MHz
[     2.338199] boot device: ld0
[     2.338199] root on ld0a dumps on ld0b

Initially stat on /dev/ld0 reports size as 0 bytes:
# stat -x /dev/ld0
  File: "/dev/ld0"
  Size: 0            Blocks: 0            IO Block: 2048         Block Device
Device: 92,0   Inode: 1573    Links: 1
  Mode: (0640/brw-r-----)         Uid: (    0/    root)  Gid: (    5/operator)
Access: 2024-02-21 13:30:44.666619198 +0000
Modify: 2021-10-17 17:58:03.000000000 +0100
Change: 2021-10-17 17:58:03.000000000 +0100
 Birth: 1970-01-01 01:00:00.000000000 +0100

So stat is no good here, let's try lseek:
# gcc -Wall -Wpedantic lseek_test.c && ./a.out
lseek(fd, 4096, SEEK_SET) = 4096 bytes
lseek(fd, 0, SEEK_END)    = 15931539456 bytes

But now, after lseek, stat reports the correct size:
# stat -x /dev/ld0
  File: "/dev/ld0"
  Size: 15931539456  Blocks: 0            IO Block: 2048         Block Device
Device: 92,0   Inode: 1573    Links: 1
  Mode: (0640/brw-r-----)         Uid: (    0/    root)  Gid: (    5/operator)
Access: 2024-02-21 13:30:44.666619198 +0000
Modify: 2021-10-17 17:58:03.000000000 +0100
Change: 2021-10-17 17:58:03.000000000 +0100
 Birth: 1970-01-01 01:00:00.000000000 +0100

This is such a buggy behaviour that I stopped using stat for finding
out block device size a long time ago, and not just on NetBSD.


Home | Main Index | Thread Index | Old Index