added truncate(), unlink()
This commit is contained in:
parent
3feb3b8a60
commit
a1dcaf8d81
2 changed files with 128 additions and 51 deletions
177
src/usecfs.c
177
src/usecfs.c
|
@ -13,10 +13,10 @@
|
||||||
# define BLOCKDEV_OPEN_ARGS (NULL)
|
# define BLOCKDEV_OPEN_ARGS (NULL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_BLOCKS_0 ((BLOCK_SIZE - MAX_FILENAME) / 4) - 3 /* accounts for 3 32B fields + FILENAME */
|
#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_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 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
|
#ifdef CRYPTO
|
||||||
#include <wolfssl/wolfcrypt/settings.h>
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
|
@ -32,8 +32,6 @@ uint8_t crypto_iv[CRYPTO_BLOCK_SIZE];
|
||||||
|
|
||||||
static ChaCha chacha;
|
static ChaCha chacha;
|
||||||
#define CRYPTO_KEY_SIZE 32
|
#define CRYPTO_KEY_SIZE 32
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t cache[BLOCK_SIZE];
|
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)
|
static uint32_t get_file(const char *filename)
|
||||||
{
|
{
|
||||||
struct inode *ci = (struct inode *)cache;
|
struct inode *ci = (struct inode *)cache;
|
||||||
|
@ -199,8 +195,8 @@ struct openfile {
|
||||||
uint32_t blk;
|
uint32_t blk;
|
||||||
uint32_t off;
|
uint32_t off;
|
||||||
};
|
};
|
||||||
struct openfile OpenFiles[MAX_OPEN_FILES];
|
|
||||||
|
|
||||||
|
struct openfile OpenFiles[MAX_OPEN_FILES];
|
||||||
static int get_free_fd(void)
|
static int get_free_fd(void)
|
||||||
{
|
{
|
||||||
int i, free_fd = -1;
|
int i, free_fd = -1;
|
||||||
|
@ -214,48 +210,6 @@ static int get_free_fd(void)
|
||||||
return free_fd;
|
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)
|
static uint32_t get_index_block(uint32_t inode0, uint32_t off)
|
||||||
{
|
{
|
||||||
struct inode *ci = (struct inode *)cache;
|
struct inode *ci = (struct inode *)cache;
|
||||||
|
@ -468,6 +422,128 @@ int usecfs_seek(int fd, int offset, int whence)
|
||||||
return OpenFiles[fd].off;
|
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)
|
int usecfs_close(int fd)
|
||||||
{
|
{
|
||||||
|
@ -477,7 +553,6 @@ int usecfs_close(int fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CRYPTO
|
#ifdef CRYPTO
|
||||||
#define SALT_LEN 32
|
#define SALT_LEN 32
|
||||||
const uint8_t password_salt[SALT_LEN] = {
|
const uint8_t password_salt[SALT_LEN] = {
|
||||||
|
|
|
@ -10,6 +10,8 @@ int usecfs_creat(const char *name);
|
||||||
int usecfs_read(int fd, void *data, uint32_t len);
|
int usecfs_read(int fd, void *data, uint32_t len);
|
||||||
int usecfs_write(int fd, const 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_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);
|
int usecfs_close(int fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue