This patch zeros out a files directory entry when a file with the EXT4_SECRM_FL attribute flag is deleted. A new flag parameter has been added to the ext4_delete_entry routine, that will force the entry to be zeroed out and flushed to the disk. Signed-off-by: Allison Henderson <achender@xxxxxxxxxxxxxxxxxx> --- v1->v2 Removed new inode parameter in ext4_delete_entry and replaced with a new flag for ext4_delete_entry :100644 100644 38a4d75... 1e50f78... M fs/ext4/ext4.h :100644 100644 b754b77... 9af19f4... M fs/ext4/namei.c fs/ext4/ext4.h | 5 +++++ fs/ext4/namei.c | 52 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 38a4d75..1e50f78 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -529,6 +529,11 @@ struct ext4_new_group_data { #define EXT4_FREE_BLOCKS_ZERO 0x0008 /* + * Flags used by ext4_delete_entry + */ +#define EXT4_DEL_ENTRY_ZERO 0x0001 + +/* * ioctl commands */ #define EXT4_IOC_GETFLAGS FS_IOC_GETFLAGS diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index b754b77..9af19f4 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1643,10 +1643,12 @@ cleanup: static int ext4_delete_entry(handle_t *handle, struct inode *dir, struct ext4_dir_entry_2 *de_del, - struct buffer_head *bh) + struct buffer_head *bh, + int flags) { struct ext4_dir_entry_2 *de, *pde; unsigned int blocksize = dir->i_sb->s_blocksize; + struct ext4_super_block *es = EXT4_SB(dir->i_sb)->s_es; int i, err; i = 0; @@ -1673,10 +1675,34 @@ static int ext4_delete_entry(handle_t *handle, de->inode = 0; dir->i_version++; BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); - err = ext4_handle_dirty_metadata(handle, dir, bh); - if (unlikely(err)) { - ext4_std_error(dir->i_sb, err); - return err; + + /* + * If the secure remove flag is on, zero + * out the entry and write it out to the + * disk + */ + if (flags & EXT4_DEL_ENTRY_ZERO) { + memset(de->name, 0x00, de->name_len); + de->file_type = 0; + + set_buffer_dirty(bh); + sync_dirty_buffer(bh); + if (buffer_req(bh) && !buffer_uptodate(bh)) { + es->s_last_error_block = + cpu_to_le64(bh->b_blocknr); + ext4_error_inode(dir, + __func__, __LINE__, bh->b_blocknr, + "IO error syncing itable block"); + return -EIO; + } + } else { + err = ext4_handle_dirty_metadata(handle, + dir, bh); + + if (unlikely(err)) { + ext4_std_error(dir->i_sb, err); + return err; + } } return 0; } @@ -2162,7 +2188,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) if (!empty_dir(inode)) goto end_rmdir; - retval = ext4_delete_entry(handle, dir, de, bh); + retval = ext4_delete_entry(handle, dir, de, bh, 0); if (retval) goto end_rmdir; if (!EXT4_DIR_LINK_EMPTY(inode)) @@ -2190,7 +2216,7 @@ end_rmdir: static int ext4_unlink(struct inode *dir, struct dentry *dentry) { - int retval; + int retval, del_entry_flags; struct inode *inode; struct buffer_head *bh; struct ext4_dir_entry_2 *de; @@ -2215,6 +2241,8 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) goto end_unlink; inode = dentry->d_inode; + del_entry_flags = EXT4_I(inode)->i_flags & EXT4_SECRM_FL ? + EXT4_DEL_ENTRY_ZERO : 0; retval = -EIO; if (le32_to_cpu(de->inode) != inode->i_ino) @@ -2226,7 +2254,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) inode->i_ino, inode->i_nlink); inode->i_nlink = 1; } - retval = ext4_delete_entry(handle, dir, de, bh); + retval = ext4_delete_entry(handle, dir, de, bh, del_entry_flags); if (retval) goto end_unlink; dir->i_ctime = dir->i_mtime = ext4_current_time(dir); @@ -2404,7 +2432,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode, *new_inode; struct buffer_head *old_bh, *new_bh, *dir_bh; struct ext4_dir_entry_2 *old_de, *new_de; - int retval, force_da_alloc = 0; + int retval, del_entry_flags, force_da_alloc = 0; dquot_initialize(old_dir); dquot_initialize(new_dir); @@ -2503,11 +2531,13 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, /* * ok, that's it */ + del_entry_flags = EXT4_I(old_inode)->i_flags & EXT4_SECRM_FL ? + EXT4_DEL_ENTRY_ZERO : 0; if (le32_to_cpu(old_de->inode) != old_inode->i_ino || old_de->name_len != old_dentry->d_name.len || strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) || (retval = ext4_delete_entry(handle, old_dir, - old_de, old_bh)) == -ENOENT) { + old_de, old_bh, del_entry_flags)) == -ENOENT) { /* old_de could have moved from under us during htree split, so * make sure that we are deleting the right entry. We might * also be pointing to a stale entry in the unused part of @@ -2518,7 +2548,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, old_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de2); if (old_bh2) { retval = ext4_delete_entry(handle, old_dir, - old_de2, old_bh2); + old_de2, old_bh2, del_entry_flags); brelse(old_bh2); } } -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html