1

I'm reading The Unix Programming Environment (1984). In Chapter 7 (Unix System Calls) the authors note:

While the number of bytes to be read or written is not restricted, the most cmmmon values are 1, which meanns one character at a time..., and the size of a block on a disc, most often 512 or 1024 bytes. (The parameter BUFSIZ in <stdio.h> has this value.)

I wrote a simple program to check this:

#include <stdio.h>

int main()
{
    printf("The BUFSIZ is %d\n", BUFSIZ);
    return 0;
}

On my system (Linux Mint) this returns 8192. That's quite a lot more than the "512 or 1024" mentioned in the book. I assumed this must be a difference based on historical circumstances.

Out of curiosity I looked up other ways to find this block size without writing my own C program and came across blockdev. It tells me this:

me@mint:~/src/c/unixprogenvbk$ sudo blockdev --getbsz /dev/sda1
4096

Why is this 4096 when the BUFSIZ val was 8192? Are these actually two different things?

1

I'm not sure what the paragraph from The Unix Programming Environment really means, but I don't think BUFSIZ is related to disk block size -- it wouldn't be possible, BUFSIZ is a constant and you can have different block sizes on different disks (some devices like NVMe and NVDIMMs even support changing block size).

I like this definiton from glibc documentation more:

The value of this macro is an integer constant expression that is good to use for the size argument to setvbuf. This value is guaranteed to be at least 256. The value of BUFSIZ is chosen on each system so as to make stream I/O efficient. So it is a good idea to use BUFSIZ as the size for the buffer when you call setvbuf.

But in stdio.h the BUFSIZ is just a constant set to 8192 to I'm nto sure why the documentation says it os chosen for each system.

blockdev uses BLKBSZGET ioctl to get the block size for specified device so it is the actual block size of the disk.

3
  • 2
    "it's chosen on each system" doesn't mean that it's configurable at run time, but that it can be different on a different architecture/operating system. FWIW, in glibc it's now 8192 everywhere.
    – user414777
    Nov 8 '20 at 6:04
  • 1
    Block devices won't have a mechanism to physically read part of a block: something, somewhere would be discarding data. But it's more efficient to read multiple physical blocks anyway, so a BUFSIZ that is a multiple of likely physical blocks is fine. In 1984, most disks controllers were so slow that "consecutive" physical blocks were offset around the tracks (maybe every 4th block), so the data rates could keep up with a multi-block transfer. Nov 8 '20 at 11:23
  • Also see the output of stat -c '%b %B %o %s %n', and du, on the same file, and stat -f -c '%s %S' /home. du counts (by default) in 1KiB units, stat calls segments blocks, and says 8x512 is optimum transfer. Nov 8 '20 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.