storage: Revise API

Pass "struct rmtfd" instead of file descriptors in the interface. This
cleans up the api a little bit, but more importantly allow us to
associate additional things with the remote file descriptors.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
Bjorn Andersson
2019-07-12 20:48:12 -07:00
parent 152b96981e
commit e6d703b3c8
3 changed files with 55 additions and 61 deletions

37
rmtfs.c
View File

@@ -51,6 +51,7 @@ static void rmtfs_open(int sock, const struct qrtr_packet *pkt)
struct rmtfs_open_resp resp = {};
struct rmtfs_open_req req = {};
DEFINE_QRTR_PACKET(resp_buf, 256);
struct rmtfd *rmtfd;
unsigned int txn;
ssize_t len;
int caller_id = -1;
@@ -63,12 +64,13 @@ static void rmtfs_open(int sock, const struct qrtr_packet *pkt)
goto respond;
}
caller_id = storage_get(pkt->node, req.path);
if (caller_id < 0) {
rmtfd = storage_open(pkt->node, req.path);
if (!rmtfd) {
qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL);
goto respond;
}
caller_id = storage_get_caller_id(rmtfd);
resp.caller_id = caller_id;
resp.caller_id_valid = true;
@@ -97,6 +99,7 @@ static void rmtfs_close(int sock, const struct qrtr_packet *pkt)
struct rmtfs_close_resp resp = {};
struct rmtfs_close_req req = {};
DEFINE_QRTR_PACKET(resp_buf, 256);
struct rmtfd *rmtfd;
unsigned int txn;
ssize_t len;
int ret;
@@ -108,11 +111,13 @@ static void rmtfs_close(int sock, const struct qrtr_packet *pkt)
goto respond;
}
ret = storage_put(pkt->node, req.caller_id);
if (ret < 0) {
rmtfd = storage_get(pkt->node, req.caller_id);
if (!rmtfd) {
qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL);
goto respond;
}
storage_close(rmtfd);
rmtfs_mem_free(rmem);
respond:
@@ -141,6 +146,7 @@ static void rmtfs_iovec(int sock, struct qrtr_packet *pkt)
struct rmtfs_iovec_resp resp = {};
struct rmtfs_iovec_req req = {};
DEFINE_QRTR_PACKET(resp_buf, 256);
struct rmtfd *rmtfd;
uint32_t caller_id = 0;
size_t num_entries = 0;
off_t sector_base;
@@ -153,7 +159,6 @@ static void rmtfs_iovec(int sock, struct qrtr_packet *pkt)
ssize_t n;
char buf[SECTOR_SIZE];
int ret;
int fd;
int i;
int j;
@@ -170,8 +175,8 @@ static void rmtfs_iovec(int sock, struct qrtr_packet *pkt)
num_entries = req.iovec_len;
force = req.is_force_sync;
fd = storage_get_handle(pkt->node, caller_id);
if (fd < 0) {
rmtfd = storage_get(pkt->node, caller_id);
if (!rmtfd) {
fprintf(stderr, "[RMTFS] iovec request for non-existing caller\n");
qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL);
goto respond;
@@ -186,9 +191,9 @@ static void rmtfs_iovec(int sock, struct qrtr_packet *pkt)
if (is_write) {
n = rmtfs_mem_read(rmem, phys_base + offset, buf, SECTOR_SIZE);
if (n == SECTOR_SIZE)
n = storage_pwrite(fd, buf, n, sector_base + offset);
n = storage_pwrite(rmtfd, buf, n, sector_base + offset);
} else {
n = storage_pread(fd, buf, SECTOR_SIZE, sector_base + offset);
n = storage_pread(rmtfd, buf, SECTOR_SIZE, sector_base + offset);
if (n >= 0) {
if (n < SECTOR_SIZE)
memset(buf + n, 0, SECTOR_SIZE - n);
@@ -287,7 +292,7 @@ static void rmtfs_get_dev_error(int sock, struct qrtr_packet *pkt)
struct rmtfs_dev_error_resp resp = {};
struct rmtfs_dev_error_req req = {};
DEFINE_QRTR_PACKET(resp_buf, 256);
int dev_error = 0;
struct rmtfd *rmtfd;
unsigned txn;
ssize_t len;
int ret;
@@ -300,17 +305,17 @@ static void rmtfs_get_dev_error(int sock, struct qrtr_packet *pkt)
goto respond;
}
dev_error = storage_get_error(pkt->node, req.caller_id);
if (dev_error < 0) {
rmtfd = storage_get(pkt->node, req.caller_id);
if (rmtfd) {
qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL);
goto respond;
}
resp.status = dev_error;
resp.status = storage_get_error(rmtfd);
resp.status_valid = true;
respond:
dbgprintf("[RMTFS] dev_error %d => %d (%d:%d)\n", req.caller_id, dev_error, resp.result.result, resp.result.error);
dbgprintf("[RMTFS] dev_error %d => %d (%d:%d)\n", req.caller_id, resp.status, resp.result.result, resp.result.error);
len = qmi_encode_message(&resp_buf,
QMI_RESPONSE, QMI_RMTFS_GET_DEV_ERROR, txn,
@@ -470,7 +475,7 @@ int main(int argc, char **argv)
if (!rmem)
return 1;
ret = storage_open(storage_root);
ret = storage_init(storage_root);
if (ret) {
fprintf(stderr, "failed to initialize storage system\n");
goto close_rmtfs_mem;
@@ -487,7 +492,7 @@ int main(int argc, char **argv)
ret = run_rmtfs();
} while (ret == -ENETRESET);
storage_close();
storage_exit();
close_rmtfs_mem:
rmtfs_mem_close(rmem);

19
rmtfs.h
View File

@@ -23,13 +23,16 @@ void rmtfs_mem_free(struct rmtfs_mem *rmem);
ssize_t rmtfs_mem_read(struct rmtfs_mem *rmem, unsigned long phys_address, void *buf, ssize_t len);
ssize_t rmtfs_mem_write(struct rmtfs_mem *rmem, unsigned long phys_address, const void *buf, ssize_t len);
int storage_open(const char *storage_root);
int storage_get(unsigned node, const char *path);
int storage_put(unsigned node, int caller_id);
int storage_get_handle(unsigned node, int caller_id);
int storage_get_error(unsigned node, int caller_id);
void storage_close(void);
ssize_t storage_pread(int fildes, void *buf, size_t nbyte, off_t offset);
ssize_t storage_pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
struct rmtfd;
int storage_init(const char *storage_root);
struct rmtfd *storage_open(unsigned node, const char *path);
struct rmtfd *storage_get(unsigned node, int caller_id);
void storage_close(struct rmtfd *rmtfd);
int storage_get_caller_id(const struct rmtfd *rmtfd);
int storage_get_error(const struct rmtfd *rmtfd);
void storage_exit(void);
ssize_t storage_pread(const struct rmtfd *rmtfd, void *buf, size_t nbyte, off_t offset);
ssize_t storage_pwrite(const struct rmtfd *rmtfd, const void *buf, size_t nbyte, off_t offset);
#endif

View File

@@ -34,7 +34,7 @@ static const struct partition partition_table[] = {
static struct rmtfd rmtfds[MAX_CALLERS];
int storage_open(const char *storage_root)
int storage_init(const char *storage_root)
{
int i;
@@ -49,7 +49,7 @@ int storage_open(const char *storage_root)
return 0;
}
int storage_get(unsigned node, const char *path)
struct rmtfd *storage_open(unsigned node, const char *path)
{
char *fspath;
const struct partition *part;
@@ -65,7 +65,7 @@ int storage_get(unsigned node, const char *path)
}
fprintf(stderr, "[RMTFS storage] request for unknown partition '%s', rejecting\n", path);
return -EPERM;
return NULL;
found:
/* Check if this node already has the requested path open */
@@ -73,7 +73,7 @@ found:
if (rmtfds[i].fd != -1 &&
rmtfds[i].node == node &&
rmtfds[i].partition == part)
return rmtfds[i].id;
return &rmtfds[i];
}
for (i = 0; i < MAX_CALLERS; i++) {
@@ -84,7 +84,7 @@ found:
}
if (!rmtfd) {
fprintf(stderr, "[storage] out of free rmtfd handles\n");
return -EBUSY;
return NULL;
}
pathlen = strlen(storage_dir) + strlen(part->actual) + 2;
@@ -95,63 +95,49 @@ found:
saved_errno = errno;
fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
fspath, part->path, strerror(saved_errno));
return -saved_errno;
errno = saved_errno;
return NULL;
}
rmtfd->node = node;
rmtfd->fd = fd;
rmtfd->partition = part;
return rmtfd->id;
return rmtfd;
}
int storage_put(unsigned node, int caller_id)
void storage_close(struct rmtfd *rmtfd)
{
struct rmtfd *rmtfd;
if (caller_id >= MAX_CALLERS)
return -EINVAL;
rmtfd = &rmtfds[caller_id];
if (rmtfd->node != node)
return -EINVAL;
close(rmtfd->fd);
rmtfd->fd = -1;
rmtfd->partition = NULL;
return 0;
}
int storage_get_handle(unsigned node, int caller_id)
struct rmtfd *storage_get(unsigned node, int caller_id)
{
struct rmtfd *rmtfd;
if (caller_id >= MAX_CALLERS)
return -EINVAL;
return NULL;
rmtfd = &rmtfds[caller_id];
if (rmtfd->node != node)
return -EINVAL;
return NULL;
return rmtfd->fd;
return rmtfd;
}
int storage_get_error(unsigned node, int caller_id)
int storage_get_caller_id(const struct rmtfd *rmtfd)
{
struct rmtfd *rmtfd;
if (caller_id >= MAX_CALLERS)
return -EINVAL;
rmtfd = &rmtfds[caller_id];
if (rmtfd->node != node)
return -EINVAL;
return rmtfd->id;
}
int storage_get_error(const struct rmtfd *rmtfd)
{
return rmtfd->dev_error;
}
void storage_close(void)
void storage_exit(void)
{
int i;
@@ -161,13 +147,13 @@ void storage_close(void)
}
}
ssize_t storage_pread(int fildes, void *buf, size_t nbyte, off_t offset)
ssize_t storage_pread(const struct rmtfd *rmtfd, void *buf, size_t nbyte, off_t offset)
{
return pread(fildes, buf, nbyte, offset);
return pread(rmtfd->fd, buf, nbyte, offset);
}
ssize_t storage_pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
ssize_t storage_pwrite(const struct rmtfd *rmtfd, const void *buf, size_t nbyte, off_t offset)
{
return pwrite(fildes, buf, nbyte, offset);
return pwrite(rmtfd->fd, buf, nbyte, offset);
}