diff -NaurbB --ignore-all-space linux-2.6.15.1-orig/fs/ext3/balloc.c linux-2.6.15.1/fs/ext3/balloc.c --- linux-2.6.15.1-orig/fs/ext3/balloc.c 2006-01-15 01:16:02.000000000 -0500 +++ linux-2.6.15.1/fs/ext3/balloc.c 2006-01-22 20:26:34.000000000 -0500 @@ -21,6 +21,7 @@ #include #include "bitmap.h" +#include "secdel.h" /* * balloc.c contains the blocks allocation and deallocation routines @@ -504,6 +505,10 @@ printk ("ext3_free_blocks: nonexistent device"); return; } +#ifdef CONFIG_EXT3_FS_SECDEL + if (EXT3_I(inode)->i_flags & EXT3_SECRM_FL) + ext3_secdel_blocks(handle, inode, block, count); +#endif ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); if (dquot_freed_blocks) DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); diff -NaurbB --ignore-all-space linux-2.6.15.1-orig/fs/ext3/Makefile linux-2.6.15.1/fs/ext3/Makefile --- linux-2.6.15.1-orig/fs/ext3/Makefile 2006-01-15 01:16:02.000000000 -0500 +++ linux-2.6.15.1/fs/ext3/Makefile 2006-01-24 15:35:26.000000000 -0500 @@ -10,3 +10,4 @@ ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o ext3-$(CONFIG_EXT3_FS_SECURITY) += xattr_security.o +ext3-$(CONFIG_EXT3_FS_SECDEL) += secdel.o diff -NaurbB --ignore-all-space linux-2.6.15.1-orig/fs/ext3/namei.c linux-2.6.15.1/fs/ext3/namei.c --- linux-2.6.15.1-orig/fs/ext3/namei.c 2006-01-15 01:16:02.000000000 -0500 +++ linux-2.6.15.1/fs/ext3/namei.c 2006-01-24 16:00:26.000000000 -0500 @@ -40,6 +40,7 @@ #include "namei.h" #include "xattr.h" #include "acl.h" +#include "secdel.h" /* * define how far ahead to read directories while searching them. @@ -2091,6 +2092,12 @@ inode->i_ino, inode->i_nlink); inode->i_nlink = 1; } +#ifdef CONFIG_EXT3_FS_SECDEL + if (EXT3_I(dentry->d_inode)->i_flags & EXT3_SECRM_FL) { + if ((retval = ext3_secdel_dentry(handle, de, bh, dentry))) + goto end_unlink; + } +#endif retval = ext3_delete_entry(handle, dir, de, bh); if (retval) goto end_unlink; diff -NaurbB --ignore-all-space linux-2.6.15.1-orig/fs/Kconfig linux-2.6.15.1/fs/Kconfig --- linux-2.6.15.1-orig/fs/Kconfig 2006-01-15 01:16:02.000000000 -0500 +++ linux-2.6.15.1/fs/Kconfig 2006-01-24 15:16:04.000000000 -0500 @@ -137,6 +137,19 @@ If you are not using a security module that requires using extended attributes for file security labels, say N. +config EXT3_FS_SECDEL + bool "Ext3 Secure Deletion" + depends on EXT3_FS + help + Secure Deletion support allows overwriting of the data and + file names on the disk after a file is deleted to prevent + further unintended recovery. + + To learn more about Secure Deletion visit the Secure Deletion + File Systems website . + + If you don't know what Secure Deletion is, say N + config JBD # CONFIG_JBD could be its own option (even modular), but until there are # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS diff -NaurbB --ignore-all-space linux-2.6.15.1-orig/fs/ext3/secdel.c linux-2.6.15.1/fs/ext3/secdel.c --- linux-2.6.15.1-orig/fs/ext3/secdel.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.15.1/fs/ext3/secdel.c 2006-01-24 14:28:31.000000000 -0500 @@ -0,0 +1,112 @@ +/* linux/fs/ext3/secdel.h + * + * Copyright (C) 2006 Stony Brook University + * + */ +#include + +int ext3_secdel_dentry(handle_t *handle, struct ext3_dir_entry_2 *de, + struct buffer_head *bh, struct dentry *dentry) +{ + int retval = 0; + struct inode *inode; + + inode = dentry->d_inode; + + if (ext3_should_journal_data(inode)) { + jbd_lock_bh_state(bh); + memset(de->name, 0, de->name_len); + jbd_unlock_bh_state(bh); + + if ((retval = ext3_journal_get_write_access(handle, bh))) + goto dentry_out; + if ((retval = ext3_journal_dirty_metadata(handle, bh))) + goto dentry_out; + } else if (ext3_should_order_data(inode)) { + + jbd_lock_bh_state(bh); + memset(de->name, 0, de->name_len); + jbd_unlock_bh_state(bh); + + if ((retval = ext3_journal_dirty_data(handle, bh))) + goto dentry_out; + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + } else { + lock_buffer(bh); + memset(de->name, 0, de->name_len); + unlock_buffer(bh); + + set_buffer_uptodate(bh); + } + retval = ext3_mark_inode_dirty(handle, inode); +dentry_out: + return retval; +} + +int ext3_secdel_blocks(handle_t *handle, struct inode *inode, + unsigned long block, unsigned long count) +{ + int retval; + int i; + struct buffer_head *bh = NULL; + struct super_block *sb; + + retval = 0; + sb = inode->i_sb; + + if (ext3_should_journal_data(inode) || ext3_should_order_data(inode)) + retval = ext3_journal_extend(handle, count); + + if (retval) + goto block_out; + + for (i = block; i < block + count; i++) { + + bh = sb_getblk(sb, i); + + if (ext3_should_journal_data(inode)) { + + jbd_lock_bh_state(bh); + memset( bh->b_data, 0, bh->b_size ); + jbd_unlock_bh_state(bh); + + if ((retval = ext3_journal_get_write_access(handle, bh))) + goto block_out; + if ((retval = ext3_journal_dirty_metadata(handle, bh))) + goto block_out; + + } else if (ext3_should_order_data(inode)) { + + jbd_lock_bh_state(bh); + memset(bh->b_data, 0, bh->b_size); + jbd_unlock_bh_state(bh); + + if ((retval = ext3_journal_dirty_data(handle, bh))) + goto block_out; + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + } else { + + lock_buffer(bh); + memset(bh->b_data, 0, bh->b_size); + unlock_buffer(bh); + + set_buffer_uptodate(bh); + } + retval = ext3_mark_inode_dirty(handle, inode); + if (retval) + goto block_out; + + brelse(bh); + + } + bh = NULL; +block_out: + if (bh) + brelse(bh); + return retval; +} +