在使用C/C++编程时,POSIX的物理磁盘块大小是多少?

7

我正在开发一个高性能I/O程序,尝试找到使用C++确定设备磁盘块的_physical_(而不是_logical_)字节大小的最佳方法。目前我的研究得出以下代码片段:

#include <iostream>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char ** argv)
{
    // file information including block size of the device
    struct stat info;
    // device to get block size from
    char * device = "/mnt/hdb1";

    if (stat(device, &info))
    {
        printf("stat() error");
        strerror(errno);
        exit(1);
    }
    printf("Prefered block size for '%s' is %i byte\n", device, info.st_blksize);
    return 0;
}

该手册介绍了st_blksize的相关信息:

st_blksize字段为高效的文件系统I/O提供了“首选”块大小。(以较小的块写入文件可能会导致低效的读-修改-重写。)

但是,该手册没有提到st_blksize是逻辑块大小还是物理磁盘块大小。
因此,st_blksize物理磁盘块大小吗?如果是,那么这是否是检测物理磁盘块大小的最常见的POSIX操作系统的可移植方式呢?

3
我认为通过POSIX不可能实现。 - Prof. Falken
我想知道/dev/nullst_blksize是什么意思。我想知道这是物理大小还是逻辑大小。 - Dan Moulding
@DanMoulding /dev/null 是一个字符设备,而不是块设备。 - Anya Shenanigans
@Petesh:你能告诉我在POSIX标准中这个区别是在哪里定义的吗? - Dan Moulding
@DanMoulding 这将涉及到 stat 中的 st_mode 字段。这大概是 POSIX 所能说出字符设备和块设备之间差异的全部了。 - Anya Shenanigans
1个回答

5
我写了一个答案,虽然充满希望,但对于块设备并没有正确工作。
没有 POSIX 机制可以获取设备的基本物理块大小,您将不得不使用平台相关的 ioctl。
对于 Linux,有 ioctl(fd, BLKPBSZGET, &block_size)
对于 Solaris,有 dkio 接口,可让您获取物理块大小。
dk_minfo_ext media_info;
if (-1 != ioctl(fd, DKIOMEDIAINFOEXT, &media_info))
    block_size = media_info.dki_pbsize;

对于 Mac OS X,它是 ioctl(fd, DKIOCGETPHYSICALBLOCKSIZE, &block_size)

对于 FreeBSD,应该是 iotcl(fd, DIOCGSECTORSIZE, &block_size)


ioctl(fd, FIGETBSZ, &block_size) 这个怎么样? FIGETBSZphysical blocksize 吗? - user152949
@IngeHenriksen 不是,它是文件系统块大小,以文件系统块分配策略为单位。 - Anya Shenanigans
在 Windows 上使用 GetDiskFreeSpaceEx() :) - Cesar Ortiz
@CesarOrtiz 你需要使用虚拟磁盘服务,它允许确定磁盘的块大小;至于其他块设备,我不清楚。 - Anya Shenanigans
@CesarOrtiz 不行,这只能在Windows上获取逻辑块大小,你需要使用 DeviceIoControl() 进行 IOCTL_STORAGE_QUERY_PROPERTY 存储查询:STORAGE_PROPERTY_QUERY storageQuery; storageQuery.PropertyId = StorageAccessAlignmentProperty; storageQuery.QueryType = PropertyStandardQuery; STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR diskAlignment = {0}; DeviceIoControl(hDrive, IOCTL_STORAGE_QUERY_PROPERTY, &storageQuery, sizeof(STORAGE_PROPERTY_QUERY), &diskAlignment, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), &outsize, NULL); std::cout<<diskAlignment.BytesPerPhysicalSector; - user152949

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接