// Returns true if a new direntry was read, otherwise false, indicating that // all of the entries have been read bool ext2_next_dirent(Ext2_file *file, Ext2_dirent *dir) { uint8_t buf[READ_SIZE]; if (ext2_read(file, buf, READ_SIZE) != READ_SIZE) // Not enough data left return false; memcpy(dir, buf, READ_SIZE); size_t size = dir->name_len + 1; uint8_t *name = kmalloc(size); if (ext2_read(file, name, size - 1) != size - 1) return false; dir->name = name; dir->name[size - 1] = '\0'; // Read up to the next entry size_t bytes_left = dir->total_len - (READ_SIZE + size - 1); if (bytes_left > 0) { uint8_t dummy[bytes_left]; ext2_read(file, dummy, bytes_left); } return true; }
int ext2_readlink(inode *ino, char *buf, size_t bufsize) { //ext2_filesystem *fs = (ino->fs); uint32_t byteRead = 0; ext2_inode *in = &ino->in; uint16_t linkCount = in->links_count; //uint32_t size; if (linkCount==0) { return -EINVAL; } else { //first check if the size exceeds 60 bytes ////////// SIZE < 60 if (in->size<60) { //if the total size is less than required if (bufsize<in->size) { memcpy(buf, &(in->block[0]), bufsize); byteRead = bufsize; } //if not else { memcpy(buf, &(in->block[0]), in->size); byteRead = in->size; } } ///////// SIZE > 60 else { //if the total size is less than required if (bufsize<in->size) { //use the ext2_read method which will calculate the total byte read byteRead = ext2_read(ino, buf, 0, bufsize); if (byteRead <0) return byteRead; } //total size > required else { byteRead = ext2_read(ino, buf, 0, in->size); if (byteRead <0) return byteRead; } } } return byteRead; }
int test_read() { char *path = "/hello"; char buf[4096]; int len; len = ext2_read(path, buf, 80, 0); assert_true(len > 0); buf[len] = '\0'; print_info("len: %d\ncontent of file:\n%s\n", len, buf); assert_ok(); }
static int fuse_ext2_read(const char *path, char *buf, size_t size, off_t offs, struct fuse_file_info *fi) { int ret; printf("read path: %s\n", path); size = 40; offs = 0; printf("sz: %d, off: %d\n", size, (int) offs); ret = ext2_read(path, buf, size, offs); printf("read file ret: %d\n", ret); return ret; }
static vnode *ext2_lookup(vnode *dir, const char *name) { ULONG ino; char *buffer = malloc(dir->size); ext2_d_entry *ent = (ext2_d_entry *)buffer; int read_size = dir->size; if (ext2_read(dir, 0, dir->size, buffer) <= 0) goto end; while (read_size > 0) { if (namei_nmatch(name, ent->name, ent->name_len)) { ino = ent->inode; free(buffer); return iget(dir->sb, ino); } if (!ent->rec_len) goto end; ent = (ext2_d_entry *)((UINT)ent + ent->rec_len); read_size -= ent->rec_len; } end: free(buffer); return 0; }
static int ext2_readdir(vnode *dir, off_t index, struct dirent *buf) { int err; char *buffer = malloc(dir->size); ext2_d_entry *ent = (ext2_d_entry *)buffer; int read_size = dir->size; if ((err = ext2_read(dir, 0, dir->size, buffer)) <= 0) goto end; err = -EINVAL; while (index--) { read_size -= ent->rec_len; if (read_size <= 0 || !ent->rec_len) goto end; ent = (ext2_d_entry *)((UINT)ent + ent->rec_len); } if (!ent->inode) goto end; buf->d_ino = ent->inode; strncpy(buf->d_name, ent->name, VFS_NAME_LEN); buf->d_namlen = strlen(buf->d_name); buf->d_name[ent->name_len] = 0; err = 0; end: free(buffer); return err; }
int ext2_readdir(inode *ino, struct dirent *dent, off_t *offset) { ext2_inode* in = &ino->in; uint32_t size = in->size; //want to read in 7 bytes for inode num (4), reclen (2) and name len (1) uint32_t byteToBeRead = INODENUM + RECLEN + NAMELEN; //need to save in a buffer and also allocate the space using malloc char* buff= (char*) malloc(byteToBeRead); //check the buff in advance if (buff==NULL) return 0; char * temp; //temp variables to save the fields inodenum, reclen and namelen uint32_t inodeNum; uint16_t recLen; uint8_t nameLen; //if buff is null then disregards while (*offset < size) { //read all the bytes into buff int r = ext2_read(ino, buff, *offset, byteToBeRead); if (r<0) { return r; } //read the first field (inode num) if its 0 returns and move the offset by reclen memcpy(&inodeNum, buff, INODENUM); memcpy(&recLen, (buff+INODENUM), RECLEN); memcpy(&nameLen, (buff+INODENUM+RECLEN), NAMELEN); // if inode field is 0, skip to the next entry if (inodeNum == 0) { *offset = *offset + recLen; memset(buff , 0, byteToBeRead); } //this entry is valid else { temp = (char*) malloc(recLen); if (temp==NULL) { return 0; } //read the whole entry int r = ext2_read(ino, temp, (*offset), recLen); if (r<0) return r; //printf("%d\n", (byteToBeRead+FILETYPE)); memcpy(&dent->d_ino, temp, INODENUM); memcpy(&dent->d_name, (temp+byteToBeRead+FILETYPE), nameLen); //string is terminated with "\0" dent->d_name[nameLen]= '\0'; (*offset) = (*offset) + recLen; free(buff); free(temp); //an entry as been read, return 1 return 1; } } free(buff); return 0; }
int main(int argc, char *argv[]) { int p = 0; int result; char buffer[256]; struct stat st; struct ext2context *context; printf("Running EXT2 tests...\n\n"); block_pc_set_image_name("testext.img"); printf("[%4d] start block device emulation...", p++); result = block_init(); printf(" %d\n", result); if(result != 0) { exit(0); } printf("[%4d] mount filesystem, FAT32", p++); result = ext2_mount(0, block_get_volume_size(), 0, &context); printf(" %d\n", result); struct file_ent *fe = ext2_open(context, "/", O_RDONLY, 0777, &result); struct file_ent *fe2; struct dirent *de; while((de = ext2_readdir(fe, &result))) { snprintf(buffer, sizeof(buffer), "/%s", de->d_name); fe2 = ext2_open(context, buffer, O_RDONLY, 0777, &result); ext2_fstat(fe2, &st, &result); printf("%s %d\n", de->d_name, (int)st.st_size); if((st.st_mode & S_IFDIR) && (strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) { // printf("Directory contents:\n"); // printf("fe2->cursor: %d\n", fe2->cursor); // printf("fe2->file_sector: %d\n", fe2->file_sector); while((de = ext2_readdir(fe2, &result))) { printf(" %s [%d]\n", de->d_name, de->d_ino); } } ext2_close(fe2, &result); } ext2_close(fe, &result); FILE *fw = fopen("dump.png", "wb"); fe = ext2_open(context, "/static/test_image.png", O_RDONLY, 0777, &result); printf("%p\n", fe); printf("fe->inode_number = %d\n", fe->inode_number); while((p = ext2_read(fe, &buffer, sizeof(buffer), &result)) == sizeof(buffer)) { fwrite(buffer, 1, p, fw); } if(p > 0) { fwrite(buffer, 1, p, fw); } fclose(fw); ext2_close(fe, &result); printf("\nWrite test...\n\n"); fe = ext2_open(context, "/logs/test.txt", O_WRONLY | O_APPEND, 0777, &result); if(fe == NULL) { printf("Open for writing failed, errno=%d (%s)\r\n", result, strerror(result)); exit(-1); } ext2_write(fe, "Hello world\r\n", 13, &result); ext2_close(fe, &result); ext2_print_bg1_bitmap(context); ext2_umount(context); block_pc_snapshot_all("writenfs.img"); block_halt(); exit(0); }