# Determine the size of a block device

How can I find out the size of a block device, such as /dev/sda? Running ls -l gives no useful information.

-

## migrated from stackoverflow.comOct 18 '12 at 16:39

This question came from our site for professional and enthusiast programmers.

fdisk doesn't understand the partition layout used by my Mac running Linux, nor any other non-PC partition format. (Yes, there's mac-fdisk for old Mac partition tables, and gdisk for newer GPT partition table, but those aren't the only other partition layouts out there.)

Since the kernel already scanned the partition layouts when the block device came into service, why not ask it directly?

$cat /proc/partitions major minor #blocks name 8 16 390711384 sdb 8 17 514079 sdb1 8 18 390194752 sdb2 8 32 976762584 sdc 8 33 514079 sdc1 8 34 976245952 sdc2 8 0 156290904 sda 8 1 514079 sda1 8 2 155774272 sda2 8 48 1465138584 sdd 8 49 514079 sdd1 8 50 1464621952 sdd2  - +1: thanks for the addl info. – Wadih M. Jun 22 '09 at 19:38 This doesn't work for things like CD drives – Ganesh Sittampalam Apr 22 '10 at 20:30 And also only reports "native" names. On a server with iSCSI and/or multipath and/or LVM you get lots and lots of sd* and dm-* devices but usually you need to lookup the symlink of the one you're actually interested in (e.g.. a /dev/mapper/* one) – Luke404 Jul 30 '13 at 8:32 blockdev --getsize64 /dev/sda returns size in bytes. blockdev --getsize /dev/sda returns size in sectors. - unfortunately needs superuser power – heinrich5991 Oct 3 '12 at 18:51 @heinrich5991 you have no choice. A normal user cannot access a block device directly ("raw reading" it), which is good for security. – Totor May 23 '13 at 7:38 @Totor Sure, but yet there are answers to this specific question that don't require any super user rights. – heinrich5991 May 23 '13 at 7:49 @heinrich5991 technically it's rather useless to know how big a block device is if you cannot even read it... – Luke404 Jul 30 '13 at 8:35 @heinrich5991 when working with filesystems you should ask statfs() and friends. More importantly, you should not assume any direct relationship between the block device size and total / usable / effective / free / whatever space on filesystem. – Luke404 Aug 1 '13 at 7:24 This simple code. Couldn't find any documentation, but does the trick nicely: #include <linux/fs.h> ... ioctl(file, BLKGETSIZE64, &file_size_in_bytes);  - Correction: it actually gets you the size in SECTORS. Edit it and I'll upvote. – JCCyC Jun 22 '12 at 1:14 @JCCyC: BLKGETSIZE64 returns the size in bytes. See linux/fs.h, which notes "return device size in bytes". Note that BLKGETSIZE (no "64") returns it "/512". – Thanatos Mar 3 '13 at 23:26 cat /sys/class/block/sda/size  This gives you its size in 512-byte blocks. - @heinrich5991 How can you be sure the device block-size is always 512 bytes? – Totor May 26 '13 at 19:19 How about: fdisk -l  This will give you a list of all your disks with their respective capacity, usage, and more. - Try it with sudo, otherwise it just prints nothing. – Alfe Jun 20 '12 at 10:23 blockdev --getsize /dev/sda - echo cat /sys/class/block/sda2/size*512 | bc or if you use bash, you don't even need to call bc echo$((512*$(cat /sys/class/block/sda2/size))) gives size in byte - First, my thanks to all who contributed. I learned a few useful things. Still, my experience is that most of these answers are somewhat incomplete, at least where CD and DVDs are concerned, notably regarding whether they are available to normal users rather than restricted to the superuser. This is based on tests on my Linux Mageia 2. Commands intended for the superuser can always be accessed by a normal user by prefixing them with /sbin/, or sometimes with /usr/sbin/. Now they may or may not work for a normal user. Many may work, for a normal user, for a DVD on the DVD drive, even when it is not mounted, while they will not work for a hard disk (again when invoked as normal user). For example /sbin/fdisk -l /dev/cdrom will work on my system and give the "geometry" of the DVD in the drive ... which is apparently mostly nonsense. But it does give the size of the DVD in bytes and in sectors, and a correct sector size (of 2048 bytes as is usual for DVD). The same is true of /usr/sbin/gdisk -l /dev/cdrom, which give only the size in sectors of 2048 bytes. other examples (as non-root, normal user) $ /sbin/blockdev --getss /dev/cdrom   # DVD sector size
2048
$/sbin/blockdev --getsize64 /dev/cdrom # DVD byte size 5453316096$ cat /proc/partitions  # see below
...
8        8  416027241 sda8
11        0    5325504 sr0
8       16 1465138584 sdb
...


This works for the DVD drive, here called sr0, since the device for it is actually /dev/sr0, /dev/cdrom being only a symbolic link to it. The size is given in chunks of 1k.

Similarly, as normal user, the command

$cat /sys/class/block/sr0/size 10651008  will give the size of a DVD on device /dev/sr0, in chunks of 512k (as well as the size of other disk, even not mounted). However cat /sys/class/block/cdrom/size will not work be cause /dev/cdrom is only a symbolic link The command df, suggested by some, gives the size of mounted partitions, not of whole disks. Furthermore, for a mounted CD or DVD it gives less than the actual size of the CD/DVD. More precisely, there are two distinct sizes one may be interested in : • the overall size of the device, including what is used for its internal organization. Typically that is the size of the file obtained if it is copied whole with the command dd; • the size of the space available (possibly only in read-only mode) to the user when it is mounted, which is always less. That is the size that is indicated by the command df. - uptick for$ /sbin/blockdev --getss /dev/cdrom # DVD sector size –  peterretief Oct 5 '13 at 11:02

The blockdev(8) has a different answer? Options --getsz and deprecated --getsize are not the same.

BLKSSZGET (blockdev --getss) is for physical sector size and BLKBSZGET (blockdev --getbsz) is for logical sector size.

echo $(($(blockdev --getsize64 /dev/sda)/(blockdev --getss /dev/sda)))  - Actually, I think you have those reversed. (Unless my system has 512-byte physical blocks and 4096-byte logical blocks.) – Edward Falk Jul 10 '12 at 19:24 No need for ioctl in C. Just seek to the end of the file and get the size (in bytes) that way: /* define this before any #includes when dealing with large files: */ #define _FILE_OFFSET_BITS 64 #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> // ... int fd = open("/dev/sda", O_RDONLY); off_t size = lseek(fd, 0, SEEK_END); // Now size is the size of the file, in bytes, or -1 on error. // lseek(fd, 0, SEEK_SET) to get back to the start of the file.  - df -k | grep /dev/sda  will give you the size in KB (first number) as well as the space used (second number) and space available (third number) - That's only if the filesystem is mounted. – lfaraone Jun 22 '09 at 12:54 This isn't about block device space, it will give you used and usable space of filesystems mounted that happen to be on /dev/sda. What about unpartitioned space? What if you have multiple partitions? – kbyrd Apr 25 '14 at 22:01 Is /sys/block/sda/size in block size? If so which one? The ioctl BLKGETSIZE has the same problem as it is in units of 512 rather than BLKSSZGET. BLKGETSIZE64 solves this ambiguity. The real block count is BLKGETSIZE64/BLKSSZGET. /*BINFMTC: http://lkml.indiana.edu/hypermail/linux/kernel/0105.2/0744.html */ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/fs.h> #include <assert.h> int main(int argc, char **argv) { int fd; long blk=0L; long ssz=0L; long long oct=0LL; if((fd=open(argv[1],O_RDONLY))<0) { perror(argv[1]); exit(1); } if(ioctl(fd,BLKGETSIZE,&blk)<0) { perror("BLKGETSIZE"); exit(1); } if(ioctl(fd,BLKSSZGET,&ssz)<0) { perror("BLKSSZGET"); exit(1); } if(ioctl(fd,BLKGETSIZE64,&oct)<0) { perror("BLKGETSIZE64"); exit(1); } if(close(fd)<0) { perror("close"); exit(1); } printf("BLKGETSIZE=%ld BLKSSZGET=%ld BLKGETSIZE64=%lld BLKGETSIZE64/BLKSSZGET=%ld SIZEGB=%f #%f\240GiB\n\n",\ blk,ssz,oct,(long)(oct/(long long)ssz),(double)oct/1000000000.0,(double)oct/1073741824.0); fflush(stdout); /* before exec */ execl("/bin/bash","bash","-c",\ "for i in \ /sys/block/?d?/{size,alignment_offset,?d??/size,?d??/alignment_offset,queue/*block*,queue/*sector*}; \ do test -f \"i\" && echo \"$i:$(<\$i)\"; done"\
,NULL);

exit(127);
return 127; /* not reached */
}

-
Abuse of assert: If you disable assertions, your necessary side-effects won't happen anymore. –  Alfe Jun 20 '12 at 10:25

There is an EMC utility called inq which gives information about all types of block devices like local attached, SAN based, etc.

Try it out.

ftp://ftp.emc.com/pub/symm3000/inquiry/

Here is a brief description of what it does: http://slashzeroconf.wordpress.com/2009/02/09/emc-inq-utility/

-

lsblk gives the information you are looking for, including device types and mountpoints (if any), with a tree view and in a human readable format.

Device type means that it works for CD drives, as asked by Ganesh Sittampalam.

-