How can I find out the size of a block device, such as /dev/sda
? Running ls -l
gives no useful information.
21 Answers
blockdev --getsize64 /dev/sda
returns size in bytes.
blockdev --getsz /dev/sda
returns size in 512-byte sectors.
Deprecated: blockdev --getsize /dev/sda
returns size in sectors.
blockdev is part of util-linux.
-
5
-
13@heinrich5991 you have no choice. A normal user cannot access a block device directly ("raw reading" it), which is good for security.– TotorCommented May 23, 2013 at 7:38
-
3@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.– Luke404Commented Aug 1, 2013 at 7:24
-
2The manpage at linux.die.net/man/8/blockdev says
--getsize
is deprecated, and suggests--getsz
for consistent 512-byte sectors. If--getsize
must be used, I guess--getss
should also be used to make sure the sector size is what you expect. Commented Jan 28, 2018 at 17:49 -
2It doesn't seem that
blockdev --getsize*
(and, probably, underlying BLKGETSIZE64 ioctl) requires superuser powers if the user has read permission for the disk device node: ``` # sudo -u user id uid=314(user) gid=4000(eng) groups=4000(eng) # ls -l hdw1 brw-rw---- 1 user disk 8, 177 Apr 10 17:17 hdw1 # sudo -u user blockdev --getsize64 hdw1 983040 # ls -l $(which blockdev) # no setuid bit -rwxr-xr-x 2 root root 26752 Dec 31 1999 /sbin/blockdev ``` Commented Apr 19, 2018 at 17:16
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
-
This doesn't work for things like CD drives Commented Apr 22, 2010 at 20:30
-
2And 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)– Luke404Commented Jul 30, 2013 at 8:32
-
3The values reported here are multiples of 1KiB which may be one sector (512 byte) too small. Commented Dec 26, 2015 at 21:31
-
2This was useful to me. I ended up doing
awk '/sd[a-z]$/{printf "%s %8.2f GiB\n", $NF, $(NF-1) / 1024 / 1024}' /proc/partitions
– suprjamiCommented Aug 5, 2016 at 3:01
cat /sys/class/block/sda/size
This gives you its size in 512-byte blocks.
-
13@heinrich5991 How can you be sure the device block-size is always 512 bytes?– TotorCommented May 26, 2013 at 19:19
-
10The sector size is always 512 bytes according to the source. For the future, I am trying to get this interface documented. Commented Dec 26, 2015 at 21:39
-
Thank you for making that clear. I noticed that there's also a /sys/class/block/sda/queue/logical_block_size. I wasn't sure if I should use that, or the constant 512. Commented Oct 4, 2019 at 23:10
-
Usually compact disks have 2kB sectors. Adding hidden data, 2352 bytes.– pbiesCommented Nov 4, 2021 at 4:27
-
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.– JCCyCCommented Jun 22, 2012 at 1:14
-
12@JCCyC:
BLKGETSIZE64
returns the size in bytes. Seelinux/fs.h
, which notes "return device size in bytes". Note thatBLKGETSIZE
(no "64") returns it "/512".– ThanatosCommented Mar 3, 2013 at 23:26 -
I worked out a fuller sample partly based on this at stackoverflow.com/a/48490543/446106. To use the above snippet here,
file
needs to be a file descriptor (e.g. fromopen()
), andfile_size_in_bytes
should be asize_t
. Commented Jan 28, 2018 at 19:54 -
1(Actually,
file_size_in_bytes
should be a 64-bit type, so it should beunsigned long long
.) Commented Jan 28, 2018 at 20:17
How about:
sudo fdisk -l
This will give you a list of all your disks with their respective capacity, usage, file system, and more.
Interactive use
lsblk -no SIZE /dev/block-device
Note that, if there are partitions, you get a list with the total size of the device followed by the size of each partition or you can append the partition to the device name.
Scripting
If you need to store the size in a variable, use:
size=$(lsblk -bno SIZE /dev/path | head -1)
Now, the result is always in bytes and, if path
does not include a partition, it is the total disk size, otherwise it is the partition size.
blockdev --getsize /dev/sda
-
1
echo "`cat /sys/class/block/sda2/size`*512" | bc
or if you use bash or any other POSIX-like shell whose arithmetic operators work with 64bit integers, you don't even need to call bc
echo "$((512*$(cat /sys/class/block/sda2/size)))"
gives the size in byte.
The call to cat
and fork (except for bash
) can be optimised away with bash
, ksh93
and zsh
with:
echo "$((512*$(</sys/class/block/sda2/size)))"
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.
-
1If you're looking for the size of the raw disk drive, you'll need root privs to open the file to seek to the end. Commented Oct 4, 2019 at 23:12
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)))
-
1Actually, I think you have those reversed. (Unless my system has 512-byte physical blocks and 4096-byte logical blocks.) Commented Jul 10, 2012 at 19:24
-
2Well, I realized that
block/ioctl.c
in Linux kernel source contains misleading comments. BLKPBSZGET (notice the P) gets physical sector size, BLKSSZGET gets logical sector size and BLKBSZGET (or BLKBSZGET_32 inblock/compat_ioctl.c
) gets file system allocation unit (cluster) size. Logical and physical sector size differ when Advanced Format 512e is used. (512e @ WP)– PalecCommented Feb 22, 2015 at 21:03 -
@Palec Most knowledgeful comment among all answers and comments to this question. Commented Sep 5, 2019 at 9:26
A block is a sequence of bit or Bytes with a fixed length ie 512 bytes, 4kB, 8kB, 16kB, 32kB etc.
blockdev --getbsz partition
Example
# blockdev --getbsz /dev/sda1
4096
So the block size of this file system is 4kB.
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 512 bytes
(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 Commented Oct 5, 2013 at 11:02
-
If you are using Node.js, you can use this native add on to get block device size, physical sector size and logical sector size (with support for FreeBSD, Linux, macOS and Windows). It also has a few other helpers for doing direct IO:
To show disks sizes in human readable form, type this as a simple user :
$ lsblk -do NAME,SIZE /dev/sd?
NAME SIZE
sda 75G
sdb 200G
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 */
}
See http://lkml.indiana.edu/hypermail/linux/kernel/0105.2/0744.html
-
1Abuse of assert: If you disable assertions, your necessary side-effects won't happen anymore.– AlfeCommented Jun 20, 2012 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/
echo "`blockdev --getbsz /dev/sdc`/1024"|bc
will show output in KB
[root@veritas datadg2]# echo "`blockdev --getbsz /dev/sdc`/1024"|bc
4
[root@veritas datadg2]#
-
bash can do calculations inline:
echo $(( $(blockdev ...)/1024 ))
. Also note,--getbsz
gives the size of the block, not the size of the device. Commented Jan 28, 2018 at 18:59
If you want to find it programmatically in C, checkout code of util-linux package - https://github.com/karelzak/util-linux/blob/master/lib/blkdev.c#L81
OR this is also useful - http://www.linuxproblem.org/art_20.html
(The code works on Linux Kernel version 5.0.0-32-generic
.)
Both these codes use ioctl system call.
fdisk -l /dev/sda | grep -m1 ^Disk | awk '{print $3 " " $4}'
I find it very useful than all those standard tools or proc entries
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)
-
6
-
6This 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?– kbyrdCommented Apr 25, 2014 at 22:01