Inode *cylin_intersect(Prim *p, Ray ro) { double a, b, c, disc, t0, t1, t2, t3; Inode *i0, *i1; int flag[4] = {FALSE, FALSE, FALSE, FALSE}; Ray r = ray_transform(ro, p->ti); Vector3 Sol0, Sol1, Sol2, Sol3; a = SQR(r.d.x) + SQR(r.d.y); b = 2 * (r.o.x * r.d.x + r.o.y * r.d.y); c = SQR(r.o.x) + SQR(r.o.y) - 1; // Case 0: no solution / infinite solutions if ((disc = SQR(b) - 4 * a * c) <= 0) return (Inode *)0; if ( fabs(a) < RAY_EPS ) { return (Inode *)0; } else { t0 = (-b - sqrt(disc)) / (2 * a); t1 = (-b + sqrt(disc)) / (2 * a); Sol0 = ray_point(r, t0); Sol1 = ray_point(r, t1); if (t1 > RAY_EPS && Sol1.z >= 0 && Sol1.z <= 1){ flag[1] = TRUE; } if (t0 > RAY_EPS && Sol0.z >= 0 && Sol0.z <= 1){ flag[0] = TRUE; } } // Ray NOT parallel to base caps --> Cap intersections if ( fabs(r.d.z) > RAY_EPS ){ t2 = - (r.o.z) / (r.d.z); t3 = (1 - (r.o.z)) / (r.d.z); Sol2 = ray_point(r,t2); Sol3 = ray_point(r,t3); if (t2 > RAY_EPS && (SQR(Sol2.x) + SQR(Sol2.y)) <= 1) flag[2] = TRUE; if (t3 > RAY_EPS && (SQR(Sol3.x) + SQR(Sol3.y)) <= 1) flag[3] = TRUE; } int k = 0, nsols = 0; double t[4] = {t0, t1, t2, t3}; while (k < 4 && nsols < 2){ if (flag[k]){ Vector3 n = v3_unit(cylin_gradient(p, ray_point(ro, t[k]))); if ( nsols == 0 ){ i0 = inode_alloc(t[k], n, TRUE); } else { i1 = inode_alloc(t[k], n, FALSE); i0->next = i1; } nsols++; } k++; } return i0; }
Inode *torus_intersect(Prim *p, Ray ro) { double a, b, c, disc, t0, t1; Inode *i0, *i1; Ray r = ray_transform(ro, p->ti); a = v3_sqrnorm(r.d); b = 2 * v3_dot(r.d, r.o); c = v3_sqrnorm(r.o) - 1; if ((disc = SQR(b) - 4 * a * c) <= 0) return (Inode *)0; t0 = (-b - sqrt(disc)) / (2 * a); t1 = (-b + sqrt(disc)) / (2 * a); if (t1 < RAY_EPS) return (Inode *)0; if (t0 < RAY_EPS) { Vector3 n1 = v3_unit(torus_gradient(p, ray_point(r, t1))); return inode_alloc(t1, n1, FALSE); } else { Vector3 n0 = v3_unit(torus_gradient(p, ray_point(ro, t0))); Vector3 n1 = v3_unit(torus_gradient(p, ray_point(ro, t1))); i0 = inode_alloc(t0, n0, TRUE); i1 = inode_alloc(t1, n1, FALSE); i0->next = i1; return i0; } }
int denemefs_read_super(struct SuperBlock* sb) { ASSERT(sb->dev == 123); ASSERT(sb->fs_type == 123); sb->root = dirent_alloc(); sb->root->mounted = 1; strcpy(sb->root->name, ""); sb->root->inode = inode_alloc(); struct inode *i = sb->root->inode; i->ino = 0; i->superblock = sb; i->op = &denemefs_dir_inode_op; i->size = di[0].size; return 0; }
void main (int argc, char ** argv) { while (1) { int err; if (argc != 2) { puts ("usage: mkromfs <dir>"); err = 1; break; } printf ("Starting from %s directory.\n", argv [1]); puts ("\nParsing file system..."); list_init (&_inodes); inode_build_t * root_node = inode_alloc (NULL, argv [1]); if (!root_node) break; root_node->flags = INODE_DIR; err = parse_dir (NULL, root_node, argv [1]); if (err) break; puts ("End of parsing."); printf ("\nTotal inodes: %u\n", _inodes.count); puts ("\nCompiling file system..."); err = compile_fs (); if (err) break; puts ("End of compilation."); break; } }
static struct inode *open_ext4_db(char *file) { int fd; struct ext4_extent_header *ihdr; struct inode *inode; struct db_handle *db; struct block_device *bdev; fd = device_open(file); bdev = bdev_alloc(fd, 12); inode = inode_alloc(bdev->bd_super); /* For testing purpose, those data is hard-coded. */ inode->i_writeback = inode_sb_writeback; memset(inode->i_uuid, 0xCC, sizeof(inode->i_uuid)); inode->i_inum = 45; inode->i_csum = ext4_crc32c(~0, inode->i_uuid, sizeof(inode->i_uuid)); inode->i_csum = ext4_crc32c(inode->i_csum, &inode->i_inum, sizeof(inode->i_inum)); inode->i_csum = ext4_crc32c(inode->i_csum, &inode->i_generation, sizeof(inode->i_generation)); if (!device_size(bdev)) exit(EXIT_FAILURE); db = db_open(inode->i_sb); ihdr = ext4_ext_inode_hdr(inode); memcpy(ihdr, db->db_header->db_tree_base, sizeof(inode->i_data)); if (ihdr->eh_magic != EXT4_EXT_MAGIC) { ext4_ext_init_i_blocks(ihdr); inode->i_data_dirty = 1; } inode->i_db = db; return inode; }
static int parse_dir (inode_build_t * grand_parent_inode, inode_build_t * parent_inode, char * parent_path) { int err; DIR * parent_dir = NULL; while (1) { parent_dir = opendir (parent_path); if (!parent_dir) { err = errno; break; } while (1) { struct dirent * ent = readdir (parent_dir); if (!ent) { err = errno; break; } char * name = ent->d_name; entry_build_t * child_ent = entry_alloc (parent_inode, name); if (!child_ent) { err = -1; break; } char * child_path = malloc (strlen (parent_path) + 1 + strlen (name) + 1); strcpy (child_path, parent_path); strcat (child_path, "/"); strcat (child_path, name); if (!strcmp (name, ".")) { printf ("Pseudo: %s\n", child_path); child_ent->inode = parent_inode; } else if (!strcmp (name, "..")) { printf ("Pseudo: %s\n", child_path); if (grand_parent_inode) child_ent->inode = grand_parent_inode; else child_ent->inode = parent_inode; /* self for root */ } else { inode_build_t * child_inode = inode_alloc (parent_inode, child_path); if (!child_inode) { err = -1; break; } child_ent->inode = child_inode; struct stat child_stat; err = lstat (child_path, &child_stat); if (err) { err = errno; break; } if (S_ISREG (child_stat.st_mode)) { printf ("File: %s\n", child_path); child_inode->flags = INODE_FILE; child_inode->size = child_stat.st_size; } else if (S_ISDIR (child_stat.st_mode)) { printf ("Dir: %s\n", child_path); child_inode->flags = INODE_DIR; err = parse_dir (parent_inode, child_inode, child_path); if (err) break; } else { assert (0); } } if (child_path) free (child_path); } if (err != 0) { perror ("Read directory"); } break; } if (parent_dir) closedir (parent_dir); return err; }
// Open a file (or directory). // // Returns: // The file descriptor index on success // -E_BAD_PATH if the path is too long (>= MAXPATHLEN) // -E_BAD_PATH if an intermediate path component is not a directory // -E_MAX_FD if no more file descriptors // -E_NOT_FOUND if the file (or a path component) was not found // (and others) int open(const char *path, int mode) { // Find an unused file descriptor page using fd_find_unused // and allocate a page there (PTE_P|PTE_U|PTE_W|PTE_SHARE). // // LAB 5: Your code here int r; struct Fd *fd; if((r = fd_find_unused(&fd)) < 0 || (r = sys_page_alloc(0, fd, PTE_P|PTE_U|PTE_W|PTE_SHARE)) < 0) goto err1; // Check the pathname. Error if too long. // Use path_walk to find the corresponding directory entry. // If '(mode & O_CREAT) == 0' (Exercise 4), // Return -E_NOT_FOUND if the file is not found. // Otherwise, use inode_open to open the inode. // If '(mode & O_CREAT) != 0' (Exercise 7), // Create the file if it doesn't exist yet. // Allocate a new inode, initialize its fields, and // reference that inode from the new directory entry. // Flush any blocks you change. // Directories can be opened, but only as read-only: // return -E_IS_DIR if '(mode & O_ACCMODE) != O_RDONLY'. // // Check for errors. On error, make sure you clean up any // allocated objects. // // The root directory is a special case -- if you aren't careful, // you will deadlock when the root directory is opened. (Why?) // // LAB 5: Your code here. int i; for(i = 0; i < MAXNAMELEN && path[i]; i++); if(i == MAXNAMELEN) { r = -E_BAD_PATH; goto err2; } struct Inode *dirino; struct Direntry *de; if((r = path_walk(path, &dirino, &de, mode & O_CREAT))) goto err2; struct Inode *fileino; if(!(mode & O_CREAT)) { if(de == &super->s_root) fileino = dirino; else if((r = inode_open(de->de_inum, &fileino)) < 0) goto err3; if(fileino->i_ftype == FTYPE_DIR && ( mode & O_ACCMODE) != O_RDONLY) { r = -E_IS_DIR; goto err4; } } else { if((r = inode_alloc(&fileino)) < 0) goto err3; fileino->i_ftype = FTYPE_REG; fileino->i_refcount = 1; fileino->i_size = 0; memset(&fileino->i_direct, 0, NDIRECT * sizeof (blocknum_t)); de->de_inum = fileino->i_inum; bcache_ipc(fileino, BCREQ_FLUSH); bcache_ipc(dirino, BCREQ_FLUSH); } // If '(mode & O_TRUNC) != 0' and the open mode is not read-only, // set the file's length to 0. Flush any blocks you change. // // LAB 5: Your code here (Exercise 8). if((mode & O_TRUNC)) { inode_set_size(fileino, 0); } // The open has succeeded. // Fill in all parts of the 'fd' appropriately. Use 'devfile.dev_id'. // Copy the file's pathname into 'fd->fd_file.open_path' to improve // error messages later. // You must account for the open file reference in the inode as well. // Clean up any open inodes. // // LAB 5: Your code here (Exercise 4). fd->fd_dev_id = devfile.dev_id; fd->fd_offset = 0; fd->fd_omode = mode; fd->fd_file.inum = fileino->i_inum; strcpy(fd->fd_file.open_path, path); fileino->i_opencount++; inode_close(dirino); inode_close(fileino); return fd2num(fd); err4: inode_close(fileino); err3: inode_close(dirino); err2: sys_page_unmap(thisenv->env_id, fd); err1: return r; }
int inode_reserve(FAR const char *path, FAR struct inode **inode) { const char *name = path; FAR struct inode *left; FAR struct inode *parent; /* Assume failure */ DEBUGASSERT(path && inode); *inode = NULL; /* Handle paths that are interpreted as the root directory */ if (!*path || path[0] != '/') { return -EINVAL; } /* Find the location to insert the new subtree */ if (inode_search(&name, &left, &parent, (FAR const char **)NULL) != NULL) { /* It is an error if the node already exists in the tree */ return -EEXIST; } /* Now we now where to insert the subtree */ for (;;) { FAR struct inode *node; /* Create a new node -- we need to know if this is the * the leaf node or some intermediary. We can find this * by looking at the next name. */ FAR const char *next_name = inode_nextname(name); if (*next_name) { /* Insert an operationless node */ node = inode_alloc(name); if (node) { inode_insert(node, left, parent); /* Set up for the next time through the loop */ name = next_name; left = NULL; parent = node; continue; } } else { node = inode_alloc(name); if (node) { inode_insert(node, left, parent); *inode = node; return OK; } } /* We get here on failures to allocate node memory */ return -ENOMEM; } }