123 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "inc.h"
 | |
| 
 | |
| static int search_dir(
 | |
| 	struct inode *ldir_ptr,		/* dir record parent */
 | |
| 	char string[NAME_MAX],			/* component to search for */
 | |
| 	ino_t *numb				/* pointer to new dir record */
 | |
| ) {
 | |
| 	/* The search_dir function performs the operation of searching for the
 | |
| 	 * component ``string" in ldir_ptr. It returns the response and the
 | |
| 	 * number of the inode in numb.
 | |
| 	 */
 | |
| 	struct inode *dir_tmp;
 | |
| 	size_t pos = 0;
 | |
| 	int r;
 | |
| 
 | |
| 	/*
 | |
| 	 * This function search a particular element (in string) in a inode and
 | |
| 	 * return its number.
 | |
| 	 */
 | |
| 
 | |
| 	if ((ldir_ptr->i_stat.st_mode & S_IFMT) != S_IFDIR)
 | |
| 		return ENOTDIR;
 | |
| 
 | |
| 	if (strcmp(string, ".") == 0) {
 | |
| 		*numb = ldir_ptr->i_stat.st_ino;
 | |
| 		return OK;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Parent directories need special attention to make sure directory
 | |
| 	 * inodes stay consistent.
 | |
| 	*/
 | |
| 	if (strcmp(string, "..") == 0) {
 | |
| 		if (ldir_ptr->i_stat.st_ino ==
 | |
| 		    v_pri.inode_root->i_stat.st_ino) {
 | |
| 			*numb = v_pri.inode_root->i_stat.st_ino;
 | |
| 			return OK;
 | |
| 		}
 | |
| 		else {
 | |
| 			dir_tmp = alloc_inode();
 | |
| 			r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos);
 | |
| 			if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) {
 | |
| 				put_inode(dir_tmp);
 | |
| 				return ENOENT;
 | |
| 			}
 | |
| 			/* Temporary fix for extent spilling */
 | |
| 			put_inode(dir_tmp);
 | |
| 			dir_tmp = alloc_inode();
 | |
| 			/* End of fix */
 | |
| 			r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos);
 | |
| 			if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) {
 | |
| 				put_inode(dir_tmp);
 | |
| 				return ENOENT;
 | |
| 			}
 | |
| 			*numb = dir_tmp->i_stat.st_ino;
 | |
| 			put_inode(dir_tmp);
 | |
| 			return OK;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* Read the dir's content */
 | |
| 	while (TRUE) {
 | |
| 		dir_tmp = alloc_inode();
 | |
| 		r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos);
 | |
| 		if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) {
 | |
| 			put_inode(dir_tmp);
 | |
| 			return ENOENT;
 | |
| 		}
 | |
| 
 | |
| 		if ((strcmp(dir_tmp->i_name, string) == 0) ||
 | |
| 		    (strcmp(dir_tmp->i_name, "..") &&
 | |
| 		    strcmp(string, "..") == 0)) {
 | |
| 			if (dir_tmp->i_stat.st_ino ==
 | |
| 			    v_pri.inode_root->i_stat.st_ino) {
 | |
| 				*numb = v_pri.inode_root->i_stat.st_ino;
 | |
| 				put_inode(dir_tmp);
 | |
| 				return OK;
 | |
| 			}
 | |
| 
 | |
| 			*numb = dir_tmp->i_stat.st_ino;
 | |
| 			put_inode(dir_tmp);
 | |
| 			return OK;
 | |
| 		}
 | |
| 
 | |
| 		put_inode(dir_tmp);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
 | |
| 	int *is_mountpt)
 | |
| {
 | |
| 	/* Given a directory and a component of a path, look up the component
 | |
| 	 * in the directory, find the inode, open it, and return its details.
 | |
| 	 */
 | |
| 	struct inode *dirp, *rip;
 | |
| 	ino_t ino_nr;
 | |
| 	int r;
 | |
| 
 | |
| 	/* Find the starting inode. */
 | |
| 	if ((dirp = find_inode(dir_nr)) == NULL)
 | |
| 		return EINVAL;
 | |
| 
 | |
| 	/* Look up the directory entry. */
 | |
| 	if ((r = search_dir(dirp, name, &ino_nr)) != OK)
 | |
| 		return r;
 | |
| 
 | |
| 	/* The component has been found in the directory.  Get the inode. */
 | |
| 	if ((rip = get_inode(ino_nr)) == NULL)
 | |
| 		return EIO;	/* FIXME: this could have multiple causes */
 | |
| 
 | |
| 	/* Return its details to the caller. */
 | |
| 	node->fn_ino_nr	= rip->i_stat.st_ino;
 | |
| 	node->fn_mode	= rip->i_stat.st_mode;
 | |
| 	node->fn_size	= rip->i_stat.st_size;
 | |
| 	node->fn_uid	= rip->i_stat.st_uid;
 | |
| 	node->fn_gid	= rip->i_stat.st_gid;
 | |
| 	node->fn_dev	= rip->i_stat.st_rdev;
 | |
| 
 | |
| 	*is_mountpt = rip->i_mountpoint;
 | |
| 
 | |
| 	return OK;
 | |
| }
 | 
