Compare commits
	
		
			No commits in common. "049405989b684ebf5c4c5ae4324b6de5488039c5" and "552e574cde247ee0d36b54d93f961c4346e5d38f" have entirely different histories.
		
	
	
		
			049405989b
			...
			552e574cde
		
	
		
							
								
								
									
										4
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								config.h
									
									
									
									
									
								
							| @ -26,8 +26,8 @@ | ||||
| #define FS_MAX_PATH_LEN 512 | ||||
| #define FS_MAX_OPEN_FD 32 | ||||
| #define FS_MAX_FNAME_LEN 11 | ||||
| #define FS_MAX_DIRECTORY_DEPTH 2048 | ||||
| #define FS_MAX_SYMLINK_FOLLOWS 1024 | ||||
| #define FS_MAX_DIRECTORY_DEPTH 512 | ||||
| #define FS_MAX_SYMLINK_FOLLOWING_DEPTH 1024 | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										257
									
								
								src/fs.c
									
									
									
									
									
								
							
							
						
						
									
										257
									
								
								src/fs.c
									
									
									
									
									
								
							| @ -24,7 +24,6 @@ static unsigned int fs_cwd_inode_ptr; | ||||
| static struct fs_file_description fs_file_descriptions[FS_MAX_OPEN_FD]; | ||||
| 
 | ||||
| static int extract_basename(char *path, char *name); | ||||
| static int read_symlink(int symlink_inode_ptr, char *path); | ||||
| 
 | ||||
| 
 | ||||
| static int read_block(unsigned int block_no, void *data) | ||||
| @ -908,21 +907,18 @@ fs_remove_fname_from_directory_finish: | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void resolve_path(struct resolved_path * const rp, const char * const original_path, const unsigned int params) | ||||
| static void resolve_path(struct resolved_path *rp, char *path, unsigned int params) | ||||
| { | ||||
| 	rp->parent_inode_ptr = -1; | ||||
| 	rp->target_inode_ptr = -1; | ||||
| 
 | ||||
| 	int path_len = strlen(original_path); | ||||
| 	int path_len = strlen(path); | ||||
| 
 | ||||
| 	if (!path_len) { | ||||
| 		pr_err("no path specified\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	char path[FS_MAX_PATH_LEN+1]; | ||||
| 	strcpy(path, original_path); | ||||
| 
 | ||||
| 	if (!strcmp(path, "/")) { | ||||
| 		rp->parent_inode_ptr = 0; | ||||
| 		rp->target_inode_ptr = 0; | ||||
| @ -935,8 +931,6 @@ static void resolve_path(struct resolved_path * const rp, const char * const ori | ||||
| 	int current_inode_ptr; | ||||
| 	int i; | ||||
| 
 | ||||
| 	unsigned int symlinks_followed = 0; | ||||
| 
 | ||||
| 	if (path[0] == '/') { | ||||
| 		current_inode_ptr = 0; | ||||
| 		rp->parent_inode_ptr = 0; | ||||
| @ -956,149 +950,65 @@ static void resolve_path(struct resolved_path * const rp, const char * const ori | ||||
| 		if (path[i] != '/') { | ||||
| 			next_fname[next_fname_ptr] = path[i]; | ||||
| 			next_fname_ptr++; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if ((path[i] != '/') && (i+1 < path_len)) | ||||
| 			continue; | ||||
| 		// path[i] == '/', trying to change current directory
 | ||||
| 
 | ||||
| 		if (!next_fname_ptr) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (i+1 == path_len) | ||||
| 			continue; | ||||
| 
 | ||||
| 		{ | ||||
| 			int res = find_fname_in_directory(current_inode_ptr, next_fname); | ||||
| 			if (res < 0) { | ||||
| 				pr_warn("directory '%s' does not exist\n", next_fname); | ||||
| 				rp->parent_inode_ptr = -1; | ||||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| 			{ | ||||
| 				struct fs_inode d; | ||||
| 				read_block(read_inode_ptr(res), &d); | ||||
| 
 | ||||
| 				if (d.ftype == REGULAR) { | ||||
| 					pr_warn("'%s' is a regular file\n", next_fname); | ||||
| 					rp->parent_inode_ptr = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			pr("Found directory '%s'\n", next_fname); | ||||
| 			current_inode_ptr = res; | ||||
| 			rp->parent_inode_ptr = res; | ||||
| 		} | ||||
| 
 | ||||
| 		next_fname_ptr = 0; | ||||
| 		strcpy(current_fname, next_fname); | ||||
| 		memset(next_fname, 0, FS_MAX_FNAME_LEN); | ||||
| 	} | ||||
| 
 | ||||
| 	if (rp->parent_inode_ptr < 0) { | ||||
| 		rp->target_inode_ptr = -1; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	strcpy(rp->parent_fname, current_fname); | ||||
| 
 | ||||
| 	{ | ||||
| 		int res = find_fname_in_directory(current_inode_ptr, next_fname); | ||||
| 		if (res < 0) { | ||||
| 			if (i+1 < path_len) { | ||||
| 				pr_warn("parent '%s' does not exist\n", next_fname); | ||||
| 				rp->parent_inode_ptr = -1; | ||||
| 			} | ||||
| 
 | ||||
| 			pr_warn("target fname '%s' does not exist\n", next_fname); | ||||
| 			rp->target_inode_ptr = -1; | ||||
| 			break; | ||||
| 		} else { | ||||
| 			rp->target_inode_ptr = res; | ||||
| 			strcpy(rp->target_fname, next_fname); | ||||
| 		} | ||||
| 
 | ||||
| 		struct fs_inode d; | ||||
| 		read_block(read_inode_ptr(res), &d); | ||||
| 
 | ||||
| 		if (d.ftype == SYMLINK) { | ||||
| 			if (i+1 < path_len) { | ||||
| 				symlinks_followed++; | ||||
| 				if (symlinks_followed > FS_MAX_SYMLINK_FOLLOWS) { | ||||
| 					pr_err("too many symlink follows\n"); | ||||
| 					rp->parent_inode_ptr = -1; | ||||
| 					rp->target_inode_ptr = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				char symlink_path[FS_MAX_PATH_LEN+1]; | ||||
| 				int symlink_path_len = read_symlink(res, symlink_path); | ||||
| 
 | ||||
| 				if (symlink_path_len < 0) { | ||||
| 					pr_warn("broken symlink\n"); | ||||
| 					rp->parent_inode_ptr = -1; | ||||
| 					rp->target_inode_ptr = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				if (symlink_path[0] == '/') { | ||||
| 					memmove(&(path[symlink_path_len]), &(path[i+1]), path_len-i-1); | ||||
| 					strcpy(path, &(symlink_path[1])); | ||||
| 					path[symlink_path_len-1] = '/'; | ||||
| 					path_len = symlink_path_len + path_len - i - 1; | ||||
| 					i = -1; | ||||
| 
 | ||||
| 					next_fname_ptr = 0; | ||||
| 					strcpy(current_fname, "/"); | ||||
| 					memset(next_fname, 0, FS_MAX_FNAME_LEN); | ||||
| 				} else { | ||||
| 					memmove(&(path[symlink_path_len+1]), &(path[i+1]), path_len-i-1); | ||||
| 					strcpy(path, symlink_path); | ||||
| 					path[symlink_path_len] = '/'; | ||||
| 					path_len = symlink_path_len + path_len - i; | ||||
| 					i = -1; | ||||
| 
 | ||||
| 					next_fname_ptr = 0; | ||||
| 					strcpy(current_fname, next_fname); | ||||
| 					memset(next_fname, 0, FS_MAX_FNAME_LEN); | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (!(params & FOLLOW_LAST_SYMLINK)) { | ||||
| 					rp->target_inode_ptr = res; | ||||
| 					strcpy(rp->parent_fname, current_fname); | ||||
| 					strcpy(rp->target_fname, next_fname); | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				symlinks_followed++; | ||||
| 				if (symlinks_followed > FS_MAX_SYMLINK_FOLLOWS) { | ||||
| 					pr_err("too many symlink follows\n"); | ||||
| 					rp->parent_inode_ptr = -1; | ||||
| 					rp->target_inode_ptr = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				char symlink_path[FS_MAX_PATH_LEN+1]; | ||||
| 				int symlink_path_len = read_symlink(res, symlink_path); | ||||
| 
 | ||||
| 				if (symlink_path_len < 0) { | ||||
| 					pr_warn("broken symlink\n"); | ||||
| 					rp->parent_inode_ptr = -1; | ||||
| 					rp->target_inode_ptr = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				if (!strcmp(symlink_path, "/")) { | ||||
| 					rp->parent_inode_ptr = 0; | ||||
| 					rp->target_inode_ptr = 0; | ||||
| 					strcpy(rp->parent_fname, "/"); | ||||
| 					strcpy(rp->target_fname, "/"); | ||||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 				if (symlink_path[0] == '/') { | ||||
| 					strcpy(path, &(symlink_path[1])); | ||||
| 					path_len = symlink_path_len - 1; | ||||
| 					i = -1; | ||||
| 
 | ||||
| 					next_fname_ptr = 0; | ||||
| 					strcpy(current_fname, "/"); | ||||
| 					memset(next_fname, 0, FS_MAX_FNAME_LEN); | ||||
| 				} else { | ||||
| 					strcpy(path, symlink_path); | ||||
| 					path_len = symlink_path_len; | ||||
| 					i = -1; | ||||
| 
 | ||||
| 					next_fname_ptr = 0; | ||||
| 					strcpy(current_fname, next_fname); | ||||
| 					memset(next_fname, 0, FS_MAX_FNAME_LEN); | ||||
| 				} | ||||
| 			} | ||||
| 		} else if (d.ftype == REGULAR) { | ||||
| 			if (i+1 < path_len) { | ||||
| 				pr_warn("'%s': regular file not in the end of a path\n", next_fname); | ||||
| 				rp->parent_inode_ptr = -1; | ||||
| 				rp->target_inode_ptr = -1; | ||||
| 				break; | ||||
| 			} else { | ||||
| 				rp->target_inode_ptr = res; | ||||
| 				strcpy(rp->parent_fname, current_fname); | ||||
| 				strcpy(rp->target_fname, next_fname); | ||||
| 			} | ||||
| 		} else if (d.ftype == DIRECTORY) { | ||||
| 			if (i+1 < path_len) { | ||||
| 				pr("Found directory '%s'\n", next_fname); | ||||
| 				current_inode_ptr = res; | ||||
| 				rp->parent_inode_ptr = res; | ||||
| 
 | ||||
| 				next_fname_ptr = 0; | ||||
| 				strcpy(current_fname, next_fname); | ||||
| 				memset(next_fname, 0, FS_MAX_FNAME_LEN); | ||||
| 			} else { | ||||
| 				rp->target_inode_ptr = res; | ||||
| 				strcpy(rp->parent_fname, current_fname); | ||||
| 				strcpy(rp->target_fname, next_fname); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -1721,73 +1631,6 @@ int fs_ln(void *d) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int read_symlink(int symlink_inode_ptr, char *path) | ||||
| { | ||||
| 	struct fs_inode i; | ||||
| 	read_block(read_inode_ptr(symlink_inode_ptr), &i); | ||||
| 
 | ||||
| 	path[0] = '\0'; | ||||
| 	int bytes_read = 0; | ||||
| 
 | ||||
| 	for (int j = 0; j < BLOCK_ADDRESSES_PER_INODE; j++) { | ||||
| 		if (!i.blocks[j]) { | ||||
| 			pr_err("inode size (%d) indicates existing block but it's address is absent in inode, symlink at inode_ptr=%d might be broken\n", | ||||
| 					i.size, symlink_inode_ptr); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		char data[FS_BLOCK_SIZE]; | ||||
| 		read_block(i.blocks[j], data); | ||||
| 
 | ||||
| 		if (i.size - bytes_read < FS_BLOCK_SIZE) { | ||||
| 			memcpy(&(path[bytes_read]), data, i.size - bytes_read); | ||||
| 			bytes_read = i.size; | ||||
| 			path[bytes_read] = '\0'; | ||||
| 		} else { | ||||
| 			memcpy(&(path[bytes_read]), data, FS_BLOCK_SIZE); | ||||
| 			bytes_read += FS_BLOCK_SIZE; | ||||
| 			path[bytes_read] = '\0'; | ||||
| 		} | ||||
| 
 | ||||
| 		if (i.size == bytes_read) | ||||
| 			goto finish_reading; | ||||
| 	} | ||||
| 
 | ||||
| 	for (unsigned int next_ext = i.next_extension; ; ) { | ||||
| 		struct fs_inode_extension ext; | ||||
| 		read_block(next_ext, &ext); | ||||
| 
 | ||||
| 		for (int j = 0; j < BLOCK_ADDRESSES_PER_INODE_EXTENSION; j++) { | ||||
| 			if (!ext.blocks[j]) { | ||||
| 				pr_err("inode size (%d) indicates existing block but it's address is absent in inode extension, symlink at inode_ptr=%d might be broken\n", | ||||
| 						i.size, symlink_inode_ptr); | ||||
| 				return -1; | ||||
| 			} | ||||
| 
 | ||||
| 			char data[FS_BLOCK_SIZE]; | ||||
| 			read_block(ext.blocks[j], data); | ||||
| 
 | ||||
| 			if (i.size - bytes_read < FS_BLOCK_SIZE) { | ||||
| 				memcpy(&(path[bytes_read]), data, i.size - bytes_read); | ||||
| 				bytes_read = i.size; | ||||
| 				path[bytes_read] = '\0'; | ||||
| 			} else { | ||||
| 				memcpy(&(path[bytes_read]), data, FS_BLOCK_SIZE); | ||||
| 				bytes_read += FS_BLOCK_SIZE; | ||||
| 				path[bytes_read] = '\0'; | ||||
| 			} | ||||
| 
 | ||||
| 			if (i.size == bytes_read) | ||||
| 				goto finish_reading; | ||||
| 		} | ||||
| 
 | ||||
| 		next_ext = ext.next_extension; | ||||
| 	} | ||||
| 
 | ||||
| finish_reading: | ||||
| 	return bytes_read; | ||||
| } | ||||
| 
 | ||||
| int fs_symlink(void *d) | ||||
| { | ||||
| 	char *target_path = ((char **) d)[0]; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user