added truncate(), unlink()

This commit is contained in:
Daniele Lacamera 2019-10-22 22:40:21 +02:00
parent 3feb3b8a60
commit a1dcaf8d81
2 changed files with 128 additions and 51 deletions

View file

@ -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 <wolfssl/wolfcrypt/settings.h>
@ -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] = {

View file

@ -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