Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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,
+46 −26
Original line number Diff line number Diff line
@@ -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,
int ext4_generic_delete_entry(handle_t *handle,
			      struct inode *dir,
			      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;
	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.