5

I am trying to get some information (specifically block size) of block device in linux, in C++. Is it possible to get block size of a device without mounting it and possibly without looking into dynamic files (like the ones in /sys), but with a system call only.

I was trying with stat, but it returns data about /dev filesystem if I ask about /dev/sdb2.

If it's impossible with system call, where should i look in dynamic files (haven't been able to locate it either.)

jww
  • 97,681
  • 90
  • 411
  • 885
j_kubik
  • 6,062
  • 1
  • 23
  • 42

2 Answers2

9

You want to use ioctl, in particular BLKSSZGET.

Quoting linux/fs.h:

#define BLKSSZGET  _IO(0x12,104)/* get block device sector size */

Untested example:

#include <sys/ioctl.h>
#include <linux/fs.h>

int fd = open("/dev/sda");
size_t blockSize;
int rc = ioctl(fd, BLKSSZGET, &blockSize);
Nowaker
  • 12,154
  • 4
  • 56
  • 62
themel
  • 8,825
  • 2
  • 32
  • 31
  • oh, may somebosy suggest, why am I getting a zero? – Tebe Apr 11 '12 at 23:04
  • 2
    @shbk - is blockSize zero or rc? Both being zero would be suprising. – themel Apr 12 '12 at 09:27
  • yeah,it was so. I should be more attentive. Thanks. – Tebe Apr 12 '12 at 09:37
  • 4
    For the record: BLKSSZGET = logical block size, BLKBSZGET = physical block size, BLKGETSIZE64 = device size in bytes, BLKGETSIZE = device size/512. At least if the comments in fs.h and my experiments can be trusted. – Edward Falk Jul 10 '12 at 19:33
0

I think the ioctl value should rather be unsigned long than size_t (the latest is more memory related), I would also initialize it to 0 (just in case BLKSSZGET returns unsigned int instead).

#include <sys/ioctl.h>
#include <linux/fs.h>

int fd = open("/dev/sda");
unsigned long blockSize = 0;
int rc = ioctl(fd, BLKSSZGET, &blockSize);
Abhijeet Kasurde
  • 3,937
  • 1
  • 24
  • 33
Bub
  • 1
  • 2
  • They're size_t's in `fs.h`, fwiw: `#define BLKBSZGET _IOR(0x12,112,size_t)` and `#define BLKBSZSET _IOW(0x12,113,size_t)`. – Mike Andrews Jul 21 '15 at 21:11