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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1015,7 +1015,6 @@ static inline int search_dirblock(struct buffer_head *bh,
 | 
			
		|||
			  d_name, offset, res_dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Directory block splitting, compacting
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1198,6 +1197,15 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
 | 
			
		|||
	namelen = d_name->len;
 | 
			
		||||
	if (namelen > EXT4_NAME_LEN)
 | 
			
		||||
		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] == '.') &&
 | 
			
		||||
	    (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,
 | 
			
		||||
				void *dirent, filldir_t filldir,
 | 
			
		||||
				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 */
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
| 
						 | 
				
			
			@ -355,6 +359,15 @@ static inline int ext4_read_inline_dir(struct file *filp,
 | 
			
		|||
{
 | 
			
		||||
	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 */
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_EXT4_FS_SECURITY
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue