如何在linux中使用ioctl(原始分区)正确刷新磁盘缓存
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何在linux中使用ioctl(原始分区)正确刷新磁盘缓存,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2830字,纯文字阅读大概需要5分钟。
内容图文
![如何在linux中使用ioctl(原始分区)正确刷新磁盘缓存](/upload/InfoBanner/zyjiaocheng/965/a43fec6a91ef41cca00b69ec63c02119.jpg)
我正在尝试使用ioctl来确保直接写入卷的更改正在访问磁盘.
fsync()显然在原始分区中不可用. sync()也是一个可怕的解决方案(为了冲洗64MB,我需要整个生命时间等待同步)
所以..这就是我想要做的事情 – 得到错误25.
/ dev / sda3是ssd驱动器上的原始卸载分区
open(_fd, "/dev/sda3", ...)
pwritev(_fd, ...)
ioctl(_fd, BLKFLSBUF, 0) <== errno = 25.
Ubuntu 14.04,c
注意:
hdparm -W 0 /dev/sda3
失败:对设备不适当的ioctl.
如何为我的ssd找到合适的冲洗方法?
解决方法:
我不能使用4.2.0-42泛型内核在x86_64上的Ubuntu 14.04.4 LTS中复制ioctl(fd,BLKFLSBUF)错误.
我测试了两个完整的块设备,以及它们上的各个分区.你能试试下面的最小测试程序吗?
保存以下内容,例如块flush.c:
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int arg, descriptor, result;
if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
fprintf(stderr, " %s BLOCK-DEVICE-OR-PARTITION ...\n", argv[0]);
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
for (arg = 1; arg < argc; arg++) {
do {
descriptor = open(argv[arg], O_RDWR);
} while (descriptor == -1 && errno == EINTR);
if (descriptor == -1) {
const int cause = errno;
fprintf(stderr, "%s: Cannot open device: %s [%d].\n", argv[arg], strerror(cause), cause);
return EXIT_FAILURE;
}
errno = 0;
result = ioctl(descriptor, BLKFLSBUF);
if (result && errno) {
const int cause = errno;
fprintf(stderr, "%s: Cannot flush device: %s [%d].\n", argv[arg], strerror(cause), cause);
return EXIT_FAILURE;
} else
if (result)
fprintf(stderr, "%s: Flush returned %d.\n", argv[arg], result);
else
if (errno) {
const int cause = errno;
fprintf(stderr, "%s: Flush returned zero, but with error: %s [%d]. Ignored.\n", argv[arg], strerror(cause), cause);
}
result = close(descriptor);
if (result == -1) {
const int cause = errno;
fprintf(stderr, "%s: Error closing device: %s [%d].\n", argv[arg], strerror(cause), cause);
return EXIT_FAILURE;
}
fprintf(stderr, "%s: Flushed.\n", argv[arg]);
}
return EXIT_SUCCESS;
}
使用编译它
gcc -Wall -O2 block-flush.c -o block-flush
并运行它(以root身份),在命令行指定分区或块设备:
sudo ./block-flush /dev/sda3
对我来说,这输出/ dev / sdxN:刷新.对于未安装的分区,以及磁盘(/ dev / sdx)本身. (另外,在ioctl()之前添加fdatasync(描述符)不会改变任何东西,并且它也会成功而没有任何错误.)
此外,我碰巧使用外部USB SATA扩展坞和“响亮的”3.5“驱动器(这种扩展需要外部电源; USB电源不足以满足这些带有旋转盘片的大型驱动器)进行测试.我很容易听到ioctl ()确实访问物理设备,所以它不是无操作(并且,最小的测试程序再次没有报告我的测试中的任何失败).关闭描述符后,磁盘也是静止的,直到磁盘或分区是当然,这些观察仅适用于USB连接的硬盘驱动器,并且只适用于这种特定的内核和硬件架构,但在我看来,它确实表明ioctl(描述符,BLKFLSBUF);应该适用于未预装的分区和完整的块设备,以预期的方式.
内容总结
以上是互联网集市为您收集整理的如何在linux中使用ioctl(原始分区)正确刷新磁盘缓存全部内容,希望文章能够帮你解决如何在linux中使用ioctl(原始分区)正确刷新磁盘缓存所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。