Signed-off-by: Alexander Holler <holler@xxxxxxxxxxxxx> --- fs/ext4/ext4.h | 2 ++ fs/ext4/mballoc.c | 25 +++++++++++++++++++++++-- fs/ext4/super.c | 12 ++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index c55a1fa..e66507c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1342,6 +1342,8 @@ struct ext4_sb_info { struct ratelimit_state s_err_ratelimit_state; struct ratelimit_state s_warning_ratelimit_state; struct ratelimit_state s_msg_ratelimit_state; + + atomic_t secure_delete; /* delete blocks securely? */ }; static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dbfe15c..f33416f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2756,6 +2756,19 @@ static inline int ext4_issue_discard(struct super_block *sb, return sb_issue_discard(sb, discard_block, count, GFP_NOFS, 0); } +static inline int ext4_issue_zeroout(struct super_block *sb, + ext4_group_t block_group, ext4_grpblk_t cluster, int count) +{ + ext4_fsblk_t discard_block; + + discard_block = (EXT4_C2B(EXT4_SB(sb), cluster) + + ext4_group_first_block_no(sb, block_group)); + count = EXT4_C2B(EXT4_SB(sb), count); + //trace_ext4_discard_blocks(sb, + // (unsigned long long) discard_block, count); + return sb_issue_zeroout(sb, discard_block, count, GFP_NOFS); +} + /* * This function is called by the jbd2 layer once the commit has finished, * so we know we can free the blocks that were released with that commit. @@ -2764,6 +2777,7 @@ static void ext4_free_data_callback(struct super_block *sb, struct ext4_journal_cb_entry *jce, int rc) { + struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_free_data *entry = (struct ext4_free_data *)jce; struct ext4_buddy e4b; struct ext4_group_info *db; @@ -2772,6 +2786,11 @@ static void ext4_free_data_callback(struct super_block *sb, mb_debug(1, "gonna free %u blocks in group %u (0x%p):", entry->efd_count, entry->efd_group, entry); + + // TODO: + // if (atomic_read(&sbi->secure_delete) && secure_trim_available) + // use secure trim + // else if (test_opt(sb, DISCARD)) { err = ext4_issue_discard(sb, entry->efd_group, entry->efd_start_cluster, @@ -2782,8 +2801,10 @@ static void ext4_free_data_callback(struct super_block *sb, " with %d", entry->efd_group, entry->efd_start_cluster, entry->efd_count, err); - } - + } else if (atomic_read(&sbi->secure_delete)) + ext4_issue_zeroout(sb, entry->efd_group, + entry->efd_start_cluster, + entry->efd_count); err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b); /* we expect to find existing buddy because it's pinned */ BUG_ON(err != 0); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2c9e686..f87e3ff 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1100,6 +1100,17 @@ static const struct quotactl_ops ext4_qctl_sysfile_operations = { }; #endif +static void ext4_set_secure_delete(struct super_block *sb, bool secure) +{ + struct ext4_sb_info *sbi = EXT4_SB(sb); + // TODO: will overflow with a very large number of + // concurrent calls of unlinkat_s(). + if (secure) + atomic_inc(&sbi->secure_delete); + else + atomic_dec(&sbi->secure_delete); +} + static const struct super_operations ext4_sops = { .alloc_inode = ext4_alloc_inode, .destroy_inode = ext4_destroy_inode, @@ -1119,6 +1130,7 @@ static const struct super_operations ext4_sops = { .quota_write = ext4_quota_write, #endif .bdev_try_to_free_page = bdev_try_to_free_page, + .set_secure_delete = ext4_set_secure_delete, }; static const struct export_operations ext4_export_ops = { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html