Я хочу сделать базовый read()
с жесткого диска SATA /dev/sdd
. A write()
похоже работает. Также read()
и write()
работает без O_DIRECT
Флаг. Я читал, что он должен быть привязан к блочному. Поэтому я использовал это, чтобы получить размер блока:чтение() с жесткого диска с ошибкой O_DIRECT с 22 (EINVAL, Invalid Argument)
root$ blockdev --getsize /dev/sdd
488397168
root$ blockdev --getsize64 /dev/sdd
250059350016
root$ python -c "print 250059350016.0/488397168"
512.0
Как вы можете видеть, у меня есть корень. Жесткий диск подключен через PCIe SATA Card, и lspci -vv
показывает мне, что он использует базовый драйвер ahci (drivers/ata/ahci.c
). Я работаю с ядром Linux 3.2.0 на 64-битной архитектуре питания.
Вот мой код:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main() {
int r;
char *buffer, *tmp_buffer;
// alloc more than necesarry to align the real buffer
tmp_buffer = malloc(2*512*sizeof(char));
long align = (unsigned long)tmp_buffer%512;
printf("tmp_buffer is at: %x \% 512 = %d\n",tmp_buffer,align);
buffer = tmp_buffer+(512-align);
printf("buffer is at: %x \% 512 = %d\n",buffer,(unsigned long)buffer%512);
memset(buffer,0,sizeof(512));
// OPEN
int fd = open("/dev/sdd",O_DIRECT | O_RDWR | O_SYNC);
if(fd!=3) printf("fd = %d\n",fd);
// READ
printf("try to read and then dump buffer:\n");
r = read(fd,buffer,sizeof(512));
if(r == -1) printf("Error: %s\n",strerror(errno));
else {
// DUMP BUFFER
int i;
for(i=0; i<sizeof(512); i++)
printf("%c",buffer[i]);
}
printf("\n");
return 0;
}
Выход:
tmp_buffer is at: 1cc80010 % 512 = 16
buffer is at: 1cc80200 % 512 = 0
try to read and then dump buffer:
Error: Invalid argument
редактировать: Я обновил свой источник, предложенный ответ Бретта Хейла. К сожалению, я все еще получаю ошибку. Могу ли я узнать, что в блоках нормально? Правильно ли я сделал выравнивание?
Большое спасибо за чтение,
Fabian
ahh Мне нужно выровнять мой буфер? Я думал, что позиция filepointer всегда должна быть выровнена (так что 0 в порядке), и получение 512 байтов для выравнивания по правильному пути - это правильный путь. Я обновил свой исходный код, но я все еще получаю сообщение об ошибке. Не могли бы вы быть добрыми и проверить, что я сделал? :) – samuirai
@samuirai, есть интересная тема [здесь] (http://kerneltrap.org/node/7563) (2.6.x) с комментариями босса. –
Да, я прочитал это. Для этого проекта очень важны ограничения скорости и мощности. Я должен рассказать о том, как быстро мы можем писать. Я слишком незнаю, чтобы задать вопрос: / – samuirai