static void materialize_imgspec(struct imgspec* const spec) { if (ftruncate(spec->sp_fd, spec->sp_upperbound) < 0) error("failed to truncate the image file: %s", strerror(errno)); char* image = mmap(NULL, spec->sp_upperbound, PROT_READ | PROT_WRITE, MAP_SHARED, spec->sp_fd, 0); if (image == MAP_FAILED) error("failed to mmap the image file: %s", strerror(errno)); __u64 offset = superblock_offset(spec) + sizeof(struct microfs_sb); offset = write_decompressordata(spec, image, offset); offset = write_metadata(spec, image, offset); offset = write_data(spec, image, offset); const __u64 innersz = offset; const __u64 outersz = sz_blkceil(offset, spec->sp_szpad); write_superblock(spec, image, innersz); if (munmap(image, spec->sp_upperbound) < 0) error("failed to unmap the image: %s", strerror(errno)); if (ftruncate(spec->sp_fd, outersz) < 0) error("failed to set the final image size: %s", strerror(errno)); message(VERBOSITY_1, "Inner image size: %llu bytes", innersz); message(VERBOSITY_0, "Outer image size: %llu bytes", outersz); }
static int vbfs_format_device() { int ret = 0; vbfs_prepare_superblock(); ret = write_root_dentry(); if (ret < 0) return -1; ret = write_bad_extend(); if (ret < 0) return -1; ret = write_bitmap(); if (ret < 0) return -1; ret = write_superblock(); if (ret < 0) return -1; fsync(vbfs_params.fd); close(vbfs_params.fd); return 0; }
void StorageLog::format(int fd) { printf("Formatted\n"); unsigned char* superblock_pt; int freeresult; //update superblock superblock_pt = get_superblock(fd); Superblock* pt = (Superblock*) superblock_pt; if(isValid(superblock_pt)) { pt->generation++; pt->logstart = LOGSTARTBLOCK; // which block pt->logsize = MAXLOGBLOCKNUM; // which block } else { pt->generation = 0; pt->logstart = LOGSTARTBLOCK; // which block pt->logsize = MAXLOGBLOCKNUM; // which block } update_checksum_super(superblock_pt); //printf("update_checksum_super finished\n"); write_superblock(fd, superblock_pt); //printf("write_super finished\n"); //clear check point edge_list.clear(); //printf("edge_list cleared\n"); assert(edge_list.empty()); //printf("edge_list empty asserted\n"); storegraph(pt->logsize, fd, edge_list); //printf("graph stored\n"); //free in memory superblock freeresult = munmap(superblock_pt, PAGESIZE); if(freeresult == -1) { printf("free superblock memory block failed in format\n"); } }
/************************************* *store the current checkpoint *increase generation number in superblock *update lastblock and lastentry *return 0 on success *return -1 indicating no enough space for checkpoint **************************************/ int StorageLog::checkpoint(int fd) { if(checkspace(edge_list) == -1) { return -1; } unsigned char* superblock_pt; ssize_t freeresult; superblock_pt = get_superblock(fd); Superblock* pt = (Superblock*) superblock_pt; if(isValid(superblock_pt)) { int storeresult = storegraph(pt->logsize, fd, edge_list); if(storeresult < 0) { printf("store checkpoint failed in checkpoint, too large\n"); return -1; } } else { printf("superblock is invalid in checkpoint\n"); exit(-1); } pt->generation++; update_checksum_super(superblock_pt); write_superblock(fd, superblock_pt); lastblock = LOGSTARTBLOCK; lastentry = 0; freeresult = munmap(superblock_pt, PAGESIZE); if(freeresult < 0) { printf("free superblock failed in checkpoint\n"); } return 0; }
static int kvfs_unlink(const char* pathname){ int index = lookup(pathname); int i = 0; if(index >= 0){ for(i = index + 1; i < kvfs->size; i++){ kvfs->data[i-1] = kvfs->data[i]; } kvfs->size = kvfs->size - 1; kvfs = realloc(kvfs, sizeof(kvfs_t) + sizeof(fnode_t) * (kvfs->size)); clear_superblock(); write_superblock(); return 0; } else{ return -EACCES; } }
static int kvfs_flush(int fd){ clear_superblock(); write_superblock(); return 0; }
int main(int argc, char *argv[]) { int rv, fd, i, is_ssd; char *node; struct stat st; struct castle_slave_superblock_public super; char buf[4096]; /* check args */ if(argc != 2) { usage(); exit(2); } node = argv[1]; if(stat(node, &st)) { fprintf(stderr, "%s: failed to stat %s: %s\n", argv[0], node, strerror(errno)); exit(2); } #if 0 if(!st.st_rdev) { fprintf(stderr, "Warning: %s does not seem to be a device node\n", node); } #endif is_ssd = check_ssd(node); init_superblock(&super, is_ssd); /* write */ if((fd = open(node, O_RDWR|O_LARGEFILE|O_SYNC)) == -1) { /* open failed */ fprintf(stderr, "%s: failed to open %s: %s\n", argv[0], node, strerror(errno)); exit(1); } /* Set first MB of the disk to 0. */ memset(buf, 0 , 4096); for(i=0; i<(MB / 4096); i++) { if(write(fd, buf, 4096) != 4096) { fprintf(stderr, "Failure setting up disk!\n"); return 0; } } lseek(fd, 0, SEEK_SET); if(!write_superblock(fd, &super)) { fprintf(stderr, "%s: Error writing superblock on %s: %s", argv[0], node, strerror(errno)); exit(1); } if(close(fd)) { fprintf(stderr, "%s: Warning: error closing %s: %s", argv[0], node, strerror(errno)); exit(1); } exit(0); }
void initiate_super_block(int fd, int total_block_number, int inode_block_number) { curr_fd = fd; curr_superblock.isize = inode_block_number; curr_superblock.fsize = total_block_number; curr_superblock.nfree = 0; curr_superblock.ninode = 0; initiate_free_list(); initiate_inode_list(); write_superblock(); }
int main(int argc, char *argv[]) { int fd; ssize_t ret; char welcomefile_body[] = "Love is God. God is Love. Anbe Murugan.\n"; struct simplefs_inode welcome = { .mode = S_IFREG, .inode_no = WELCOMEFILE_INODE_NUMBER, .data_block_number = WELCOMEFILE_DATABLOCK_NUMBER, .data_size.file_size = sizeof(welcomefile_body), }; struct simplefs_dir_record record = { .filename = "vanakkam", .inode_no = WELCOMEFILE_INODE_NUMBER, }; if (argc != 2) { printf("Usage: mkfs-simplefs <device>\n"); return -1; } fd = open(argv[1], O_RDWR); if (fd == -1) { perror("Error opening the device"); return -1; } ret = 1; do { if (write_superblock(fd)) break; if (write_root_inode(fd)) break; if (write_journal_inode(fd)) break; if (write_welcome_inode(fd, &welcome)) break; if (write_journal(fd)) break; if (write_dirent(fd, &record)) break; if (write_block(fd, welcomefile_body, welcome.data_size.file_size)) break; ret = 0; } while (0); close(fd); return ret; }
int main(int argc, char **argv) { int devfd; // get the device from argv if(argc != 2) { fprintf(stderr, "need to pass in a device\n"); exit(1); } // open device devfd = open_device(argv[1], O_WRONLY); // find if there is enough space -- seek blocks * block size verify_device_space(devfd); // write the superblock write_superblock(devfd); // setup the inodes for / write_inode(devfd, 3, 1); // setup the inode for lost+found write_inode(devfd, 2, 2); // skip into file section // write directories for / ., .. struct rdfs_dirent *p = calloc(3, sizeof(struct rdfs_dirent)); struct rdfs_dirent *dirent = p; p->d_inode = 1; strcpy(p->d_name, "."); p++; p->d_inode = 1; strcpy(p->d_name, ".."); p++; p->d_inode = 2; strcpy(p->d_name, "lost+found"); write_directory(devfd, dirent, 3, 0); free(dirent); // write directories for lost+found ., .. p = calloc(2, sizeof(struct rdfs_dirent)); dirent = p; p->d_inode = 2; strcpy(p->d_name, "."); p++; p->d_inode = 1; strcpy(p->d_name, ".."); write_directory(devfd, dirent, 2, 1); free(dirent); return 0; }
static int kvfs_utimens(const char *path, const struct timespec tv[2]) { read_superblock(); int i; for(i = 0; i < kvfs->size ; i++) { if(kvfs->data[i].name == (path+1) ) { break; } } if(i == kvfs->size) { write_superblock(path+1,NULL); } return 0; }
void free_block(uint free_block) { if(curr_superblock.nfree == MAX_SIZE) { struct head_free_block w; //int i; w.nfr = curr_superblock.nfree; memcpy(w.fr, curr_superblock.free, curr_superblock.nfree * sizeof(uint)); write_block(free_block, (void*)&w, BLOCKSIZE); //write nfree and free array into block i; curr_superblock.nfree = 0; } curr_superblock.free[curr_superblock.nfree++] = free_block; write_superblock(); }
uint allocate_block() { curr_superblock.nfree--; uint block_id = curr_superblock.free[curr_superblock.nfree]; if(block_id == 0) { fprintf(stderr, "Error: the data blocks are full, allocation failure\n"); exit(-1); } if(curr_superblock.nfree == 0) { struct head_free_block w; //int i; read_block(block_id, (void*)&w, BLOCKSIZE); curr_superblock.nfree = w.nfr; memcpy(curr_superblock.free, w.fr, (curr_superblock.nfree + 1) * sizeof(uint)); } write_superblock(); return block_id; }
static int kvfs_rename(const char* name, const char* newname){ int index = lookup(name); if(index >= 0){ memset((void*) kvfs->data[index].name, 0, NAME_SIZE); strcpy(kvfs->data[index].name, newname); clear_superblock(); write_superblock(); return 0; } else{ return -EACCES; } }
int make_dir(char * name){ if(lookup_fs(name, DIRECTORY)){ printk("\nAlready exist dir"); return 0; } inode * inode_i ; int new_inode_number ; int new_inode_sector ; int dir_index=find_parent_index(name); if(dir_index== -1){ printk("\n Required PARENT Directory doesn't Exist :: Create one and try again"); return 0; } new_inode_number = get_free_inode_block(); new_inode_sector = get_inode_sector(new_inode_number); printk("\n %d %d", new_inode_number, new_inode_sector); read(&abar->ports[0], new_inode_sector, 0, 1, (uint64_t) inode_mgmt_buffer_p); inode_i = (inode *)inode_mgmt_buffer; inode_i += (new_inode_number-1)%3; inode_i->inode_num = new_inode_number; strcpy(inode_i->filename, name); inode_i->size = 0 ; inode_i->type = DIRECTORY; inode_i->perm = 0; int i = 0; for(i=0; i<10; i++) inode_i->sector_loc[i] = 0; write_superblock(); write(&abar->ports[0], new_inode_sector, 0, 1, (uint64_t) inode_mgmt_buffer_p); printk("\n sata_fs_count = [%d]",sata_fs_count); add_inode_to_table(inode_i); return 1; }
/**Initialize the superblock structure on disk. * * @param sb Pointer to the superblock structure. * * @return EOK on success or a negative error code. */ static int init_superblock(struct mfs_sb_info *sb) { aoff64_t inodes; unsigned long ind; unsigned long ind2; unsigned long zones; int rc; if (sb->longnames) sb->magic = sb->fs_version == 1 ? MFS_MAGIC_V1L : MFS_MAGIC_V2L; /* Compute the number of zones on disk */ if (sb->fs_version == 1) { /* Valid only for MFS V1 */ sb->n_zones = sb->dev_nblocks > UINT16_MAX ? UINT16_MAX : sb->dev_nblocks; ind = MFS_BLOCKSIZE / sizeof(uint16_t); ind2 = ind * ind; sb->max_file_size = (V1_NR_DIRECT_ZONES + ind + ind2) * MFS_BLOCKSIZE; } else { /*Valid for MFS V2/V3*/ size_t ptrsize; if (sb->fs_version == 2) ptrsize = sizeof(uint16_t); else ptrsize = sizeof(uint32_t); ind = sb->block_size / ptrsize; ind2 = ind * ind; zones = V2_NR_DIRECT_ZONES + ind + ind2; sb->max_file_size = zones * sb->block_size; sb->n_zones = sb->dev_nblocks > UINT32_MAX ? UINT32_MAX : sb->dev_nblocks; if (sb->fs_version == 3) { if(INT32_MAX / sb->block_size < zones) sb->max_file_size = INT32_MAX; sb->ino_per_block = V3_INODES_PER_BLOCK(sb->block_size); sb->n_zones /= (sb->block_size / MFS_MIN_BLOCKSIZE); } } /* Round up the number of inodes to fill block size */ if (sb->n_inodes == 0) inodes = sb->dev_nblocks / 3; else inodes = sb->n_inodes; if (inodes % sb->ino_per_block) inodes = ((inodes / sb->ino_per_block) + 1) * sb->ino_per_block; if (sb->fs_version < 3) sb->n_inodes = inodes > UINT16_MAX ? UINT16_MAX : inodes; else sb->n_inodes = inodes > UINT32_MAX ? UINT32_MAX : inodes; /* Compute inode bitmap size in blocks */ sb->ibmap_blocks = UPPER(sb->n_inodes, sb->block_size * 8); /* Compute inode table size */ sb->itable_size = sb->n_inodes / sb->ino_per_block; /* Compute zone bitmap size in blocks */ sb->zbmap_blocks = UPPER(sb->n_zones, sb->block_size * 8); /* Compute first data zone position */ sb->first_data_zone = 2 + sb->itable_size + sb->zbmap_blocks + sb->ibmap_blocks; /* Set log2 of zone to block ratio to zero */ sb->log2_zone_size = 0; /* Check for errors */ if (sb->first_data_zone >= sb->n_zones) { printf(NAME ": Error! Insufficient disk space"); return ENOMEM; } /* Superblock is now ready to be written on disk */ printf(NAME ": %d block size\n", sb->block_size); printf(NAME ": %d inodes\n", (uint32_t) sb->n_inodes); printf(NAME ": %d zones\n", (uint32_t) sb->n_zones); printf(NAME ": inode table blocks = %ld\n", sb->itable_size); printf(NAME ": inode bitmap blocks = %ld\n", sb->ibmap_blocks); printf(NAME ": zone bitmap blocks = %ld\n", sb->zbmap_blocks); printf(NAME ": first data zone = %d\n", (uint32_t)sb->first_data_zone); printf(NAME ": max file size = %u\n", sb->max_file_size); printf(NAME ": long fnames = %s\n", sb->longnames ? "Yes" : "No"); if (sb->fs_version == 3) rc = write_superblock3(sb); else rc = write_superblock(sb); return rc; }
int file_write(struct file *fd, char * buf, int size){ inode * inode_i; int len=0; int offset=fd->offset; int offset_in_sector; int sector_index; int sector_num; int free_data_block_no; int free_data_block_sector; int page_no = 0; int i=0; if(fd->inode_num != 0){ inode_i = read_inode(fd->inode_num); sector_index=(fd->offset/512); sector_num=inode_i->sector_loc[sector_index]; while(len<size){ offset_in_sector=((offset-1)%512); sector_index=(offset/512); sector_num=inode_i->sector_loc[sector_index]; if(sector_num==0){ free_data_block_no = get_free_data_block(); free_data_block_sector = get_data_sector(free_data_block_no); inode_i->sector_loc[page_no++] = free_data_block_sector; sector_num=free_data_block_sector; } if(offset_in_sector!=0 || (offset_in_sector ==0 && (size-len) <512)) read(&abar->ports[0], sector_num, 0, 1, (uint64_t) data_mgmt_buffer_p); char *tmp=(char *)data_mgmt_buffer; while(len < size && offset_in_sector <= 512){ tmp[((offset-1)%512)]=buf[len]; len++; offset++; offset_in_sector++; } write(&abar->ports[0], sector_num, 0, 1, (uint64_t) data_mgmt_buffer_p); } inode_i->size += len; write_inode(inode_i); write_superblock(); for(i=0;i<sata_fs_count;i++){ if(inode_i->inode_num==sata_fs[i].inode_num){ sata_fs[i].size=inode_i->size; break; } } } else{ printk("\nFile doesnt exist :: Try creating file first"); return 0; } return len; }
struct file * file_open(char *filename,int flag){ int inode_num = lookup_fs(filename, flag); inode * inode_i ; int i=0; kern_init_desc(); if(inode_num != 0 ){ inode_i = read_inode(inode_num); if(flag==DIRECTORY) printk("\nDIrectory EXISTS"); else printk("\nFile EXISTS"); printk("\nsize %d\n", inode_i->size); } else if(inode_num==0 && flag==FILE_TYPE){ int dir_index=find_parent_index(filename); if(dir_index== -1){ printk("\n Required Directory doesn't Exist :: Create one and try again"); return NULL; } int new_inode_number = get_free_inode_block(); int new_inode_sector = get_inode_sector(new_inode_number); printk("\n %d %d", new_inode_number, new_inode_sector); read(&abar->ports[0], new_inode_sector, 0, 1, (uint64_t) inode_mgmt_buffer_p); printk("\n %x %x", inode_mgmt_buffer, inode_mgmt_buffer_p); inode_i = (inode *)inode_mgmt_buffer; inode_i += (new_inode_number-1)%3; inode_i->inode_num = new_inode_number; strcpy(inode_i->filename, filename); inode_i->size = 0 ; inode_i->type = FILE_TYPE; inode_i->perm = 0; for(i=0;i<10;i++) inode_i->sector_loc[i]=0; sata_fs[dir_index].number_of_dentry +=1; add_inode_to_table(inode_i); write_superblock(); write(&abar->ports[0], new_inode_sector, 0, 1, (uint64_t) inode_mgmt_buffer_p); } else if(inode_num==0 && flag==DIRECTORY){ printk("\n NO Directory Exists"); return NULL; } else return NULL; sata_vfs_fd.inode_num=inode_i->inode_num; strcpy(sata_vfs_fd.filename, inode_i->filename); sata_vfs_fd.perm=inode_i->perm; sata_vfs_fd.size=inode_i->size; sata_vfs_fd.type=inode_i->type; sata_vfs_fd.location=FS_LOC; for(i=0;i<10;i++) sata_vfs_fd.sector_loc[i]=inode_i->sector_loc[i]; for(i=0;i<sata_fs_count;i++){ if(inode_i->inode_num==sata_fs[i].inode_num && inode_i->type==flag){ sata_vfs_fd.tarfs_table_index=i; break; } } return &sata_vfs_fd; }