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_PATH_LEN 512 | ||||||
| #define FS_MAX_OPEN_FD 32 | #define FS_MAX_OPEN_FD 32 | ||||||
| #define FS_MAX_FNAME_LEN 11 | #define FS_MAX_FNAME_LEN 11 | ||||||
| #define FS_MAX_DIRECTORY_DEPTH 2048 | #define FS_MAX_DIRECTORY_DEPTH 512 | ||||||
| #define FS_MAX_SYMLINK_FOLLOWS 1024 | #define FS_MAX_SYMLINK_FOLLOWING_DEPTH 1024 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #endif | #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 struct fs_file_description fs_file_descriptions[FS_MAX_OPEN_FD]; | ||||||
| 
 | 
 | ||||||
| static int extract_basename(char *path, char *name); | 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) | static int read_block(unsigned int block_no, void *data) | ||||||
| @ -908,21 +907,18 @@ fs_remove_fname_from_directory_finish: | |||||||
| 	return 0; | 	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->parent_inode_ptr = -1; | ||||||
| 	rp->target_inode_ptr = -1; | 	rp->target_inode_ptr = -1; | ||||||
| 
 | 
 | ||||||
| 	int path_len = strlen(original_path); | 	int path_len = strlen(path); | ||||||
| 
 | 
 | ||||||
| 	if (!path_len) { | 	if (!path_len) { | ||||||
| 		pr_err("no path specified\n"); | 		pr_err("no path specified\n"); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	char path[FS_MAX_PATH_LEN+1]; |  | ||||||
| 	strcpy(path, original_path); |  | ||||||
| 
 |  | ||||||
| 	if (!strcmp(path, "/")) { | 	if (!strcmp(path, "/")) { | ||||||
| 		rp->parent_inode_ptr = 0; | 		rp->parent_inode_ptr = 0; | ||||||
| 		rp->target_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 current_inode_ptr; | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| 	unsigned int symlinks_followed = 0; |  | ||||||
| 
 |  | ||||||
| 	if (path[0] == '/') { | 	if (path[0] == '/') { | ||||||
| 		current_inode_ptr = 0; | 		current_inode_ptr = 0; | ||||||
| 		rp->parent_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] != '/') { | 		if (path[i] != '/') { | ||||||
| 			next_fname[next_fname_ptr] = path[i]; | 			next_fname[next_fname_ptr] = path[i]; | ||||||
| 			next_fname_ptr++; | 			next_fname_ptr++; | ||||||
|  | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((path[i] != '/') && (i+1 < path_len)) | 		// path[i] == '/', trying to change current directory
 | ||||||
| 			continue; |  | ||||||
| 
 | 
 | ||||||
| 		if (!next_fname_ptr) | 		if (!next_fname_ptr) | ||||||
| 			continue; | 			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); | 		int res = find_fname_in_directory(current_inode_ptr, next_fname); | ||||||
| 		if (res < 0) { | 		if (res < 0) { | ||||||
| 			if (i+1 < path_len) { | 			pr_warn("target fname '%s' does not exist\n", next_fname); | ||||||
| 				pr_warn("parent '%s' does not exist\n", next_fname); |  | ||||||
| 				rp->parent_inode_ptr = -1; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			rp->target_inode_ptr = -1; | 			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; | 	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) | int fs_symlink(void *d) | ||||||
| { | { | ||||||
| 	char *target_path = ((char **) d)[0]; | 	char *target_path = ((char **) d)[0]; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user