mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ext4: let ext4_find_entry handle inline data
Create a new function ext4_find_inline_entry() to handle the case of inline data. Signed-off-by: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
		
							parent
							
								
									7335cd3b41
								
							
						
					
					
						commit
						e8e948e780
					
				
					 3 changed files with 70 additions and 1 deletions
				
			
		| 
						 | 
					@ -1462,6 +1462,54 @@ int ext4_try_create_inline_dir(handle_t *handle, struct inode *parent,
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct buffer_head *ext4_find_inline_entry(struct inode *dir,
 | 
				
			||||||
 | 
										const struct qstr *d_name,
 | 
				
			||||||
 | 
										struct ext4_dir_entry_2 **res_dir,
 | 
				
			||||||
 | 
										int *has_inline_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						struct ext4_iloc iloc;
 | 
				
			||||||
 | 
						void *inline_start;
 | 
				
			||||||
 | 
						int inline_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ext4_get_inode_loc(dir, &iloc))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						down_read(&EXT4_I(dir)->xattr_sem);
 | 
				
			||||||
 | 
						if (!ext4_has_inline_data(dir)) {
 | 
				
			||||||
 | 
							*has_inline_data = 0;
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
 | 
				
			||||||
 | 
											EXT4_INLINE_DOTDOT_SIZE;
 | 
				
			||||||
 | 
						inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
 | 
				
			||||||
 | 
						ret = search_dir(iloc.bh, inline_start, inline_size,
 | 
				
			||||||
 | 
								 dir, d_name, 0, res_dir);
 | 
				
			||||||
 | 
						if (ret == 1)
 | 
				
			||||||
 | 
							goto out_find;
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ext4_get_inline_size(dir) == EXT4_MIN_INLINE_DATA_SIZE)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
 | 
				
			||||||
 | 
						inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = search_dir(iloc.bh, inline_start, inline_size,
 | 
				
			||||||
 | 
								 dir, d_name, 0, res_dir);
 | 
				
			||||||
 | 
						if (ret == 1)
 | 
				
			||||||
 | 
							goto out_find;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						brelse(iloc.bh);
 | 
				
			||||||
 | 
						iloc.bh = NULL;
 | 
				
			||||||
 | 
					out_find:
 | 
				
			||||||
 | 
						up_read(&EXT4_I(dir)->xattr_sem);
 | 
				
			||||||
 | 
						return iloc.bh;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
 | 
					int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1015,7 +1015,6 @@ static inline int search_dirblock(struct buffer_head *bh,
 | 
				
			||||||
			  d_name, offset, res_dir);
 | 
								  d_name, offset, res_dir);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Directory block splitting, compacting
 | 
					 * Directory block splitting, compacting
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1198,6 +1197,15 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
 | 
				
			||||||
	namelen = d_name->len;
 | 
						namelen = d_name->len;
 | 
				
			||||||
	if (namelen > EXT4_NAME_LEN)
 | 
						if (namelen > EXT4_NAME_LEN)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ext4_has_inline_data(dir)) {
 | 
				
			||||||
 | 
							int has_inline_data = 1;
 | 
				
			||||||
 | 
							ret = ext4_find_inline_entry(dir, d_name, res_dir,
 | 
				
			||||||
 | 
										     &has_inline_data);
 | 
				
			||||||
 | 
							if (has_inline_data)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((namelen <= 2) && (name[0] == '.') &&
 | 
						if ((namelen <= 2) && (name[0] == '.') &&
 | 
				
			||||||
	    (name[1] == '.' || name[1] == '\0')) {
 | 
						    (name[1] == '.' || name[1] == '\0')) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,6 +171,10 @@ extern int ext4_try_create_inline_dir(handle_t *handle,
 | 
				
			||||||
extern int ext4_read_inline_dir(struct file *filp,
 | 
					extern int ext4_read_inline_dir(struct file *filp,
 | 
				
			||||||
				void *dirent, filldir_t filldir,
 | 
									void *dirent, filldir_t filldir,
 | 
				
			||||||
				int *has_inline_data);
 | 
									int *has_inline_data);
 | 
				
			||||||
 | 
					extern struct buffer_head *ext4_find_inline_entry(struct inode *dir,
 | 
				
			||||||
 | 
										const struct qstr *d_name,
 | 
				
			||||||
 | 
										struct ext4_dir_entry_2 **res_dir,
 | 
				
			||||||
 | 
										int *has_inline_data);
 | 
				
			||||||
# else  /* CONFIG_EXT4_FS_XATTR */
 | 
					# else  /* CONFIG_EXT4_FS_XATTR */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int
 | 
					static inline int
 | 
				
			||||||
| 
						 | 
					@ -355,6 +359,15 @@ static inline int ext4_read_inline_dir(struct file *filp,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct buffer_head *
 | 
				
			||||||
 | 
					ext4_find_inline_entry(struct inode *dir,
 | 
				
			||||||
 | 
							       const struct qstr *d_name,
 | 
				
			||||||
 | 
							       struct ext4_dir_entry_2 **res_dir,
 | 
				
			||||||
 | 
							       int *has_inline_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
# endif  /* CONFIG_EXT4_FS_XATTR */
 | 
					# endif  /* CONFIG_EXT4_FS_XATTR */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_EXT4_FS_SECURITY
 | 
					#ifdef CONFIG_EXT4_FS_SECURITY
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue