Commit 05019a9e authored by Tao Ma's avatar Tao Ma Committed by Theodore Ts'o

ext4: make ext4_delete_entry generic

Currently ext4_delete_entry() is used only for dir entry removing from
a dir block.  So let us create a new function
ext4_generic_delete_entry and this function takes a entry_buf and a
buf_size so that it can be used for inline data.
Signed-off-by: default avatarTao Ma <boyu.mt@taobao.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent e8e948e7
...@@ -2129,6 +2129,13 @@ extern int search_dir(struct buffer_head *bh, ...@@ -2129,6 +2129,13 @@ extern int search_dir(struct buffer_head *bh,
const struct qstr *d_name, const struct qstr *d_name,
unsigned int offset, unsigned int offset,
struct ext4_dir_entry_2 **res_dir); struct ext4_dir_entry_2 **res_dir);
extern int ext4_generic_delete_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh,
void *entry_buf,
int buf_size,
int csum_size);
/* resize.c */ /* resize.c */
extern int ext4_group_add(struct super_block *sb, extern int ext4_group_add(struct super_block *sb,
......
...@@ -2109,37 +2109,29 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, ...@@ -2109,37 +2109,29 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
} }
/* /*
* ext4_delete_entry deletes a directory entry by merging it with the * ext4_generic_delete_entry deletes a directory entry by merging it
* previous entry * with the previous entry
*/ */
static int ext4_delete_entry(handle_t *handle, int ext4_generic_delete_entry(handle_t *handle,
struct inode *dir, struct inode *dir,
struct ext4_dir_entry_2 *de_del, struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh) struct buffer_head *bh,
void *entry_buf,
int buf_size,
int csum_size)
{ {
struct ext4_dir_entry_2 *de, *pde; struct ext4_dir_entry_2 *de, *pde;
unsigned int blocksize = dir->i_sb->s_blocksize; unsigned int blocksize = dir->i_sb->s_blocksize;
int csum_size = 0; int i;
int i, err;
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext4_dir_entry_tail);
i = 0; i = 0;
pde = NULL; pde = NULL;
de = (struct ext4_dir_entry_2 *) bh->b_data; de = (struct ext4_dir_entry_2 *)entry_buf;
while (i < bh->b_size - csum_size) { while (i < buf_size - csum_size) {
if (ext4_check_dir_entry(dir, NULL, de, bh, if (ext4_check_dir_entry(dir, NULL, de, bh,
bh->b_data, bh->b_size, i)) bh->b_data, bh->b_size, i))
return -EIO; return -EIO;
if (de == de_del) { if (de == de_del) {
BUFFER_TRACE(bh, "get_write_access");
err = ext4_journal_get_write_access(handle, bh);
if (unlikely(err)) {
ext4_std_error(dir->i_sb, err);
return err;
}
if (pde) if (pde)
pde->rec_len = ext4_rec_len_to_disk( pde->rec_len = ext4_rec_len_to_disk(
ext4_rec_len_from_disk(pde->rec_len, ext4_rec_len_from_disk(pde->rec_len,
...@@ -2150,12 +2142,6 @@ static int ext4_delete_entry(handle_t *handle, ...@@ -2150,12 +2142,6 @@ static int ext4_delete_entry(handle_t *handle,
else else
de->inode = 0; de->inode = 0;
dir->i_version++; dir->i_version++;
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_dirent_node(handle, dir, bh);
if (unlikely(err)) {
ext4_std_error(dir->i_sb, err);
return err;
}
return 0; return 0;
} }
i += ext4_rec_len_from_disk(de->rec_len, blocksize); i += ext4_rec_len_from_disk(de->rec_len, blocksize);
...@@ -2165,6 +2151,40 @@ static int ext4_delete_entry(handle_t *handle, ...@@ -2165,6 +2151,40 @@ static int ext4_delete_entry(handle_t *handle,
return -ENOENT; return -ENOENT;
} }
static int ext4_delete_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
{
int err, csum_size = 0;
if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext4_dir_entry_tail);
BUFFER_TRACE(bh, "get_write_access");
err = ext4_journal_get_write_access(handle, bh);
if (unlikely(err))
goto out;
err = ext4_generic_delete_entry(handle, dir, de_del,
bh, bh->b_data,
dir->i_sb->s_blocksize, csum_size);
if (err)
goto out;
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_dirent_node(handle, dir, bh);
if (unlikely(err))
goto out;
return 0;
out:
if (err != -ENOENT)
ext4_std_error(dir->i_sb, err);
return err;
}
/* /*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2, * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1. * since this indicates that nlinks count was previously 1.
......
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