1 #include "inc.h" 2 3 static int search_dir( 4 struct inode *ldir_ptr, /* dir record parent */ 5 char string[NAME_MAX], /* component to search for */ 6 ino_t *numb /* pointer to new dir record */ 7 ) { 8 /* The search_dir function performs the operation of searching for the 9 * component ``string" in ldir_ptr. It returns the response and the 10 * number of the inode in numb. 11 */ 12 struct inode *dir_tmp; 13 size_t pos = 0; 14 int r; 15 16 /* 17 * This function search a particular element (in string) in a inode and 18 * return its number. 19 */ 20 21 if ((ldir_ptr->i_stat.st_mode & S_IFMT) != S_IFDIR) 22 return ENOTDIR; 23 24 if (strcmp(string, ".") == 0) { 25 *numb = ldir_ptr->i_stat.st_ino; 26 return OK; 27 } 28 29 /* 30 * Parent directories need special attention to make sure directory 31 * inodes stay consistent. 32 */ 33 if (strcmp(string, "..") == 0) { 34 if (ldir_ptr->i_stat.st_ino == 35 v_pri.inode_root->i_stat.st_ino) { 36 *numb = v_pri.inode_root->i_stat.st_ino; 37 return OK; 38 } 39 else { 40 dir_tmp = alloc_inode(); 41 r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos); 42 if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) { 43 put_inode(dir_tmp); 44 return ENOENT; 45 } 46 /* Temporary fix for extent spilling */ 47 put_inode(dir_tmp); 48 dir_tmp = alloc_inode(); 49 /* End of fix */ 50 r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos); 51 if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) { 52 put_inode(dir_tmp); 53 return ENOENT; 54 } 55 *numb = dir_tmp->i_stat.st_ino; 56 put_inode(dir_tmp); 57 return OK; 58 } 59 } 60 61 /* Read the dir's content */ 62 while (TRUE) { 63 dir_tmp = alloc_inode(); 64 r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos); 65 if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) { 66 put_inode(dir_tmp); 67 return ENOENT; 68 } 69 70 if ((strcmp(dir_tmp->i_name, string) == 0) || 71 (strcmp(dir_tmp->i_name, "..") && 72 strcmp(string, "..") == 0)) { 73 if (dir_tmp->i_stat.st_ino == 74 v_pri.inode_root->i_stat.st_ino) { 75 *numb = v_pri.inode_root->i_stat.st_ino; 76 put_inode(dir_tmp); 77 return OK; 78 } 79 80 *numb = dir_tmp->i_stat.st_ino; 81 put_inode(dir_tmp); 82 return OK; 83 } 84 85 put_inode(dir_tmp); 86 } 87 } 88 89 int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node, 90 int *is_mountpt) 91 { 92 /* Given a directory and a component of a path, look up the component 93 * in the directory, find the inode, open it, and return its details. 94 */ 95 struct inode *dirp, *rip; 96 ino_t ino_nr; 97 int r; 98 99 /* Find the starting inode. */ 100 if ((dirp = find_inode(dir_nr)) == NULL) 101 return EINVAL; 102 103 /* Look up the directory entry. */ 104 if ((r = search_dir(dirp, name, &ino_nr)) != OK) 105 return r; 106 107 /* The component has been found in the directory. Get the inode. */ 108 if ((rip = get_inode(ino_nr)) == NULL) 109 return EIO; /* FIXME: this could have multiple causes */ 110 111 /* Return its details to the caller. */ 112 node->fn_ino_nr = rip->i_stat.st_ino; 113 node->fn_mode = rip->i_stat.st_mode; 114 node->fn_size = rip->i_stat.st_size; 115 node->fn_uid = rip->i_stat.st_uid; 116 node->fn_gid = rip->i_stat.st_gid; 117 node->fn_dev = rip->i_stat.st_rdev; 118 119 *is_mountpt = rip->i_mountpoint; 120 121 return OK; 122 } 123