Here we are: RHEL 4 versions of my zerofree patches. I add these to the kernel spec file at about Patch6000. Ron
--- linux-2.6.9/include/linux/ext2_fs.h.zerofree2 2004-10-18 22:53:21.000000000 +0100 +++ linux-2.6.9/include/linux/ext2_fs.h 2006-08-29 19:49:10.000000000 +0100 @@ -310,6 +310,7 @@ struct ext2_inode { #define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ #define EXT2_MOUNT_NOBH 0x0100 /* No buffer_heads */ #define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ +#define EXT2_MOUNT_ZEROFREE 0x0400 /* Zero freed blocks */ #define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ #define EXT2_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */ --- linux-2.6.9/fs/ext2/balloc.c.zerofree2 2004-10-18 22:53:51.000000000 +0100 +++ linux-2.6.9/fs/ext2/balloc.c 2006-08-29 19:46:35.000000000 +0100 @@ -173,9 +173,28 @@ static void group_release_blocks(struct } } +static void ext2_zero_blocks(struct super_block *sb, unsigned long block, + unsigned long count) +{ + unsigned long i; + struct buffer_head * bh; + + for (i = 0; i < count; i++) { + bh = sb_getblk(sb, block+i); + if (!bh) + continue; + + lock_buffer(bh); + memset(bh->b_data, 0, bh->b_size); + mark_buffer_dirty(bh); + unlock_buffer(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) + unsigned long count, int zero) { struct buffer_head *bitmap_bh = NULL; struct buffer_head * bh2; @@ -200,6 +219,9 @@ void ext2_free_blocks (struct inode * in ext2_debug ("freeing block(s) %lu-%lu\n", block, block + count - 1); + if (test_opt(sb, ZEROFREE) && zero) + ext2_zero_blocks(sb, block, count); + do_more: overflow = 0; block_group = (block - le32_to_cpu(es->s_first_data_block)) / --- linux-2.6.9/fs/ext2/super.c.zerofree2 2006-08-29 19:44:53.000000000 +0100 +++ linux-2.6.9/fs/ext2/super.c 2006-08-29 19:54:05.000000000 +0100 @@ -293,7 +293,7 @@ enum { Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh, - Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, + Opt_zerofree, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_ignore, Opt_err, }; @@ -318,6 +318,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"}, @@ -407,6 +408,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.9/fs/ext2/xattr.c.zerofree2 2006-08-29 19:40:46.000000000 +0100 +++ linux-2.6.9/fs/ext2/xattr.c 2006-08-29 19:55:25.000000000 +0100 @@ -679,7 +679,7 @@ ext2_xattr_set2(struct inode *inode, str new_bh = sb_getblk(sb, block); if (!new_bh) { - ext2_free_blocks(inode, block, 1); + ext2_free_blocks(inode, block, 1, 0); error = -EIO; goto cleanup; } @@ -712,24 +712,25 @@ ext2_xattr_set2(struct inode *inode, str error = 0; if (old_bh && old_bh != new_bh) { + unsigned long block = old_bh->b_blocknr; struct mb_cache_entry *ce; /* * If there was an old block and we are no longer using it, * release the old block. */ - ce = mb_cache_entry_get(ext2_xattr_cache, old_bh->b_bdev, - old_bh->b_blocknr); + ce = mb_cache_entry_get(ext2_xattr_cache, old_bh->b_bdev, block); lock_buffer(old_bh); if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) { /* Free the old block. */ if (ce) mb_cache_entry_free(ce); ea_bdebug(old_bh, "freeing"); - ext2_free_blocks(inode, old_bh->b_blocknr, 1); + unlock_buffer(old_bh); /* We let our caller release old_bh, so we * need to duplicate the buffer before. */ get_bh(old_bh); bforget(old_bh); + ext2_free_blocks(inode, block, 1, 1); } else { /* Decrement the refcount only. */ if (ce) @@ -740,8 +741,8 @@ ext2_xattr_set2(struct inode *inode, str mark_buffer_dirty(old_bh); ea_bdebug(old_bh, "refcount now=%d", le32_to_cpu(HDR(old_bh)->h_refcount)); + unlock_buffer(old_bh); } - unlock_buffer(old_bh); } cleanup: @@ -786,10 +787,10 @@ ext2_xattr_delete_inode(struct inode *in if (HDR(bh)->h_refcount == cpu_to_le32(1)) { if (ce) mb_cache_entry_free(ce); - ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1); + unlock_buffer(bh); get_bh(bh); bforget(bh); - unlock_buffer(bh); + ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1, 1); } else { if (ce) mb_cache_entry_release(ce); --- linux-2.6.9/fs/ext2/inode.c.zerofree2 2006-08-29 19:44:53.000000000 +0100 +++ linux-2.6.9/fs/ext2/inode.c 2006-08-29 19:46:35.000000000 +0100 @@ -99,7 +99,7 @@ void ext2_discard_prealloc (struct inode ei->i_prealloc_count = 0; ei->i_prealloc_block = 0; write_unlock(&ei->i_meta_lock); - ext2_free_blocks (inode, block, total); + ext2_free_blocks (inode, block, total, 0); return; } else write_unlock(&ei->i_meta_lock); @@ -462,7 +462,7 @@ static int ext2_alloc_branch(struct inod for (i = 1; i < n; i++) bforget(branch[i].bh); for (i = 0; i < n; i++) - ext2_free_blocks(inode, le32_to_cpu(branch[i].key), 1); + ext2_free_blocks(inode, le32_to_cpu(branch[i].key), 1, 0); return err; } @@ -522,7 +522,7 @@ changed: for (i = 1; i < num; i++) bforget(where[i].bh); for (i = 0; i < num; i++) - ext2_free_blocks(inode, le32_to_cpu(where[i].key), 1); + ext2_free_blocks(inode, le32_to_cpu(where[i].key), 1, 1); return -EAGAIN; } @@ -821,7 +821,7 @@ static inline void ext2_free_data(struct count++; else { mark_inode_dirty(inode); - ext2_free_blocks (inode, block_to_free, count); + ext2_free_blocks (inode, block_to_free, count, 1); free_this: block_to_free = nr; count = 1; @@ -830,7 +830,7 @@ static inline void ext2_free_data(struct } if (count > 0) { mark_inode_dirty(inode); - ext2_free_blocks (inode, block_to_free, count); + ext2_free_blocks (inode, block_to_free, count, 1); } } @@ -873,7 +873,7 @@ static void ext2_free_branches(struct in (__le32*)bh->b_data + addr_per_block, depth); bforget(bh); - ext2_free_blocks(inode, nr, 1); + ext2_free_blocks(inode, nr, 1, 1); mark_inode_dirty(inode); } } else --- linux-2.6.9/fs/ext2/ext2.h.zerofree2 2006-08-29 19:44:53.000000000 +0100 +++ linux-2.6.9/fs/ext2/ext2.h 2006-08-29 19:46:35.000000000 +0100 @@ -85,7 +85,7 @@ extern unsigned long ext2_bg_num_gdb(str extern int ext2_new_block (struct inode *, unsigned long, __u32 *, __u32 *, int *); extern void ext2_free_blocks (struct inode *, unsigned long, - unsigned long); + unsigned long, int); extern unsigned long ext2_count_free_blocks (struct super_block *); extern unsigned long ext2_count_dirs (struct super_block *); extern void ext2_check_blocks_bitmap (struct super_block *); --- linux-2.6.9/Documentation/filesystems/ext2.txt.zerofree2 2004-10-18 22:53:43.000000000 +0100 +++ linux-2.6.9/Documentation/filesystems/ext2.txt 2006-08-29 19:46:35.000000000 +0100 @@ -62,6 +62,8 @@ resgid=n The group ID which may use th sb=n Use alternate superblock at this location. +zerofree Zero data blocks when they are freed. + grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2.
--- linux-2.6.9/include/linux/ext3_fs.h.zerofree3 2006-08-30 20:44:40.000000000 +0100 +++ linux-2.6.9/include/linux/ext3_fs.h 2006-08-30 20:47:19.000000000 +0100 @@ -355,6 +355,7 @@ struct ext3_inode { #define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ #define EXT3_MOUNT_BARRIER 0x10000 /* Use block barriers */ #define EXT3_MOUNT_RESERVATION 0x20000 /* Preallocation */ +#define EXT3_MOUNT_ZEROFREE 0x40000 /* Zero freed blocks */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H @@ -713,7 +714,7 @@ extern int ext3_bg_has_super(struct supe extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *); extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long, - unsigned long); + unsigned long, int); extern void ext3_free_blocks_sb (handle_t *, struct super_block *, unsigned long, unsigned long, int *); extern unsigned long ext3_count_free_blocks (struct super_block *); --- linux-2.6.9/fs/ext3/super.c.zerofree3 2006-08-30 20:45:30.000000000 +0100 +++ linux-2.6.9/fs/ext3/super.c 2006-08-30 20:47:19.000000000 +0100 @@ -631,7 +631,7 @@ enum { Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, + Opt_zerofree, Opt_ignore, Opt_barrier, Opt_err, Opt_resize, }; static match_table_t tokens = { @@ -674,6 +674,7 @@ static match_table_t tokens = { {Opt_grpjquota, "grpjquota=%s"}, {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, + {Opt_zerofree, "zerofree"}, {Opt_ignore, "grpquota"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, @@ -970,6 +971,9 @@ clear_qf_name: match_int(&args[0], &option); *n_blocks_count = option; break; + case Opt_zerofree: + set_opt(sbi->s_mount_opt, ZEROFREE); + break; default: printk (KERN_ERR "EXT3-fs: Unrecognized mount option \"%s\" " --- linux-2.6.9/fs/ext3/balloc.c.zerofree3 2006-08-30 20:44:40.000000000 +0100 +++ linux-2.6.9/fs/ext3/balloc.c 2006-08-30 20:47:19.000000000 +0100 @@ -451,9 +451,28 @@ error_return: return; } +static void ext3_zero_blocks(struct super_block *sb, unsigned long block, + unsigned long count) +{ + unsigned long i; + struct buffer_head *bh; + + for (i = 0; i < count; i++) { + bh = sb_getblk(sb, block+i); + if (!bh) + continue; + + lock_buffer(bh) ; + memset(bh->b_data, 0, bh->b_size); + mark_buffer_dirty(bh); + unlock_buffer(bh) ; + brelse(bh); + } +} + /* Free given blocks, update quota and i_blocks field */ void ext3_free_blocks(handle_t *handle, struct inode *inode, - unsigned long block, unsigned long count) + unsigned long block, unsigned long count, int zero) { struct super_block * sb; int dquot_freed_blocks; @@ -463,6 +482,8 @@ void ext3_free_blocks(handle_t *handle, printk ("ext3_free_blocks: nonexistent device"); return; } + if (test_opt(sb, ZEROFREE) && zero && !ext3_should_journal_data(inode)) + ext3_zero_blocks(sb, block, count); ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); if (dquot_freed_blocks) DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); --- linux-2.6.9/fs/ext3/inode.c.zerofree3 2006-08-30 20:44:40.000000000 +0100 +++ linux-2.6.9/fs/ext3/inode.c 2006-08-30 20:47:19.000000000 +0100 @@ -571,7 +571,7 @@ static int ext3_alloc_branch(handle_t *h ext3_journal_forget(handle, branch[i].bh); } for (i = 0; i < keys; i++) - ext3_free_blocks(handle, inode, le32_to_cpu(branch[i].key), 1); + ext3_free_blocks(handle, inode, le32_to_cpu(branch[i].key), 1, 0); return err; } @@ -672,7 +672,7 @@ err_out: if (err == -EAGAIN) for (i = 0; i < num; i++) ext3_free_blocks(handle, inode, - le32_to_cpu(where[i].key), 1); + le32_to_cpu(where[i].key), 1, 0); return err; } @@ -1819,7 +1819,7 @@ ext3_clear_blocks(handle_t *handle, stru } } - ext3_free_blocks(handle, inode, block_to_free, count); + ext3_free_blocks(handle, inode, block_to_free, count, 1); } /** @@ -1992,7 +1992,7 @@ static void ext3_free_branches(handle_t ext3_journal_test_restart(handle, inode); } - ext3_free_blocks(handle, inode, nr, 1); + ext3_free_blocks(handle, inode, nr, 1, 0); if (parent_bh) { /* --- linux-2.6.9/fs/ext3/xattr.c.zerofree3 2006-08-30 20:45:00.000000000 +0100 +++ linux-2.6.9/fs/ext3/xattr.c 2006-08-30 20:48:06.000000000 +0100 @@ -699,7 +699,7 @@ ext3_xattr_set_handle2(handle_t *handle, new_bh = sb_getblk(sb, block); if (!new_bh) { getblk_failed: - ext3_free_blocks(handle, inode, block, 1); + ext3_free_blocks(handle, inode, block, 1, 0); error = -EIO; goto cleanup; } @@ -746,7 +746,7 @@ getblk_failed: if (ce) mb_cache_entry_free(ce); ea_bdebug(old_bh, "freeing"); - ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1); + ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1, 0); /* ext3_forget() calls bforget() for us, but we let our caller release old_bh, so we need to @@ -845,7 +845,7 @@ ext3_xattr_delete_inode(handle_t *handle if (HDR(bh)->h_refcount == cpu_to_le32(1)) { if (ce) mb_cache_entry_free(ce); - ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1); + ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1, 0); get_bh(bh); ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl); } else { --- linux-2.6.9/Documentation/filesystems/ext3.txt.zerofree3 2004-10-18 22:53:51.000000000 +0100 +++ linux-2.6.9/Documentation/filesystems/ext3.txt 2006-08-30 20:47:19.000000000 +0100 @@ -108,6 +108,8 @@ noquota (see fs/ext3/super.c, line 594 grpquota usrquota +zerofree Zero data blocks when they are freed. + Specification =============
_______________________________________________ Ext3-users mailing list Ext3-users@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/ext3-users