[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Zeroing freed blocks



A couple of years ago there was a discussion on lkml under the thread
'PATCH - ext2fs privacy (i.e. secure deletion) patch' about zapping
deleted data in the filesystem as a security mechanism.  The discussion
wandered off into how 'chattr +s' could be implemented and whether
encrypting filesystems wouldn't be a better solution to the problem.

I've been maintaining a simplified version of the patch for a different
reason:  to keep filesystems in files sparse.  Filesystem images for use
by things like user-mode Linux and Xen are often created as sparse files.
After they've been in use for a while their sparseness is reduced even
though they may have lots of free space.  Having the guest kernel fill
deleted blocks with zeros doesn't make the underlying file sparse,
but it does help.  I've got a page with more details:

   http://intgat.tigress.co.uk/rmy/uml/sparsify.html

Anyway, a couple of things:

1. The patch (see below) is pretty simple.  I've been using it for some
   time in UML build systems for old versions of software (rh62, anyone?),
   and today I even tried it for several seconds in a Xen domU kernel.
   It seems to do what I want, but is it any good?

2. The patch is now for ext2 only, the original ext3 version having 
   succumbed to bitrot.  What would it take to implement something
   similar for ext3 these days?

Ron

--- linux-2.6.16/Documentation/filesystems/ext2.txt.zerofree	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/Documentation/filesystems/ext2.txt	2006-04-02 09:21:52.000000000 +0100
@@ -58,6 +58,8 @@ nobh				Do not attach buffer_heads to fi
 
 xip				Use execute in place (no caching) if possible
 
+zerofree			Zero data blocks when they are freed.
+
 grpquota,noquota,quota,usrquota	Quota options are silently ignored by ext2.
 
 
--- linux-2.6.16/fs/ext2/balloc.c.zerofree	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/fs/ext2/balloc.c	2006-04-02 09:21:52.000000000 +0100
@@ -174,6 +174,16 @@ static void group_release_blocks(struct 
 	}
 }
 
+static inline void zero_block(struct super_block *sb, unsigned long block)
+{
+	struct buffer_head * bh;
+
+	bh = sb_getblk(sb, block);
+	memset(bh->b_data, 0, bh->b_size);
+	mark_buffer_dirty(bh);
+	brelse(bh);
+}
+
 /* Free given blocks, update quota and i_blocks field */
 void ext2_free_blocks (struct inode * inode, unsigned long block,
 		       unsigned long count)
@@ -242,6 +252,9 @@ do_more:
 				"bit already cleared for block %lu", block + i);
 		} else {
 			group_freed++;
+			if ( test_opt(sb, ZEROFREE) ) {
+				zero_block(sb, block+i);
+			}
 		}
 	}
 
--- linux-2.6.16/fs/ext2/super.c.zerofree	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/fs/ext2/super.c	2006-04-02 09:21:52.000000000 +0100
@@ -289,7 +289,7 @@ enum {
 	Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
 	Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
 	Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
-	Opt_usrquota, Opt_grpquota
+	Opt_usrquota, Opt_grpquota, Opt_zerofree
 };
 
 static match_table_t tokens = {
@@ -312,6 +312,7 @@ static match_table_t tokens = {
 	{Opt_oldalloc, "oldalloc"},
 	{Opt_orlov, "orlov"},
 	{Opt_nobh, "nobh"},
+	{Opt_zerofree, "zerofree"},
 	{Opt_user_xattr, "user_xattr"},
 	{Opt_nouser_xattr, "nouser_xattr"},
 	{Opt_acl, "acl"},
@@ -395,6 +396,9 @@ static int parse_options (char * options
 		case Opt_nobh:
 			set_opt (sbi->s_mount_opt, NOBH);
 			break;
+		case Opt_zerofree:
+			set_opt (sbi->s_mount_opt, ZEROFREE);
+			break;
 #ifdef CONFIG_EXT2_FS_XATTR
 		case Opt_user_xattr:
 			set_opt (sbi->s_mount_opt, XATTR_USER);
--- linux-2.6.16/include/linux/ext2_fs.h.zerofree	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/include/linux/ext2_fs.h	2006-04-02 09:21:52.000000000 +0100
@@ -310,6 +310,7 @@ struct ext2_inode {
 #define EXT2_MOUNT_MINIX_DF		0x000080  /* Mimics the Minix statfs */
 #define EXT2_MOUNT_NOBH			0x000100  /* No buffer_heads */
 #define EXT2_MOUNT_NO_UID32		0x000200  /* Disable 32-bit UIDs */
+#define EXT2_MOUNT_ZEROFREE		0x000400  /* Zero freed blocks */
 #define EXT2_MOUNT_XATTR_USER		0x004000  /* Extended user attributes */
 #define EXT2_MOUNT_POSIX_ACL		0x008000  /* POSIX Access Control Lists */
 #define EXT2_MOUNT_XIP			0x010000  /* Execute in place */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]