void sfs_write(int sfs_handle, char *fn) { int i, cur_read_i, to_read, cur_read, total_size, block_i, free_i; sfs_file_entry_t fe; if ((i = sfs_lookup(sfs_handle, fn, &fe)) == -1) { printf("File %s doesn't exist\n", fn); return; } cur_read_i = 0; to_read = sb.block_size; total_size = 0; block_i = 0; while ((cur_read = read(0, block + cur_read_i, to_read)) > 0) { if (cur_read == to_read) { /* Write this block */ if (block_i == SIMULA_FS_DATA_BLOCK_CNT) break; /* File size limit */ if ((free_i = get_data_block(sfs_handle)) == -1) break; /* File system full */ lseek(sfs_handle, free_i * sb.block_size, SEEK_SET); write(sfs_handle, block, sb.block_size); fe.blocks[block_i] = free_i; block_i++; total_size += sb.block_size; /* Reset various variables */ cur_read_i = 0; to_read = sb.block_size; } else { cur_read_i += cur_read; to_read -= cur_read; } } if ((cur_read <= 0) && (cur_read_i)) { /* Write this partial block */ if ((block_i != SIMULA_FS_DATA_BLOCK_CNT) && ((fe.blocks[block_i] = get_data_block(sfs_handle)) != -1)) { lseek(sfs_handle, fe.blocks[block_i] * sb.block_size, SEEK_SET); write(sfs_handle, block, cur_read_i); total_size += cur_read_i; } } fe.size = total_size; fe.timestamp = time(NULL); lseek(sfs_handle, sb.entry_table_block_start * sb.block_size + i * sb.entry_size, SEEK_SET); write(sfs_handle, &fe, sizeof(sfs_file_entry_t)); }
int ext2_truncate(inode_t *inode, off_t off) { __u32 size = off; ext2_fs_instance_t *instance = (ext2_fs_instance_t*)inode->i_instance; struct ext2_inode *einode = read_inode(instance, inode->i_ino); if (einode) { __u32 n_blk; if (size > 0) { n_blk = (size - 1) / (1024 << instance->superblock.s_log_block_size) + 1; } else { n_blk = 1; } __u32 addr = get_data_block (instance,einode, n_blk);; if (addr) { while (addr) { if (off <= 0) { free_block(instance, addr / (1024 << instance->superblock.s_log_block_size)); } else { off -= 1024 << instance->superblock.s_log_block_size; } n_blk++; addr = get_data_block (instance,einode, n_blk); } } else { while (off > 0) { set_block_inode_data(instance, einode, n_blk, alloc_block(instance)); n_blk++; off -= 1024 << instance->superblock.s_log_block_size; } } einode->i_size = size; write_inode(instance, inode->i_ino, einode); ext2inode_2_inode(inode, inode->i_instance, inode->i_ino, einode); return 0; } return -ENOENT; }
int has_file(struct inode *cur_inode, char *cur) { //this assumes cur_inode is dir and looks for something named cur int i,k; struct directory *cur_directory_block = NULL;// = malloc(sizeof(struct directory)); struct datablock *datablock = NULL; if(cur_inode == NULL) { DEBUG1 && printf("cur_inode is null \n"); return -1; } if(cur_inode->is_dir == 0) { return -2; //cur_inode not dir } for(i=0 ; i < cur_inode->num_blocks; i++) { get_data_block(&datablock, cur_inode, i); cur_directory_block = (struct directory *)datablock; if( ! (cur_directory_block) ) { DEBUG2 && printf("error reading dir block\n"); return -2; } for(k=0 ; k < 32 ; k++) { int cur_inum = cur_directory_block->entries[k].inode_number; char *cur_iname = cur_directory_block->entries[k].filename; //printf("has_file: cur_inum %d\n",cur_inum); //printf("has_file: cur_iname %s %d\n", cur_iname, strlen(cur_iname)); //printf("has_file: cur %s %d\n", cur, strlen(cur)); if(cur_inum < 0) { return -2;//invalid inode } if(strcmp(cur, cur_iname) == 0) { //printf("has_file: match\n"); return cur_inum; } } } return -1; //not found }
void *realloc(void *ptr, size_t size) { t_block *block; if (ptr == NULL) return (NULL); block = get_data_block(ptr); if (size == 0) { free(ptr); return (NULL); } else if (size == block->size) return (ptr); else if (size < block->size) return (realloc_smaller(ptr, block, size)); else return (realloc_larger(ptr, block, size)); }
int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len) { struct buffer_head map_bh; sector_t start_blk, last_blk; loff_t isize = i_size_read(inode); u64 logical = 0, phys = 0, size = 0; u32 flags = 0; bool past_eof = false, whole_file = false; int ret = 0; ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); if (ret) return ret; mutex_lock(&inode->i_mutex); if (len >= isize) { whole_file = true; len = isize; } if (logical_to_blk(inode, len) == 0) len = blk_to_logical(inode, 1); start_blk = logical_to_blk(inode, start); last_blk = logical_to_blk(inode, start + len - 1); next: memset(&map_bh, 0, sizeof(struct buffer_head)); map_bh.b_size = len; ret = get_data_block(inode, start_blk, &map_bh, 0, F2FS_GET_BLOCK_FIEMAP); if (ret) goto out; /* HOLE */ if (!buffer_mapped(&map_bh)) { start_blk++; if (!past_eof && blk_to_logical(inode, start_blk) >= isize) past_eof = 1; if (past_eof && size) { flags |= FIEMAP_EXTENT_LAST; ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); } else if (size) { ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); size = 0; } /* if we have holes up to/past EOF then we're done */ if (start_blk > last_blk || past_eof || ret) goto out; } else { if (start_blk > last_blk && !whole_file) { ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); goto out; } /* * if size != 0 then we know we already have an extent * to add, so add it. */ if (size) { ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); if (ret) goto out; } logical = blk_to_logical(inode, start_blk); phys = blk_to_logical(inode, map_bh.b_blocknr); size = map_bh.b_size; flags = 0; if (buffer_unwritten(&map_bh)) flags = FIEMAP_EXTENT_UNWRITTEN; start_blk += logical_to_blk(inode, size); /* * If we are past the EOF, then we need to make sure as * soon as we find a hole that the last extent we found * is marked with FIEMAP_EXTENT_LAST */ if (!past_eof && logical + size >= isize) past_eof = true; } cond_resched(); if (fatal_signal_pending(current)) ret = -EINTR; else goto next; out: if (ret == 1) ret = 0; mutex_unlock(&inode->i_mutex); return ret; }
int ext2_read(open_file_descriptor * ofd, void * buf, size_t size) { if ((ofd->flags & O_ACCMODE) == O_WRONLY) { return 0; } int inode = ofd->inode->i_ino; if (inode >= 0) { ext2_fs_instance_t *instance = (ext2_fs_instance_t*) ofd->fs_instance; off_t offset = ofd->current_octet; int count = 0; struct ext2_inode *einode = read_inode(instance, inode); if (offset >= einode->i_size) { return 0; } if (size + offset > einode->i_size) { size = einode->i_size - offset; } int n_blk = 0; while (offset >= (unsigned int)(1024 << instance->superblock.s_log_block_size)) { n_blk++; offset -= (1024 << instance->superblock.s_log_block_size); } //int n_blk = offset / (1024 << instance->superblock.s_log_block_size); //offset %= (1024 << instance->superblock.s_log_block_size); // while (size > 0) { __u32 addr = get_data_block (instance,einode, n_blk); if (addr == 0) break; n_blk++; size_t size2 = (1024 << instance->superblock.s_log_block_size) - offset; if (size2 > size) { size2 = size; } instance->read_data(instance->super.device, ((char*)buf) + count, size2, addr + offset); size -= size2; count += size2; offset = 0; } ofd->current_octet += count; return count; } else { return inode; } }
int ext2_write(open_file_descriptor * ofd, const void *buf, size_t size) { if ((ofd->flags & O_ACCMODE) == O_RDONLY) { return 0; } int inode = ofd->inode->i_ino; if (inode >= 0) { ext2_fs_instance_t *instance = (ext2_fs_instance_t*) ofd->fs_instance; struct ext2_inode *einode = read_inode(instance, inode); if (einode != NULL) { unsigned int offset; if (ofd->flags & O_APPEND) { offset = einode->i_size; } else { offset = ofd->current_octet; } int count = 0; __u32 n_blk = 0; int off = offset; while (off >= (1024 << instance->superblock.s_log_block_size)) { if (get_data_block (instance,einode, n_blk) == 0) { int addr = alloc_block(instance); set_block_inode_data(instance, einode, n_blk, addr); } off -= 1024 << instance->superblock.s_log_block_size; n_blk++; } while (size > 0) { __u32 addr = get_data_block (instance,einode, n_blk); if (addr == 0) { addr = alloc_block(instance); set_block_inode_data(instance, einode, n_blk, addr); addr *= (1024 << instance->superblock.s_log_block_size); } addr += off; size_t size2 = (1024 << instance->superblock.s_log_block_size) - off; off = 0; if (size2 > size) { size2 = size; } instance->write_data(instance->super.device, ((char*)buf) + count, size2, addr); size -= size2; count += size2; n_blk++; } einode->i_size = max(einode->i_size, offset + count); // struct timeval tv; // gettimeofday(&tv, NULL); // einode.i_mtime = tv.tv_sec; write_inode(instance, inode, einode); return count; } else { return -ENOENT; } return size; } else { return inode; } }
static int gif_get_extension(GifContext *context) { int retval; int empty_block = false; if (context->extension_flag) { if (!context->extension_label && !gif_read(context, &context->extension_label , 1)) return -1; switch (context->extension_label) { case 0xf9: /* Graphic Control Extension */ retval = get_data_block(context, (euchar *)context->block_buf, NULL); if (retval != 0) return retval; if (context->frame == NULL) { context->gif89.disposal = (context->block_buf[0] >> 2) & 0x7; context->gif89.input_flag = (context->block_buf[0] >> 1) & 0x1; context->gif89.delay_time = LM_to_uint(context->block_buf[1], context->block_buf[2]); if ((context->block_buf[0] & 0x1) != 0) context->gif89.transparent = context->block_buf[3]; else context->gif89.transparent = -1; } /* Now we've successfully loaded this one, we continue on our way */ context->block_count = 0; context->extension_flag = false; break; case 0xff: /* application extension */ if (!context->in_loop_extension) { retval = get_data_block(context, (euchar *)context->block_buf, NULL); if (retval != 0) return retval; if (!e_strncmp(context->block_buf, _("NETSCAPE2.0"), 11) || !e_strncmp(context->block_buf, _("ANIMEXTS1.0"), 11)) { context->in_loop_extension = true; } context->block_count = 0; } if (context->in_loop_extension) { do { retval = get_data_block(context, (euchar *)context->block_buf, &empty_block); if (retval != 0) return retval; if (context->is_anim && context->block_buf[0] == 0x01) { context->anim->loop = context->block_buf[1] + (context->block_buf[2] << 8); if (context->anim->loop != 0) context->anim->loop++; } context->block_count = 0; } while (!empty_block); context->in_loop_extension = false; context->extension_flag = false; goto step; } break; default: break; } }
int add_dir_to_inode(int inode_num, char *n_dir, int n_inode_num) { struct inode_block *ib = malloc(sizeof(struct inode_block)); struct inode *inode = NULL; struct directory *nd = malloc(sizeof(struct directory)); struct directory *cur_dir = NULL; struct datablock *datablock = NULL; int data_block_num; int i; int new_dir_block_num; for(i=0 ; i < 32 ; i++) { strcpy(nd->entries[i].filename,""); nd->entries[i].inode_number = 0; } get_inode(&ib, &inode, inode_num); if(inode->num_blocks == 0) { new_dir_block_num = add_data_block(inode_num); if(new_dir_block_num < 0) { return ERR_DISK_FULL; } strcpy(nd->entries[0].filename, n_dir); nd->entries[0].inode_number = n_inode_num; if(!write_block(file, nd, new_dir_block_num)) { DEBUG2 && printf("error reading datablock\n"); return ERR_INTERNAL; } return SUCCESS; } if(inode->num_blocks > 0) { //int dir_block_num = inode->num_blocks - 1; data_block_num = get_data_block(&datablock, inode, inode->num_blocks - 1); cur_dir = (struct directory *)datablock; for(i=0; i < 32 ; i++) { if(cur_dir->entries[i].inode_number <= 0) { cur_dir->entries[i].inode_number = n_inode_num; strcpy(cur_dir->entries[i].filename, n_dir); if( !write_block(file, cur_dir, data_block_num)) { DEBUG2 && printf("error reading datablock\n"); return ERR_INTERNAL; } return SUCCESS; } } //we got here, we need another data block new_dir_block_num = add_data_block(inode_num); if(new_dir_block_num < 0) { DEBUG2 && printf("error no more free data blocks\n"); return ERR_DISK_FULL; } strcpy(nd->entries[0].filename, n_dir); nd->entries[0].inode_number = n_inode_num; if(!write_block(file, nd, new_dir_block_num)) { DEBUG2 && printf("error writing datablock\n"); return ERR_INTERNAL; } return SUCCESS; } return SUCCESS; }
int delete_file(char *path) { char *lpath = malloc(sizeof(char)*strlen(path)+1); char *orig_path = malloc(sizeof(char)*strlen(path)+1); char *last; char *ptr; char null_array[12]; int wd, free_inode_num, found, s; int inode_num; struct inode_block *ib = NULL; struct inode *inode = NULL; struct inode_block *doomed_ib = NULL; struct inode *doomed_inode = NULL; struct directory *dir = NULL; struct datablock *datablock = NULL; struct directory *ldir = NULL; struct datablock *ldatablock = NULL; int doomed_inode_num; int i, j, k, foundit = 0; int cur_db_num, last_db_num; /* for(i=0;i<12;i++){ null_array[i] = '\0'; } */ strcpy(lpath, path); strcpy(orig_path, path); if(strlen(lpath) == 1) { if(lpath[0] == '/') { return ERR_FILE_EXISTS; //update this to correct val } else { return ERR_INVALID_PATH; } } ptr = strrchr(lpath, '/'); if(ptr == lpath+strlen(lpath)-1) { *ptr = '\0'; ptr = strrchr(lpath, '/'); } ptr++; last = malloc(sizeof(char)*strlen(ptr)+1); strcpy(last, ptr); *ptr = '\0'; wd = path_to_inode(lpath); DEBUG1 && printf("lpath = %s last = %s \n", lpath, last); //funct to remove all data blocks if((doomed_inode_num = path_to_inode(orig_path)) < 0) { DEBUG1 && printf("cannot delete, does not exist\n"); return ERR_FILE_NOT_FOUND; } if((get_inode(&doomed_ib, &doomed_inode, doomed_inode_num)) < 0) { DEBUG2 && printf("error get_inode\n"); return -1; } if(doomed_inode->is_dir != 0 && doomed_inode->num_blocks > 0) { DEBUG1 && printf("cannot delete a none empty directory"); return ERR_INVALID_PATH;//should be a different error } erase_inode(doomed_inode_num); //funct to remove from dir if((inode_num = path_to_inode(lpath)) < 0) { DEBUG2 && printf("error path_to_inode\n"); return -1; } if((get_inode(&ib, &inode, inode_num)) < 0) { DEBUG2 && printf("error get_inode\n"); return -1; } for(i=0; i<inode->num_blocks; i++) { cur_db_num = get_data_block(&datablock, inode, i); dir = (struct directory *)datablock; for(j=0; j<32; j++) { if(strcmp(last,dir->entries[j].filename) == 0 ) { DEBUG1 && printf("got it!\n"); //strcpy(dir->entries[j].filename, ""); //dir->entries[j].inode_number = 0; foundit = 1; //write_block(file, dir, cur_db_num); break; } } if(foundit) { break; } } if(!foundit) { return -1; } last_db_num = get_data_block(&ldatablock, inode, inode->num_blocks-1); ldir = (struct directory *)ldatablock; if(last_db_num == cur_db_num) { for(k=0; k<32; k++) { if(dir->entries[k].inode_number == 0) { //k++; break; } } // k-1 is the one we want, even if we went all the way to the end. strcpy(dir->entries[j].filename, dir->entries[k-1].filename); dir->entries[j].inode_number = dir->entries[k-1].inode_number; for(i=0; i<12; i++) { dir->entries[k-1].filename[i] = '\0'; } dir->entries[k-1].inode_number = 0; write_block(file, dir, cur_db_num); if(k-1 == 0) { //add last_db_num to free blocks if(make_free_datablock(last_db_num)) { DEBUG2 && printf("couldnt free datablock\n"); } //subtract a datablock from inode->num_blocks //WE NEED TO ADD STUFF TO SUBTRACT INDIRECTION BLOCKS inode->num_blocks--; DEBUG1 && printf("inode->num_blocks = %d \n", inode->num_blocks); //write the inode back put_inode_block(ib, inode_num); trim_indirection_blocks(inode_num); } } else { for(k=0; k<32; k++) { if(ldir->entries[k].inode_number == 0) { //k++; break; } } // k-1 is the one we want, even if we went all the way to the end. strcpy(dir->entries[j].filename, ldir->entries[k-1].filename); dir->entries[j].inode_number = ldir->entries[k-1].inode_number; for(i=0; i<12; i++) { ldir->entries[k-1].filename[i] = '\0'; } ldir->entries[k-1].inode_number = 0; write_block(file, dir, cur_db_num); write_block(file, ldir, last_db_num); if(k-1 == 0) { //add last_db_num to free blocks if(make_free_datablock(last_db_num)) { DEBUG1 && printf("couldnt free datablock\n"); } //subtract a datablock from inode->num_blocks //WE NEED TO ADD STUFF TO SUBTRACT INDIRECTION BLOCKS inode->num_blocks--; DEBUG1 && printf("inode->num_blocks = %d \n", inode->num_blocks); //write the inode back put_inode_block(ib, inode_num); trim_indirection_blocks(inode_num); } } return SUCCESS; }
int erase_inode(int inode_num) { struct inode_block *ib = NULL; struct inode *inode = NULL; struct directory *dir = NULL; struct datablock *datablock = NULL; struct indirection_block *idb = malloc(sizeof(struct indirection_block)); struct indirection_block *idb2 = malloc(sizeof(struct indirection_block)); struct superblock *sb = malloc(sizeof(struct superblock)); int cur_db_num, i; if((get_inode(&ib, &inode, inode_num)) < 0) { DEBUG2 && printf("error get_inode\n"); return -1; } while(inode->num_blocks > 0) { cur_db_num = get_data_block(&datablock, inode, inode->num_blocks-1); make_free_datablock(cur_db_num); inode->num_blocks--; } if(inode->indirect1 != 0) { make_free_datablock(inode->indirect1); inode->indirect1 = 0; } if(inode->indirect2 !=0) { if(!read_block(file, idb2, inode->indirect2)) { return ERR_INTERNAL; } for(i=0; i<128; i++) { if(idb2->pointer[i] != 0) { make_free_datablock(idb2->pointer[i]); } } make_free_datablock(inode->indirect2); inode->indirect2 = 0; } for(i=0; i<10; i++) { inode->file_blocks[i] = 0; } inode->is_dir = 0; inode->is_free = 1; if(!read_block(file, sb, 1)) { return ERR_INTERNAL; } inode->next_free_inode = sb->free_inode_list; sb->free_inode_list = inode_num; if(!write_block(file, sb, 1)) { return ERR_INTERNAL; } put_inode_block(ib, inode_num); }
int file_read(int file_number, void *buffer, int bytes) { struct inode_block *inode_block = NULL; struct inode *inode = NULL; struct datablock *datablock = NULL; int copened, inum, spos; int file_size; //in bytes int pos, bnum, bidx; int new_db = 0; int bytes_r=0; BYTE *bbuffer = (BYTE *)buffer; int cur_blk_num; copened = open_file_table[file_number].currently_opened; inum = open_file_table[file_number].inode_number; spos = open_file_table[file_number].seek_position; if(copened == 0) { DEBUG1 && printf("file desc %d is not opened \n", file_number); return ERR_FILE_NOT_OPEN; } if(inum <= 0) { DEBUG2 && printf("invalid inode \n"); return ERR_INTERNAL; } get_inode(&inode_block, &inode, inum); file_size = 512 * inode->num_blocks; //printf("num_data_blocks = %d \n", inode->num_blocks); //printf("file_size = %d \n", file_size); bnum = spos / 512; bidx = spos % 512; //printf("bum %d, bidx %d \n",bnum, bidx); //printf("starting byte = %d\n", datablock->byte[bidx]); int i = bidx; while(bytes_r < bytes && (file_size - (spos+bytes_r)) > 0) { if(bnum > inode->num_blocks) break; cur_blk_num = get_data_block(&datablock, inode, bnum); if(datablock == NULL) { DEBUG2 && printf("error: datablock is null \n"); break; } for(i; i < 512; i++) { *bbuffer = datablock->byte[i]; bbuffer++; bytes_r++; if(bytes_r >= bytes || (file_size - (spos+bytes_r)) < 0 ) { break; } } //new_db--; i = 0; bnum++; //cur_blk_num = get_data_block(&datablock, inode, bnum); } open_file_table[file_number].seek_position += bytes_r; return bytes_r; }
int file_write(int file_number, void *buffer, int bytes) { struct inode_block *inode_block = NULL; struct inode *inode = NULL; struct datablock *datablock = NULL; int copened, inum, spos; int file_size; //in bytes int pos, bnum, bidx; int new_db = 0; int bytes_w =0; BYTE *bbuffer = (BYTE *)buffer; int cur_blk_num; copened = open_file_table[file_number].currently_opened; inum = open_file_table[file_number].inode_number; spos = open_file_table[file_number].seek_position; if(copened == 0) { DEBUG1 && printf("file desc %d is not opened \n", file_number); return ERR_FILE_NOT_OPEN; } if(inum <= 0) { DEBUG2 && printf("invalid inode \n"); return ERR_INTERNAL; } get_inode(&inode_block, &inode, inum); file_size = 512 * inode->num_blocks; //printf("num_data_blocks = %d \n", inode->num_blocks); //printf("file_size = %d \n", file_size); while(((512*inode->num_blocks) - spos) < bytes) { int new_db_num; new_db_num = add_data_block(inum); get_inode(&inode_block, &inode, inum); if(new_db_num <=0) { //cannot get anymore blocks!! must be out of space //we will write what we can break; } new_db++; } //printf("num_data_blocks = %d \n", inode->num_blocks); bnum = spos / 512; bidx = spos % 512; //printf("bum %d, bidx %d \n",bnum, bidx); //printf("starting byte = %d\n", datablock->byte[bidx]); int i = bidx; pos = spos; while(bytes_w < bytes && pos < inode->num_blocks*512) { cur_blk_num = get_data_block(&datablock, inode, bnum); if(datablock == NULL) { DEBUG2 && printf("error: datablock is null \n"); break; } for(i; i < 512; i++) { datablock->byte[i] = *bbuffer; bbuffer++; bytes_w++; pos++; if(bytes_w >= bytes || pos >= inode->num_blocks*512) { break; } } if( !write_block(file, datablock, cur_blk_num)) { DEBUG2 && printf("error reading datablock\n"); return ERR_INTERNAL; } //new_db--; i = 0; bnum++; //cur_blk_num = get_data_block(&datablock, inode, bnum); } open_file_table[file_number].seek_position += bytes_w; return bytes_w; }