Commit 9f40fe54 authored by Tao Ma's avatar Tao Ma Committed by Theodore Ts'o

ext4: let ext4_delete_entry() handle inline data

Signed-off-by: default avatarTao Ma <boyu.mt@taobao.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 05019a9e
......@@ -1510,6 +1510,61 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
return iloc.bh;
}
int ext4_delete_inline_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh,
int *has_inline_data)
{
int err, inline_size;
struct ext4_iloc iloc;
void *inline_start;
err = ext4_get_inode_loc(dir, &iloc);
if (err)
return err;
down_write(&EXT4_I(dir)->xattr_sem);
if (!ext4_has_inline_data(dir)) {
*has_inline_data = 0;
goto out;
}
if ((void *)de_del - ((void *)ext4_raw_inode(&iloc)->i_block) <
EXT4_MIN_INLINE_DATA_SIZE) {
inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
EXT4_INLINE_DOTDOT_SIZE;
inline_size = EXT4_MIN_INLINE_DATA_SIZE -
EXT4_INLINE_DOTDOT_SIZE;
} else {
inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
inline_size = ext4_get_inline_size(dir) -
EXT4_MIN_INLINE_DATA_SIZE;
}
err = ext4_journal_get_write_access(handle, bh);
if (err)
goto out;
err = ext4_generic_delete_entry(handle, dir, de_del, bh,
inline_start, inline_size, 0);
if (err)
goto out;
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
err = ext4_mark_inode_dirty(handle, dir);
if (unlikely(err))
goto out;
ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size);
out:
up_write(&EXT4_I(dir)->xattr_sem);
brelse(iloc.bh);
if (err != -ENOENT)
ext4_std_error(dir->i_sb, err);
return err;
}
int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
{
int ret;
......
......@@ -2158,6 +2158,14 @@ static int ext4_delete_entry(handle_t *handle,
{
int err, csum_size = 0;
if (ext4_has_inline_data(dir)) {
int has_inline_data = 1;
err = ext4_delete_inline_entry(handle, dir, de_del, bh,
&has_inline_data);
if (has_inline_data)
return err;
}
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext4_dir_entry_tail);
......
......@@ -175,6 +175,11 @@ 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);
extern int ext4_delete_inline_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh,
int *has_inline_data);
# else /* CONFIG_EXT4_FS_XATTR */
static inline int
......@@ -368,6 +373,14 @@ ext4_find_inline_entry(struct inode *dir,
{
return NULL;
}
static inline int ext4_delete_inline_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh,
int *has_inline_data)
{
return 0;
}
# endif /* CONFIG_EXT4_FS_XATTR */
#ifdef CONFIG_EXT4_FS_SECURITY
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment