From 2dd5cf430edaae01594d566c9f27d780c3ffb4ef Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Sun, 26 Apr 2015 21:43:42 -0300 Subject: Initial commit --- file.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 file.c (limited to 'file.c') diff --git a/file.c b/file.c new file mode 100644 index 0000000..71f84ac --- /dev/null +++ b/file.c @@ -0,0 +1,178 @@ +#include "file.h" +#include "block_walker.h" + +#include +#include +#include +#include + +#include "defs.h" + +uint16_t file_create(const char *disk_mem, mode_t mode) +{ + uint16_t ipos = 0; + file *f = NULL; + bwalker *bw = NULL; + + assert (disk_mem != NULL); + + bw = bwalker_create (disk_mem, 0, 0); + ipos = inode_allocate_block(disk_mem); + + f = (file *) disk_mem + INODEPOOL_OFFSET + (ipos * INODE_SIZE); + f->uid = getuid(); + f->gid = getgid(); + f->mode = mode; + f->size = 0; + f->type = I_FILE; + f->nlinks = 1; + f->ctime = NEW_TIME; + f->mtime = NEW_TIME; + f->atime = NEW_TIME; + + bwalker_destroy (bw); + + return (ipos); +} + +size_t file_read (const char *disk_mem, file *f, char *buf, + size_t size, off_t offset) +{ + size_t result = 0; + size_t len = 0; + bwalker *bw = NULL; + uint16_t *block; + uint16_t bnum; + + assert (f != NULL); + assert (buf != NULL); + + bw = bwalker_create (disk_mem, f->size, &(f->indirect)); + + while (size > 0 && (bnum = bwalker_next(bw))) + { + block = (uint16_t *) disk_mem + BLOCKPOOL_OFFSET + (bnum*BLOCK_SIZE); + if (offset >= BLOCK_SIZE){ + /* Nos movemos (no escribimos) */ + offset -= BLOCK_SIZE; + continue; + } + assert(offset < BLOCK_SIZE); + + block += offset; + + len = MIN(size,(BLOCK_SIZE - offset)); + + memcpy(buf, block, len); + result += len; + buf += len; + size -= len; + offset = 0; + if(bwalker_block_is_last(bw)){ + break; + } + + } + + bwalker_destroy (bw); + return (result); +} + +int file_truncate (const char *disk_mem, file *f, off_t size) +{ + bwalker *walker; + uint16_t offset, i, fb_size, block=0; + assert(disk_mem != NULL); + assert(f != NULL); + + + walker=bwalker_create(disk_mem, f->size, &(f->indirect)); + /*el tamaño en bytes de la cantidad de bloques que ocupa el file + * siempre es >= file_size*/ + fb_size=(bwalker_direct_length(walker)*BLOCK_SIZE); + + if(f->size < size){ + /*si el pedacito que jode...*/ + offset=size-f->size; + /*es menor que 512, y ademas el nuevo tamaño no pasa al fb_size + * no es neceasrio alocar bloques, solo se cambia el tamaño*/ + if(offsetsize=size; + bwalker_destroy(walker); + return 0; + } + for(i=0; i<(DIV_CEIL(offset, BLOCK_SIZE)); i++){ + /*aloca lo que necesita*/ + block=bwalker_allocate_block(walker); + } + /*change size*/ + f->size=size; + }else{ + /*idem, pero al verez*/ + offset=f->size-size; + f->size=size; + if(offset=fb_size){ + f->size=size; + bwalker_destroy(walker); + return 0; + } + for(i=0; i<(DIV_CEIL(offset, BLOCK_SIZE)); i++){ + bwalker_free_block(walker); + } + f->size=size; + } + bwalker_destroy(walker); + return 0; +} + +size_t file_write (const char *disk_mem, file *f, char *buf, + size_t size, off_t offset) +{ + size_t result = 0; + size_t len = BLOCK_SIZE; + bwalker *bw = NULL; + uint16_t *block = NULL; + uint16_t bnum = 0; + time_t new_time = NEW_TIME; + + assert (disk_mem != NULL); + assert (f != NULL); + + + bw = bwalker_create (disk_mem, f->size, &(f->indirect)); + + while (size > 0 && (bnum = bwalker_next(bw))) + { + assert(bnum != f->indirect); + if (offset >= BLOCK_SIZE){ + /* Nos movemos (no escribimos) */ + offset -= BLOCK_SIZE; + continue; + } + block = (uint16_t *) disk_mem + BLOCKPOOL_OFFSET + (bnum*BLOCK_SIZE); + + assert(offset < BLOCK_SIZE); + block += offset; + + len = MIN(size,(BLOCK_SIZE - offset)); + + memcpy(block, buf, len); + + result += len; + buf += len; + size -= len; + offset = 0; + + if(bwalker_direct_length(bw)<=1){ + break; + } + + } + + f->atime = new_time; + f->mtime = new_time; + + bwalker_destroy (bw); + + return (result); +} -- cgit v1.2.3-70-g09d2