#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); }