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: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
e8e948e780
commit
05019a9e7f
2 changed files with 53 additions and 26 deletions
|
@ -2129,6 +2129,13 @@ extern int search_dir(struct buffer_head *bh,
|
|||
const struct qstr *d_name,
|
||||
unsigned int offset,
|
||||
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 */
|
||||
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,
|
|||
}
|
||||
|
||||
/*
|
||||
* ext4_delete_entry deletes a directory entry by merging it with the
|
||||
* previous entry
|
||||
* ext4_generic_delete_entry deletes a directory entry by merging it
|
||||
* with the previous entry
|
||||
*/
|
||||
static int ext4_delete_entry(handle_t *handle,
|
||||
struct inode *dir,
|
||||
struct ext4_dir_entry_2 *de_del,
|
||||
struct buffer_head *bh)
|
||||
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)
|
||||
{
|
||||
struct ext4_dir_entry_2 *de, *pde;
|
||||
unsigned int blocksize = dir->i_sb->s_blocksize;
|
||||
int csum_size = 0;
|
||||
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);
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
pde = NULL;
|
||||
de = (struct ext4_dir_entry_2 *) bh->b_data;
|
||||
while (i < bh->b_size - csum_size) {
|
||||
de = (struct ext4_dir_entry_2 *)entry_buf;
|
||||
while (i < buf_size - csum_size) {
|
||||
if (ext4_check_dir_entry(dir, NULL, de, bh,
|
||||
bh->b_data, bh->b_size, i))
|
||||
return -EIO;
|
||||
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)
|
||||
pde->rec_len = ext4_rec_len_to_disk(
|
||||
ext4_rec_len_from_disk(pde->rec_len,
|
||||
|
@ -2150,12 +2142,6 @@ static int ext4_delete_entry(handle_t *handle,
|
|||
else
|
||||
de->inode = 0;
|
||||
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;
|
||||
}
|
||||
i += ext4_rec_len_from_disk(de->rec_len, blocksize);
|
||||
|
@ -2165,6 +2151,40 @@ static int ext4_delete_entry(handle_t *handle,
|
|||
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,
|
||||
* since this indicates that nlinks count was previously 1.
|
||||
|
|
Loading…
Reference in a new issue