aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2022-01-01 18:20:11 +0100
committerMarvin Borner2022-01-01 18:20:11 +0100
commit6a1f4e4d394b3c5ff7a7d1c58a8775a645275e4a (patch)
treeaecf46ad188b047301578f5707a171d7c63b2a8e
parent0d665f1bf585930b1b6c45f53fe23f6fa07b398f (diff)
Implementing..
-rw-r--r--inc/spec.h12
-rw-r--r--makefile4
-rw-r--r--src/fuse.c120
3 files changed, 109 insertions, 27 deletions
diff --git a/inc/spec.h b/inc/spec.h
index 7991866..b13534c 100644
--- a/inc/spec.h
+++ b/inc/spec.h
@@ -17,7 +17,7 @@
#define MARFS_ENTRY_SIZE 1024
#define MARFS_DIR_ENTRY 1
-#define MARFS_FILE_ENTRY 2;
+#define MARFS_FILE_ENTRY 2
#define MARFS_DIR_ENTRY_COUNT (MARFS_ENTRY_SIZE / sizeof(struct marfs_dir_entry_data))
@@ -35,24 +35,28 @@ struct marfs_header {
struct marfs_entry_header {
u32 type;
+ u32 id;
u32 prev, next; // MARFS_END if end
} PACKED;
struct marfs_dir_entry_data {
- char name[MARFS_NAME_LENGTH];
+ char name[MARFS_NAME_LENGTH + 1];
+ u32 length;
struct marfs_pointer pointer;
} PACKED;
struct marfs_dir_entry {
struct marfs_entry_header header;
+ u32 count;
struct marfs_dir_entry_data entries[MARFS_DIR_ENTRY_COUNT];
- u8 padding[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header) -
+ u8 padding[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header) - sizeof(u32) -
(MARFS_DIR_ENTRY_COUNT * sizeof(struct marfs_dir_entry_data))];
} PACKED;
struct marfs_file_entry {
struct marfs_entry_header header;
- u8 data[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header)];
+ u32 size;
+ u8 data[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header) - sizeof(u32)];
} PACKED;
#endif
diff --git a/makefile b/makefile
index 16094e0..3793b61 100644
--- a/makefile
+++ b/makefile
@@ -47,13 +47,13 @@ $(MNT):
mount: disk $(MNT)
@DEV=$$(losetup -a | grep $(BUILD)/disk.img | grep -m 1 -o '/dev/loop[[:digit:]]*') && \
PART="p1" && \
- ($(BUILD)/marfs_fuse "$$DEV$$PART" -f $(MNT) &) && \
+ ($(SU) $(BUILD)/marfs_fuse "$$DEV$$PART" -f $(MNT) &) && \
echo "Mounted $$DEV$$PART"
umount:
@DEV=$$(losetup -a | grep $(BUILD)/disk.img | grep -m 1 -o '/dev/loop[[:digit:]]*') && \
$(SU) losetup -d "$$DEV" && \
- umount $(MNT) && \
+ $(SU) umount $(MNT) && \
echo "Unmounted $$DEV$$PART" || \
echo "No disk to unmount"
diff --git a/src/fuse.c b/src/fuse.c
index a3c946d..9cfd2bf 100644
--- a/src/fuse.c
+++ b/src/fuse.c
@@ -7,6 +7,7 @@
#include <spec.h>
+#include <assert.h>
#include <errno.h>
#include <fuse.h>
#include <limits.h>
@@ -16,9 +17,11 @@
#include <sys/time.h>
#include <time.h>
-static char *image = 0;
+static FILE *image = NULL;
-static void marfs_debug(const char *fmt, ...)
+static struct marfs_header header = { 0 };
+
+static void debug(const char *fmt, ...)
{
printf("\t>>> ");
va_list args;
@@ -28,9 +31,56 @@ static void marfs_debug(const char *fmt, ...)
printf("\n");
}
+static void sector(u32 index, u32 size, void *buf)
+{
+ fseek(image, index * header.entry_size, SEEK_SET);
+ assert(fread(buf, 1, size, image) == size);
+}
+
+// first -> start = header.main.head
+static u8 read_entry_header(const char *path, u32 start, struct marfs_entry_header *entry_header)
+{
+ while (*path && *path == '/')
+ path++;
+
+ struct marfs_entry_header h;
+ sector(start, sizeof(h), &h);
+
+ if (h.type == MARFS_DIR_ENTRY) {
+ struct marfs_dir_entry entry;
+ sector(start, sizeof(entry), &entry);
+ assert(entry.count <= MARFS_DIR_ENTRY_COUNT);
+ for (u32 i = 0; i < entry.count; i++) {
+ struct marfs_dir_entry_data *data = &entry.entries[i];
+ if (!strncmp(path, data->name, data->length)) {
+ if (path[data->length] == '/') {
+ return read_entry_header(path, data->pointer.head,
+ entry_header);
+ }
+ if (!path[data->length]) {
+ *entry_header = h;
+ return 1;
+ }
+ }
+ }
+
+ if (entry.header.next != MARFS_END)
+ return read_entry_header(path, entry.header.next, entry_header);
+ } else if (h.type == MARFS_FILE_ENTRY) {
+ *entry_header = h;
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Fuse operations
+ */
+
static void *marfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
{
- marfs_debug("init()");
+ debug("init()");
UNUSED(conn);
cfg->kernel_cache = 1;
return NULL;
@@ -38,26 +88,28 @@ static void *marfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
static void marfs_destroy(void *data)
{
- marfs_debug("destroy()");
+ debug("destroy()");
+ UNUSED(data);
+
if (image)
- free(image);
+ fclose(image);
}
static int marfs_open(const char *file_path, struct fuse_file_info *file_info)
{
- marfs_debug("open() on %s", file_path);
+ debug("open() on %s", file_path);
return 0;
}
static int marfs_opendir(const char *dir_path, struct fuse_file_info *file_info)
{
- marfs_debug("opendir() on %s", dir_path);
+ debug("opendir() on %s", dir_path);
return 0;
}
static int marfs_getattr(const char *path, struct stat *stat, struct fuse_file_info *info)
{
- marfs_debug("getattr() on %s", path);
+ debug("getattr() on %s", path);
UNUSED(info);
memset(stat, 0, sizeof(*stat));
@@ -76,7 +128,7 @@ static int marfs_getattr(const char *path, struct stat *stat, struct fuse_file_i
static int marfs_readdir(const char *path, void *buf, fuse_fill_dir_t fill, off_t offset,
struct fuse_file_info *file_info, enum fuse_readdir_flags flags)
{
- marfs_debug("readdir() on %s and offset %lu", path, offset);
+ debug("readdir() on %s and offset %lu", path, offset);
UNUSED(offset);
UNUSED(file_info);
@@ -93,70 +145,70 @@ static int marfs_readdir(const char *path, void *buf, fuse_fill_dir_t fill, off_
static int marfs_release(const char *path, struct fuse_file_info *file_info)
{
- marfs_debug("release() on %s", path);
+ debug("release() on %s", path);
return 0;
}
static int marfs_releasedir(const char *path, struct fuse_file_info *file_info)
{
- marfs_debug("releasedir() on %s", path);
+ debug("releasedir() on %s", path);
return 0;
}
static int marfs_read(const char *path, char *buf, size_t to_read, off_t offset,
struct fuse_file_info *file_info)
{
- marfs_debug("read() on %s, %lu", path, to_read);
+ debug("read() on %s, %lu", path, to_read);
return to_read;
}
static int marfs_write(const char *path, const char *buf, size_t to_write, off_t offset,
struct fuse_file_info *file_info)
{
- marfs_debug("write() on %s", path);
+ debug("write() on %s", path);
return to_write;
}
static int marfs_create(const char *path, mode_t mode, struct fuse_file_info *file_info)
{
- marfs_debug("create() on %s", path);
+ debug("create() on %s", path);
return 0;
}
static int marfs_mkdir(const char *path, mode_t mode)
{
- marfs_debug("mkdir() on %s", path);
+ debug("mkdir() on %s", path);
return 0;
}
static int marfs_unlink(const char *path)
{
- marfs_debug("unlink() on %s", path);
+ debug("unlink() on %s", path);
return 0;
}
static int marfs_rmdir(const char *path)
{
- marfs_debug("rmdir() on %s", path);
+ debug("rmdir() on %s", path);
return 0;
}
static int marfs_utimens(const char *path, const struct timespec tv[2],
struct fuse_file_info *file_info)
{
- marfs_debug("utimens() on %s", path);
+ debug("utimens() on %s", path);
return 0;
}
static int marfs_truncate(const char *path, off_t size, struct fuse_file_info *file_info)
{
- marfs_debug("truncate() on %s, size %lu", path, size);
+ debug("truncate() on %s, size %lu", path, size);
return 0;
}
static int marfs_rename(const char *path, const char *new, unsigned int flags)
{
- marfs_debug("rename() on %s -> %s", path, new);
+ debug("rename() on %s -> %s", path, new);
return 0;
}
@@ -188,10 +240,36 @@ int main(int argc, char **argv)
}
// I don't think that's how fuse is supposed to work but idc
- image = strdup(argv[1]);
+ char *path = argv[1];
argv++;
argc--;
+ image = fopen(path, "r");
+ if (!image) {
+ fprintf(stderr, "error: invalid image path '%s' specified: %s\n", path,
+ strerror(errno));
+ exit(1);
+ }
+
+ int head_read = fread(&header, 1, sizeof(header), image);
+ if (head_read != sizeof(header)) {
+ fprintf(stderr, "error: could not read full header: %d\n", head_read);
+ fclose(image);
+ exit(1);
+ }
+
+ if (strcmp(header.magic, MARFS_MAGIC) != 0) {
+ fprintf(stderr, "error: invalid header magic: %s\n", header.magic);
+ fclose(image);
+ exit(1);
+ }
+
+ if (header.version != MARFS_SPEC_VERSION) {
+ fprintf(stderr, "error: non-supported spec-version %d\n", header.version);
+ fclose(image);
+ exit(1);
+ }
+
fuse_main(argc, argv, &operations, NULL);
return 0;