1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <memory.h>
#include <errno.h>
#include <stdbool.h>
#include "verbose.h"
#include "arch.h"
bool disk_dev_open(disk_dev_t *dev, const char *path)
{
dev->fd = open(path, O_RDWR|O_DIRECT);
if (dev->fd < 0) {
INFO("Failed to open device %s with write permission, retrying without", path);
dev->fd = open(path, O_RDONLY|O_DIRECT);
}
return dev->fd >= 0;
}
void disk_dev_close(disk_dev_t *dev)
{
close(dev->fd);
dev->fd = -1;
}
ssize_t disk_dev_read(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res)
{
ssize_t ret = pread(dev->fd, buf, len_bytes, offset_bytes);
if (ret == len_bytes) {
io_res->data = DATA_FULL;
io_res->error = ERROR_NONE;
return ret;
} else if (ret > 0) {
io_res->data = DATA_PARTIAL;
io_res->error = ERROR_NONE;
return ret;
} else if (ret == 0) {
io_res->data = DATA_NONE;
io_res->error = ERROR_NONE;
return ret;
} else {
// ret < 0, i.e. error
INFO("Error reading from disk, offset=%lu len=%u errno=%d (%s)",
offset_bytes, len_bytes, errno, strerror(errno));
io_res->data = DATA_NONE;
io_res->error = ERROR_UNCORRECTED;
io_res->sense_len = 0;
memset(&io_res->info, 0, sizeof(io_res->info));
return -1;
}
//TODO: Handle EINTR with a retry
}
ssize_t disk_dev_write(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res)
{
ssize_t ret = pwrite(dev->fd, buf, len_bytes, offset_bytes);
if (ret == len_bytes) {
io_res->data = DATA_FULL;
io_res->error = ERROR_NONE;
return ret;
} else if (ret > 0) {
io_res->data = DATA_PARTIAL;
io_res->error = ERROR_NONE;
return ret;
} else if (ret == 0) {
io_res->data = DATA_NONE;
io_res->error = ERROR_NONE;
return ret;
} else {
// ret < 0, i.e. error
io_res->data = DATA_NONE;
io_res->error = ERROR_UNCORRECTED;
io_res->sense_len = 0;
memset(&io_res->info, 0, sizeof(io_res->info));
return -1;
}
//TODO: Handle EINTR with a retry
}
void disk_dev_cdb_in(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res)
{
(void)sense_size;
(void)sense;
(void)buf_size;
(void)buf;
(void)cdb_len;
(void)cdb;
(void)dev;
*sense_read = 0;
*buf_read = 0;
memset(&io_res, 0, sizeof(*io_res));
io_res->data = DATA_NONE;
io_res->error = ERROR_NONE;
}
|