diff --git a/src/usecfs.c b/src/usecfs.c index 16e06dc..cf9b67a 100644 --- a/src/usecfs.c +++ b/src/usecfs.c @@ -13,10 +13,10 @@ # define BLOCKDEV_OPEN_ARGS (NULL) #endif -#define MAX_BLOCKS_0 ((BLOCK_SIZE - MAX_FILENAME) / 4) - 3 /* accounts for 3 32B fields + FILENAME */ -#define MAX_BLOCKS_N ((BLOCK_SIZE - MAX_FILENAME) / 4) - 1 /* overhead is only 'extra' fields */ +#define MAX_BLOCKS_0 ((BLOCK_SIZE - MAX_FILENAME) / 4) - 3 /* accounts for 3 32bit fields + FILENAME */ +#define MAX_BLOCKS_N ((BLOCK_SIZE - MAX_FILENAME) / 4) - 1 /* overhead is only 'extra' fields */ #define MAX_INLINE_SIZE ((MAX_BLOCKS_0 - 1) * 4) /* Max data size for self-contained block */ -#define INLINE_PAYLOAD(x) ((uint8_t *)(&x->blk[1])) /* Macro to access INLINE paylaod */ +#define INLINE_PAYLOAD(x) ((uint8_t *)(&x->blk[1])) /* Macro to access INLINE paylaod */ #ifdef CRYPTO #include @@ -32,8 +32,6 @@ uint8_t crypto_iv[CRYPTO_BLOCK_SIZE]; static ChaCha chacha; #define CRYPTO_KEY_SIZE 32 - - #endif static uint8_t cache[BLOCK_SIZE]; @@ -117,8 +115,6 @@ static void cache_load(uint32_t blk) } } - - static uint32_t get_file(const char *filename) { struct inode *ci = (struct inode *)cache; @@ -199,8 +195,8 @@ struct openfile { uint32_t blk; uint32_t off; }; -struct openfile OpenFiles[MAX_OPEN_FILES]; +struct openfile OpenFiles[MAX_OPEN_FILES]; static int get_free_fd(void) { int i, free_fd = -1; @@ -214,48 +210,6 @@ static int get_free_fd(void) return free_fd; } -int usecfs_open(const char *name) -{ - int free_fd; - free_fd = get_free_fd(); - if (free_fd < 0) - return -1; - OpenFiles[free_fd].blk = get_file(name); - if (OpenFiles[free_fd].blk == NO_BLOCK) - return -1; - OpenFiles[free_fd].off = 0; - return free_fd; -} - -int usecfs_creat(const char *name) -{ - int free_fd; - int i; - uint32_t newnode; - struct inode *ci = (struct inode *)cache; - free_fd = get_free_fd(); - if (free_fd < 0) - return -1; - if (get_file(name) != NO_BLOCK) - return -1; - newnode = new_inode(); - if (newnode == NO_BLOCK) - return -1; - OpenFiles[free_fd].blk = newnode; - - /* Initialize inode (already in cache from new_inode()) */ - ci->size = 0; /* newly created file is zero bytes long */ - memset(ci->filename, 0, MAX_FILENAME); - for (i = 0; (i < strlen(name)) && (i < MAX_FILENAME - 1); i++) - ci->filename[i] = name[i]; - ci->blk[0] = newnode; /* self-reference, start as INLINE */ - for (i = 1; i < MAX_BLOCKS_0; i++) - ci->blk[i] = NO_BLOCK; - OpenFiles[free_fd].off = 0; - cache_commit(); - return free_fd; -} - static uint32_t get_index_block(uint32_t inode0, uint32_t off) { struct inode *ci = (struct inode *)cache; @@ -468,6 +422,128 @@ int usecfs_seek(int fd, int offset, int whence) return OpenFiles[fd].off; } +int usecfs_open(const char *name) +{ + int free_fd; + free_fd = get_free_fd(); + if (free_fd < 0) + return -1; + OpenFiles[free_fd].blk = get_file(name); + if (OpenFiles[free_fd].blk == NO_BLOCK) + return -1; + OpenFiles[free_fd].off = 0; + return free_fd; +} + +int usecfs_creat(const char *name) +{ + int free_fd; + int i; + uint32_t newnode; + struct inode *ci = (struct inode *)cache; + free_fd = get_free_fd(); + if (free_fd < 0) + return -1; + if (get_file(name) != NO_BLOCK) + return -1; + newnode = new_inode(); + if (newnode == NO_BLOCK) + return -1; + OpenFiles[free_fd].blk = newnode; + + /* Initialize inode (already in cache from new_inode()) */ + ci->size = 0; /* newly created file is zero bytes long */ + memset(ci->filename, 0, MAX_FILENAME); + for (i = 0; (i < strlen(name)) && (i < MAX_FILENAME - 1); i++) + ci->filename[i] = name[i]; + ci->blk[0] = newnode; /* self-reference, start as INLINE */ + for (i = 1; i < MAX_BLOCKS_0; i++) + ci->blk[i] = NO_BLOCK; + OpenFiles[free_fd].off = 0; + cache_commit(); + return free_fd; +} + +int usecfs_truncate(int fd, uint32_t newsize) +{ + struct inode *ci = (struct inode *)cache; + struct extra *ce = (struct extra *)cache; + uint32_t idx, new_idx; + uint32_t last_block_idx; + uint32_t idx_block, new_idx_block; + uint32_t node0 = OpenFiles[fd].blk; + uint32_t idx_off; + uint32_t i; + if (node0 == NO_BLOCK) + return -1; + cache_load(OpenFiles[fd].blk); + if (ci->size <= newsize) + return -1; + idx = ci->size / BLOCK_SIZE; + new_idx = newsize / BLOCK_SIZE; + if (ci->size <= (BLOCK_SIZE * MAX_BLOCKS_0) || /* File is inlined, or */ + (idx == new_idx) ) /* number of blocks is unchanged? */ + { + ci->size = newsize; + return 0; + } + if ((ci->size > MAX_INLINE_SIZE) && (newsize <= MAX_INLINE_SIZE)) + { + /* Special case: file was big, now it's inlined. */ + cache_load(ci->blk[0]); + memcpy(inline_buffer_copy, cache, newsize); + cache_load(node0); + memcpy(INLINE_PAYLOAD(ci), inline_buffer_copy, newsize); + ci->blk[0] = node0; /* establish self-reference */ + for (i = 1; i < MAX_BLOCKS_0; i++) + ci->blk[i] = NO_BLOCK; + ci->size = newsize; + return 0; + } + idx_block = get_index_block(node0, ci->size); + new_idx_block = get_index_block(node0, newsize); + cache_load(new_idx_block); + if (idx_block != new_idx_block) + ci->extra = NO_BLOCK; + if (idx_off <= MAX_BLOCKS_0) { + idx_off = new_idx_block; + for (i = idx_off; i < MAX_BLOCKS_N; i++) + ce->blk[i] = NO_BLOCK; + } else { + idx_off = (new_idx_block - MAX_BLOCKS_0) % MAX_BLOCKS_N; + while (idx_off > MAX_BLOCKS_N) + idx_off -= MAX_BLOCKS_N; + for (i = idx_off; i < MAX_BLOCKS_N; i++) + ce->blk[i] = NO_BLOCK; + } + ci->size = newsize; + return 0; +} + +int usecfs_unlink(const char *filename) +{ + struct inode *ci = (struct inode *)cache; + uint32_t blk = 1; + uint32_t blk_prev = 0; + uint32_t blk_next; + cache_load(blk); + while (1) { + if (strncmp(filename, ci->filename, MAX_FILENAME - 1) == 0) + { + blk_next = ci->nextfile; + cache_load(blk_prev); + ci->nextfile = blk_next; + return 0; + } + if (ci->nextfile != NO_BLOCK) { + blk_prev = blk; + blk = ci->nextfile; + cache_load(blk); + } else + return -1; + } + return -1; /* Never reached */ +} int usecfs_close(int fd) { @@ -477,7 +553,6 @@ int usecfs_close(int fd) } } - #ifdef CRYPTO #define SALT_LEN 32 const uint8_t password_salt[SALT_LEN] = { diff --git a/src/usecfs.h b/src/usecfs.h index cfadbde..c149031 100644 --- a/src/usecfs.h +++ b/src/usecfs.h @@ -10,6 +10,8 @@ int usecfs_creat(const char *name); int usecfs_read(int fd, void *data, uint32_t len); int usecfs_write(int fd, const void *data, uint32_t len); int usecfs_seek(int fd, int offset, int whence); +int usecfs_truncate(int fd, uint32_t newsize); +int usecfs_unlink(const char *filename); int usecfs_close(int fd); #endif