File: arch-posix.c

package info (click to toggle)
diskscan 0.21-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,656 kB
  • sloc: ansic: 11,136; python: 338; xml: 138; sh: 41; makefile: 34
file content (99 lines) | stat: -rw-r--r-- 2,502 bytes parent folder | download | duplicates (6)
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;
}