Ivan Baravy
5822be9942
It is useless since host OS cache is used anyway. It also slows down coverage collection because of many taken branches. Specialized tests should be written to test disk cache specifically.
148 lines
4.6 KiB
C
148 lines
4.6 KiB
C
/*
|
|
umka_fuse: User-Mode KolibriOS developer tools, the filesystem
|
|
Copyright (C) 2018--2020 Ivan Baravy <dunkaist@gmail.com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define FUSE_USE_VERSION 31
|
|
|
|
#include <fuse.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <assert.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include "vdisk.h"
|
|
#include "kolibri.h"
|
|
#include "syscalls.h"
|
|
|
|
#define DIRENTS_TO_READ 100
|
|
|
|
static void bdfe_to_stat(bdfe_t *kf, struct stat *st) {
|
|
if (kf->attr & KF_FOLDER) {
|
|
st->st_mode = S_IFDIR | 0755;
|
|
st->st_nlink = 2;
|
|
} else {
|
|
st->st_mode = S_IFREG | 0644;
|
|
st->st_nlink = 1;
|
|
st->st_size = kf->size;
|
|
}
|
|
st->st_atime = kos_time_to_epoch(&(kf->atime));
|
|
st->st_mtime = kos_time_to_epoch(&(kf->mtime));
|
|
st->st_ctime = kos_time_to_epoch(&(kf->ctime));
|
|
}
|
|
|
|
static void *umka_init(struct fuse_conn_info *conn,
|
|
struct fuse_config *cfg) {
|
|
(void) conn;
|
|
cfg->kernel_cache = 1;
|
|
return NULL;
|
|
}
|
|
|
|
static int umka_getattr(const char *path, struct stat *stbuf,
|
|
struct fuse_file_info *fi) {
|
|
(void) fi;
|
|
int res = 0;
|
|
|
|
|
|
bdfe_t file;
|
|
f7080s5arg_t fX0 = {.sf = 5, .flags = 0, .buf = &file, .u = {.f80 = {.path_encoding = UTF8, .path = path}}};
|
|
f7080ret_t r;
|
|
umka_sys_lfn(&fX0, &r, F80);
|
|
|
|
bdfe_to_stat(&file, stbuf);
|
|
// res = -ENOENT;
|
|
return res;
|
|
}
|
|
|
|
static int umka_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
|
off_t offset, struct fuse_file_info *fi,
|
|
enum fuse_readdir_flags flags) {
|
|
(void) offset; // TODO
|
|
(void) fi;
|
|
(void) flags;
|
|
|
|
f7080s1info_t *dir = (f7080s1info_t*)malloc(sizeof(f7080s1info_t) + BDFE_LEN_UNICODE * DIRENTS_TO_READ);
|
|
f7080s1arg_t fX0 = {.sf = 1, .offset = 0, .encoding = UTF8, .size = DIRENTS_TO_READ, .buf = dir, .u = {.f80 = {.path_encoding = UTF8, .path = path}}};
|
|
f7080ret_t r;
|
|
umka_sys_lfn(&fX0, &r, F80);
|
|
bdfe_t *bdfe = dir->bdfes;
|
|
for (size_t i = 0; i < dir->cnt; i++) {
|
|
filler(buf, bdfe->name, NULL, 0, 0);
|
|
bdfe = (bdfe_t*)((uintptr_t)bdfe + BDFE_LEN_UNICODE);
|
|
}
|
|
free(dir);
|
|
return 0;
|
|
}
|
|
|
|
static int umka_open(const char *path, struct fuse_file_info *fi) {
|
|
// if (strcmp(path+1, "blah") != 0)
|
|
// return -ENOENT;
|
|
(void) path;
|
|
|
|
if ((fi->flags & O_ACCMODE) != O_RDONLY)
|
|
return -EACCES;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int umka_read(const char *path, char *buf, size_t size, off_t offset,
|
|
struct fuse_file_info *fi) {
|
|
(void) fi;
|
|
|
|
f7080s0arg_t fX0 = {.sf = 0, .offset = offset, .count = size, .buf = buf, .u = {.f80 = {.path_encoding = UTF8, .path = path}}};
|
|
f7080ret_t r;
|
|
umka_sys_lfn(&fX0, &r, F80);
|
|
return size;
|
|
}
|
|
|
|
static struct fuse_operations umka_oper = {
|
|
.init = umka_init,
|
|
.getattr = umka_getattr,
|
|
.readdir = umka_readdir,
|
|
.open = umka_open,
|
|
.read = umka_read,
|
|
};
|
|
|
|
diskfunc_t vdisk_functions = {
|
|
.strucsize = sizeof(diskfunc_t),
|
|
.close = vdisk_close,
|
|
.closemedia = NULL,
|
|
.querymedia = vdisk_querymedia,
|
|
.read = vdisk_read,
|
|
.write = vdisk_write,
|
|
.flush = NULL,
|
|
.adjust_cache_size = NULL,
|
|
};
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc != 3) {
|
|
printf("usage: umka_fuse dir img\n");
|
|
exit(1);
|
|
}
|
|
kos_init();
|
|
void *userdata = vdisk_init(argv[2], 0u);
|
|
void *vdisk = disk_add(&vdisk_functions, "hd0", userdata, 0);
|
|
disk_media_changed(vdisk, 1);
|
|
return fuse_main(argc-1, argv, &umka_oper, NULL);
|
|
}
|