1 /* VTreeFS - path.c - name resolution */ 2 3 #include "inc.h" 4 5 /* 6 * Resolve a path string to an inode. 7 */ 8 int 9 fs_lookup(ino_t dir_nr, char * name, struct fsdriver_node * node_details, 10 int * is_mountpt) 11 { 12 struct inode *node, *child; 13 int r; 14 15 if ((node = find_inode(dir_nr)) == NULL) 16 return EINVAL; 17 18 if (!S_ISDIR(node->i_stat.mode)) 19 return ENOTDIR; 20 21 if (strlen(name) > NAME_MAX) 22 return ENAMETOOLONG; 23 24 if (!strcmp(name, ".")) { 25 /* Stay in the given directory. */ 26 child = node; 27 } else if (!strcmp(name, "..")) { 28 /* Progress into the parent directory. */ 29 if ((child = get_parent_inode(node)) == NULL) 30 return ENOENT; /* deleted? should not be possible */ 31 } else { 32 /* Progress into a directory entry. Call the lookup hook, if 33 * present, before doing the actual lookup. 34 */ 35 if (!is_inode_deleted(node) && 36 vtreefs_hooks->lookup_hook != NULL) { 37 r = vtreefs_hooks->lookup_hook(node, name, 38 get_inode_cbdata(node)); 39 if (r != OK) return r; 40 } 41 42 if ((child = get_inode_by_name(node, name)) == NULL) 43 return ENOENT; 44 } 45 46 /* On success, open the resulting file and return its details. */ 47 ref_inode(child); 48 49 node_details->fn_ino_nr = get_inode_number(child); 50 node_details->fn_mode = child->i_stat.mode; 51 node_details->fn_size = child->i_stat.size; 52 node_details->fn_uid = child->i_stat.uid; 53 node_details->fn_gid = child->i_stat.gid; 54 node_details->fn_dev = child->i_stat.dev; 55 56 *is_mountpt = FALSE; 57 58 return OK; 59 } 60