diff options
author | Matias Linares <matiaslina@opmbx.org> | 2015-04-26 21:43:42 -0300 |
---|---|---|
committer | Matias Linares <matiaslina@opmbx.org> | 2015-04-26 21:43:42 -0300 |
commit | 2dd5cf430edaae01594d566c9f27d780c3ffb4ef (patch) | |
tree | 13111bc82a73e951d5d7c07865a206c025d15529 /file.c | |
download | medianinfs-2dd5cf430edaae01594d566c9f27d780c3ffb4ef.tar.gz |
Initial commit
Diffstat (limited to 'file.c')
-rw-r--r-- | file.c | 178 |
1 files changed, 178 insertions, 0 deletions
@@ -0,0 +1,178 @@ +#include "file.h" +#include "block_walker.h" + +#include <assert.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +#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(offset<BLOCK_SIZE&&size<=fb_size){ + f->size=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<BLOCK_SIZE&&size>=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); +} |