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.
21 Answers 21
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.
@heinrich5991 you have no choice. A normal user cannot access a block device directly («raw reading» it), which is good for security.
@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.
The 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.
It 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 «`
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
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)
This was useful to me. I ended up doing awk ‘/sd[a-z]$/
This gives you its size in 512-byte blocks.
The sector size is always 512 bytes according to the source. For the future, I am trying to get this interface documented.
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.
This simple code. Couldn’t find any documentation, but does the trick nicely:
#include . ioctl(file, BLKGETSIZE64, &file_size_in_bytes);
@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».
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. from open() ), and file_size_in_bytes should be a size_t .
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.
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)))"
The call to cat and fork (except for bash ) can be optimised away with bash , ksh93 and zsh with:
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 #include #include #include // . 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.
If 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.
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.)
Well, 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 in block/compat_ioctl.c ) gets file system allocation unit (cluster) size. Logical and physical sector size differ when Advanced Format 512e is used. (512e @ WP)
A block is a sequence of bit or Bytes with a fixed length ie 512 bytes, 4kB, 8kB, 16kB, 32kB etc.
blockdev --getbsz partition
# blockdev --getbsz /dev/sda1 4096
So the block size of this file system is 4kB.
Analogy: number of bottles in crates.
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 .
How do I determine the block size for ext4 and btrfs filesystems?
I’m looking for the commands that will tell me the allocation quantum on drives formatted with ext4 vs btrfs. Background: I am using a backup system that allows users to restore individual files. This system just uses rsync and has no server-side software, backups are not compressed. The result is that I have some 3.6TB of files, most of them small. It appears that for my data set storage is much less efficient on a btrfs volume under LVM than it is on a plain old ext4 volume, and I suspect this has to do with the minimum file size, and thus the block size, but I have been unable to figure out how to get those sizes for comparison purposes. The btrfs wiki says that it uses the «page size» but there’s nothing I’ve found on obtaining that number.
Am I the only one that finds it strange that btrfs is under lvm? I’m more used to zfs, but I’m pretty sure btrfs, like zfs, also optimizes if it’s configured full stack (both volume and fs). Anyway, I seem to remember btrfs can provide better volume infrastructure than lvm.
3 Answers 3
You’ll want to look at the data block allocation size, which is the minimum block that any file can allocate. Large files consist of multiple blocks. And there’s always some «waste» at the end of large files (or all small files) where the final block isn’t filled entirely, and therefore unused.
As far as I know, every popular Linux filesystem uses 4K blocks by default because that’s the default pagesize of modern CPUs, which means that there’s an easy mapping between memory-mapped files and disk blocks. I know for a fact that BTRFS and Ext4 default to the page size (which is 4K on most systems).
On ext4, just use tune2fs to check your block size, as follows (change /dev/sda1 to your own device path):
[root@centos8 ~]# tune2fs -l /dev/sda1 |grep "^Block size:" Block size: 4096 [root@centos8 ~]#
On btrfs, use the following command to check your block size (change /dev/mapper/cr_root to your own device path, this example simply uses a typical encrypted BTRFS-on-LUKS path):
sudo btrfs inspect-internal dump-super -f /dev/mapper/cr_root | grep "^sectorsize"