diff --git a/.gitignore b/.gitignore index 021b6dd..dda2bde 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -zerofree-1.0.1.tgz +/zerofree-*.tgz diff --git a/index.html b/index.html index 92e5b0d..2a0b312 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,10 @@ + + Keeping filesystem images sparse @@ -51,79 +56,43 @@ all the free space: The disadvantage of dd in this context is that it destroys any sparseness that exists: free blocks that were originally represented as holes in the image file are replaced with actual blocks containing -zeroes. +zeroes. Also, filling up a live filesystem is probably a bad idea.

As an alternative approach, and as practice in mucking about with ext2 filesystems, I've written a utility which scans the free blocks in an ext2 filesystem and fills any non-zero blocks with zeroes. -(The source, zerofree-1.0.1.tgz, is -available for download.) The zerofree utility is faster -than dd, especially when the filesystem is already partly sparse. -The filesystem to be processed should be unmounted or mounted read-only. +The source, zerofree-1.1.1.tgz, is +available for download.

-Better than either of these would be to have the guest kernel keep the free -blocks empty. My original inspiration was the - -ext2fs privacy (i.e. secure deletion) patch described in a Linux -kernel mailing list thread. I've also made use of a later patch for ext3 -entitled -Secure Deletion Functionality in ext3 -from the linux-fsdevel mailing list. (See also the authors' paper on -Secure Deletion File Systems.) -I've modified the patches to make them more suitable for the present purpose.

-When a filesystem is mounted with the zerofree option (added -by these patches) all the blocks freed when a file is deleted are filled -with zeroes. -Remember, this extra work will hurt disk performance. -Note that the ext3 patch doesn't support data journalling -mode, so deleted metadata isn't zeroed. It also hasn't been tested -as thoroughly as the patch for ext2.

-However, the above techniques are only half the story: the empty free +However, this is only half the story: the empty free blocks still consume space in the underlying filesystem, so something -must to be done to reclaim that space. One approach would be to -implement a system call, like the legendary - -sys_punch, which could be used to write a utility to make any -suitable file sparse. +must to be done to reclaim that space.

-An existing alternative is to use the sparse file handling capabilities +A common suggestion is to use the sparse file handling capabilities of the GNU cp command to take a copy of the filesystem image with cp --sparse=always (though this does require the original and sparse files to exist at the same time, which may be inconvenient).

-As an alternative alternative I've written a utility which can make -any specified files on an ext2 filesystem -sparse, sparsify.c. This doesn't require any -additional disk space to work its magic, but it does require that the -filesystem containing the filesystem image is unmounted, which is just a -different sort of inconvenience. -

-(The usual disclaimers apply: this worked for me -when I tested it but it might destroy your data. Only use it on -disposable filesystems, or have a full backup available. e2fsck -is your friend.) -

-As an example, suppose we have an unmounted filesystem -image, fs.image, in the directory /data, which is the -root of the /dev/hda2 filesystem. We can reclaim deleted -blocks and make it sparse like so: -

-

-   zerofree /data/fs.image
-   umount /data
-   sparsify /dev/hda2 /fs.image
-   mount /data
-
+If your kernel and util-linux are sufficiently modern and you have a supported +filesystem you can use fallocate -d to 'dig holes' in a file. +This makes the file sparse in-place, without using extra disk space.


-Ron Yorston
-29th July 2008 +Ron Yorston
+18th April 2004 (updated 19th February 2018)
+Some obsolete information has been moved to a +separate page.
diff --git a/sources b/sources index 2c5121c..05a7873 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -a8c772fdd134448f25ab4e7e12004595 zerofree-1.0.1.tgz +SHA512 (zerofree-1.1.1.tgz) = 2d7ee57a877bff2491c48054338a26d624ae75c238ac2b0568a75de88b6621c16cc1e7d65500879825d14d8ba44a5173587a061459072769c165bee47c3f9f1c diff --git a/sparsify-opaque-group-desc.patch b/sparsify-opaque-group-desc.patch deleted file mode 100644 index 2db49f9..0000000 --- a/sparsify-opaque-group-desc.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- zerofree-1.0.1.old/sparsify.c 2012-01-16 14:15:53.752724537 +0000 -+++ zerofree-1.0.1/sparsify.c 2012-01-16 14:27:18.546285148 +0000 -@@ -43,8 +43,9 @@ - - if ( i == fs->blocksize && !p->dryrun ) { - ext2fs_unmark_block_bitmap(fs->block_map, *blocknr) ; -- group = ext2fs_group_of_blk(fs, *blocknr); -- fs->group_desc[group].bg_free_blocks_count++; -+ group = ext2fs_group_of_blk2(fs, *blocknr); -+ ext2fs_bg_free_blocks_count_set(fs, group, -+ ext2fs_bg_free_blocks_count(fs, group) + 1); - fs->super->s_free_blocks_count++ ; - /* the inode counts blocks of 512 bytes */ - p->inode->i_blocks -= fs->blocksize / 512 ; diff --git a/sparsify.c b/sparsify.c index fbcd71f..4c52e00 100644 --- a/sparsify.c +++ b/sparsify.c @@ -1,10 +1,10 @@ /* * sparsify - a tool to make files on an ext2 filesystem sparse * - * Copyright (C) 2004 R M Yorston + * Copyright (C) 2004-2012 R M Yorston * * This file may be redistributed under the terms of the GNU General Public - * License. + * License, version 2. */ #include #include @@ -13,181 +13,262 @@ #define USAGE "usage: %s [-n] [-v] filesystem filename ...\n" +/* initially assume pre-ext4 API version */ +#define API 140 + +#if defined(BLOCK_FLAG_READ_ONLY) +#undef API +#define API 141 +#endif + +#if defined(EXT2_FLAG_64BITS) +#undef API +#define API 142 +#endif + struct process_data { - struct ext2_inode *inode ; unsigned char *buf; - int dryrun ; - int changed ; -} ; + int verbose; + int dryrun; + blk_t count; + blk_t blocks; + blk_t total_blocks; + int old_percent; +}; static int process(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt, blk_t ref_block, int ref_offset, void *priv) { - struct process_data *p ; - errcode_t ret ; - int i, group ; + struct process_data *p; + errcode_t errcode; + int i, group; + int ret = 0; - p = (struct process_data *)priv ; + p = (struct process_data *)priv; + p->blocks++; if ( blockcnt >= 0 ) { - ret = io_channel_read_blk(fs->io, *blocknr, 1, p->buf); - if ( ret ) { - return BLOCK_ABORT ; + errcode = io_channel_read_blk(fs->io, *blocknr, 1, p->buf); + if ( errcode ) { + return BLOCK_ABORT; } for ( i=0; i < fs->blocksize; ++i ) { if ( p->buf[i] ) { - break ; + break; } } - if ( i == fs->blocksize && !p->dryrun ) { - ext2fs_unmark_block_bitmap(fs->block_map, *blocknr) ; - group = ext2fs_group_of_blk(fs, *blocknr); - fs->group_desc[group].bg_free_blocks_count++; - fs->super->s_free_blocks_count++ ; - /* the inode counts blocks of 512 bytes */ - p->inode->i_blocks -= fs->blocksize / 512 ; - *blocknr = 0 ; - /* direct blocks need to be zeroed in the inode */ - if ( blockcnt < EXT2_NDIR_BLOCKS ) { - p->inode->i_block[blockcnt] = 0 ; + if ( i == fs->blocksize ) { + p->count++; + + if ( !p->dryrun ) { + ext2fs_unmark_block_bitmap(fs->block_map, *blocknr); + group = ext2fs_group_of_blk(fs, *blocknr); +#if API >= 142 + ext2fs_bg_free_blocks_count_set(fs, group, + ext2fs_bg_free_blocks_count(fs, group)+1); + ext2fs_free_blocks_count_add(fs->super, (blk64_t)1); +#else + fs->group_desc[group].bg_free_blocks_count++; + fs->super->s_free_blocks_count++; +#endif +#if API >= 141 + ext2fs_group_desc_csum_set(fs, group); +#endif + *blocknr = 0; + ret = BLOCK_CHANGED; + } + } + + if ( p->verbose ) { + double percent; + + percent = 100.0 * (double)p->blocks/(double)p->total_blocks; + + if ( (int)(percent*10) != p->old_percent ) { + fprintf(stderr, "\r%4.1f%%", percent); + p->old_percent = (int)(percent*10); } - p->changed = 1 ; - return BLOCK_CHANGED ; } } - return 0 ; + return ret; } int main(int argc, char **argv) { - int verbose = 0 ; - int dryrun = 0 ; - errcode_t ret ; - int flags ; - int superblock = 0 ; - int open_flags = EXT2_FLAG_RW ; - int blocksize = 0 ; - ext2_filsys current_fs = NULL; - struct ext2_inode inode ; - ext2_ino_t root, cwd, inum ; - int i, c ; - struct process_data pdata ; + int verbose = 0; + int dryrun = 0; + errcode_t ret; + int flags; + int superblock = 0; + int open_flags = EXT2_FLAG_RW; + int iter_flags = 0; + int blocksize = 0; + ext2_filsys fs = NULL; + struct ext2_inode inode; + ext2_ino_t root, cwd, inum; + int i, c; + struct process_data pdata; while ( (c=getopt(argc, argv, "nv")) != -1 ) { switch (c) { case 'n' : - dryrun = 1 ; - break ; + dryrun = 1; +#if defined(BLOCK_FLAG_READ_ONLY) + iter_flags |= BLOCK_FLAG_READ_ONLY; +#endif + break; case 'v' : - verbose = 1 ; - break ; + verbose = 1; + break; default : - fprintf(stderr, USAGE, argv[0]) ; - return 1 ; + fprintf(stderr, USAGE, argv[0]); + return 1; } } if ( argc < optind+2 ) { - fprintf(stderr, USAGE, argv[0]) ; - return 1 ; + fprintf(stderr, USAGE, argv[0]); + return 1; } - ret = ext2fs_check_if_mounted(argv[optind], &flags) ; + ret = ext2fs_check_if_mounted(argv[optind], &flags); if ( ret ) { fprintf(stderr, "%s: failed to determine filesystem mount state %s\n", - argv[0], argv[optind]) ; - return 1 ; + argv[0], argv[optind]); + return 1; } if ( flags & EXT2_MF_MOUNTED ) { fprintf(stderr, "%s: filesystem %s is mounted\n", - argv[0], argv[optind]) ; - return 1 ; + argv[0], argv[optind]); + return 1; } ret = ext2fs_open(argv[optind], open_flags, superblock, blocksize, - unix_io_manager, ¤t_fs); + unix_io_manager, &fs); if ( ret ) { fprintf(stderr, "%s: failed to open filesystem %s\n", - argv[0], argv[optind]) ; - return 1 ; + argv[0], argv[optind]); + return 1; } - pdata.buf = (unsigned char *)malloc(current_fs->blocksize) ; + pdata.buf = (unsigned char *)malloc(fs->blocksize); if ( pdata.buf == NULL ) { - fprintf(stderr, "%s: out of memory (surely not?)\n", argv[0]) ; - return 1 ; + fprintf(stderr, "%s: out of memory (surely not?)\n", argv[0]); + return 1; } - ret = ext2fs_read_inode_bitmap(current_fs); + ret = ext2fs_read_inode_bitmap(fs); if ( ret ) { fprintf(stderr, "%s: error while reading inode bitmap\n", argv[0]); - return 1 ; + return 1; } - ret = ext2fs_read_block_bitmap(current_fs); + ret = ext2fs_read_block_bitmap(fs); if ( ret ) { fprintf(stderr, "%s: error while reading block bitmap\n", argv[0]); - return 1 ; + return 1; } - root = cwd = EXT2_ROOT_INO ; + root = cwd = EXT2_ROOT_INO; for ( i=optind+1; isuper->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) + && (inode.i_flags & EXT4_HUGE_FILE_FL) ) { + fprintf(stderr, "%s: unable to process %s, it's huge\n", + argv[0], argv[i]); + continue; + } +#endif + + if ( verbose ) { + printf("processing %s\n", argv[i]); + } + + pdata.verbose = verbose; + pdata.dryrun = dryrun; + pdata.count = pdata.blocks = 0; + pdata.total_blocks = inode.i_blocks/(fs->blocksize >> 9); + pdata.old_percent = 1000; + ret = ext2fs_block_iterate2(fs, inum, iter_flags, NULL, + process, &pdata); if ( ret ) { fprintf(stderr, "%s: failed to process file %s\n", argv[0], - argv[i]) ; - continue ; + argv[i]); + continue; } - if ( pdata.changed ) { - ret = ext2fs_write_inode(current_fs, inum, &inode) ; + if ( pdata.count && !dryrun ) { + ext2fs_mark_bb_dirty(fs); + ext2fs_mark_super_dirty(fs); + + ret = ext2fs_read_inode(fs, inum, &inode); if ( ret ) { - fprintf(stderr, "%s: failed to write inode data %s\n", argv[0], - argv[i]) ; - continue ; + fprintf(stderr, "%s: failed to open inode (%s)\n", argv[0], + argv[i]); + continue; } - ext2fs_mark_bb_dirty(current_fs) ; - ext2fs_mark_super_dirty(current_fs) ; +#if API >= 141 + ret = ext2fs_iblk_sub_blocks(fs, &inode, (blk64_t)pdata.count); + if ( ret ) { + fprintf(stderr, "%s: failed to update block count (%s)\n", + argv[0], argv[i]); + continue; + } +#else + inode.i_blocks -= pdata.count * (fs->blocksize >> 9); +#endif + + ret = ext2fs_write_inode(fs, inum, &inode); + if ( ret ) { + fprintf(stderr, "%s: failed to write inode (%s)\n", + argv[0], argv[i]); + continue; + } + } + + if ( verbose ) { + printf("\r%d/%d/%d %s\n", pdata.count, pdata.blocks, + pdata.total_blocks, argv[i]); } } - ret = ext2fs_close(current_fs) ; + ret = ext2fs_close(fs); if ( ret ) { - fprintf(stderr, "%s: error while closing filesystem\n", argv[0]) ; - return 1 ; + fprintf(stderr, "%s: error while closing filesystem\n", argv[0]); + return 1; } - return 0 ; + return 0; } diff --git a/zerofree.8 b/zerofree.8 index b0be0d2..ee306b5 100644 --- a/zerofree.8 +++ b/zerofree.8 @@ -1,25 +1,36 @@ .TH "ZEROFREE" "8" .SH "NAME" -zerofree \(em zero free blocks from ext2/3 file-systems +zerofree \(em zero free blocks from ext2, ext3 and ext4 file-systems .SH "SYNOPSIS" .PP -\fBzerofree\fR [\fB-n\fP] [\fB-v\fP] \fIfilesystem\fR +\fBzerofree\fR [\fB-n\fP] [\fB-v\fP] [\fB-f fillval\fP] \fIfilesystem\fR .SH "DESCRIPTION" .PP \fBzerofree\fR finds the unallocated, -non-zeroed blocks in an ext2 or ext3 +blocks with non-zero value content in an ext2, ext3 or ext4 \fIfilesystem\fR (e.g. /dev/hda1) and -fills them with zeroes. This is useful if the device on which -this file-system resides is a disk image. In this case, +fills them with zeroes (or another octet of your choice). + + +.PP +Filling unused areas with zeroes is useful if the device on +which this file-system resides is a disk image. In this case, depending on the type of disk image, a secondary utility may be able to reduce the size of the disk image after zerofree has -been run. +been run. + +.PP +Filling unused areas may also be useful with solid-state +drives (SSDs). On some SSDs, filling blocks with ones (0xFF) +is reported to trigger Flash block erasure by the firmware, +possibly giving a write performance increase. + .PP The usual way to achieve the same result (zeroing the unallocated blocks) is to run \fBdd\fR (1) to create a file full of zeroes that takes up the entire free space on the drive, and then delete this file. This has many -disadvantages, which zerofree alleviates: +disadvantages, which zerofree alleviates: .IP " \(bu" 6 it is slow; .IP " \(bu" 6 @@ -27,7 +38,8 @@ it makes the disk image (temporarily) grow to its maximal extent; .IP " \(bu" 6 it (temporarily) uses all free space on the disk, so other -concurrent write actions may fail. +concurrent write actions may fail. + .PP \fIfilesystem\fR has to be unmounted or mounted read-only for \fBzerofree\fR to work. It @@ -36,17 +48,36 @@ will exit with an error message if the remount the root file-system readonly, you can first switch to single user runlevel (\fBtelinit 1\fR) then use \fBmount \-o remount,ro -\fIfilesystem\fR\fR. +\fIfilesystem\fR\fR. + .PP -\fBzerofree\fR has been written to be -run from GNU/Linux systems installed as guest OSes inside a -virtual machine. It may however be useful in other -situations. +\fBzerofree\fR has been written to be run +from GNU/Linux systems installed as guest OSes inside a virtual +machine. In this case, it is typically run from within the guest +system, and a utility is then run from the host system to shrink +disk image (\fBVBoxManage modifyhd \-\-compact\fR, +provided with virtualbox, is able to do that for some disk image +formats). + +.PP +It may however be useful in other situations: for instance +it can be used to make it more difficult to retrieve deleted +data. Beware that securely deleting sensitive data is not in +general an easy task and usually requires writing several times +on the deleted blocks. + .SH "OPTIONS" .IP "\fB-n\fP " 10 Perform a dry run (do not modify the file-system); .IP "\fB-v\fP " 10 -Be verbose. +Be verbose: show the number of blocks modified by +\fBzerofree\fR (or that would be modified, +in case the \fB-n\fP is used), the number of free +blocks and the total number of blocks on the +filesystem; +.IP "\fB-f value\fP " 10 +Specify the octet value to fill empty blocks with (defaults to +0). Argument must be within the range 0 to 255. .SH "SEE ALSO" .PP dd (1). @@ -62,4 +93,4 @@ later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-2. -.\" created by instant / docbook-to-man, Wed 25 Nov 2009, 17:45 +.\" created by instant / docbook-to-man, Thu 31 Dec 2020, 01:06 diff --git a/zerofree.sgml b/zerofree.sgml index e5c43a3..1c40f71 100644 --- a/zerofree.sgml +++ b/zerofree.sgml @@ -9,7 +9,7 @@ Thibaut"> Paumard"> - February 6, 2008"> + April 3rd, 2012"> 8"> <paumard@users.sourceforge.net>"> @@ -44,7 +44,7 @@ &dhpackage; - zero free blocks from ext2/3 file-systems + zero free blocks from ext2, ext3 and ext4 file-systems @@ -54,6 +54,8 @@ + + filesystem @@ -61,14 +63,21 @@ DESCRIPTION &dhpackage; finds the unallocated, - non-zeroed blocks in an ext2 or ext3 + blocks with non-zero value content in an ext2, ext3 or ext4 filesystem (e.g. /dev/hda1) and - fills them with zeroes. This is useful if the device on which - this file-system resides is a disk image. In this case, + fills them with zeroes (or another octet of your choice). + + Filling unused areas with zeroes is useful if the device on + which this file-system resides is a disk image. In this case, depending on the type of disk image, a secondary utility may be able to reduce the size of the disk image after zerofree has been run. + Filling unused areas may also be useful with solid-state + drives (SSDs). On some SSDs, filling blocks with ones (0xFF) + is reported to trigger Flash block erasure by the firmware, + possibly giving a write performance increase. + The usual way to achieve the same result (zeroing the unallocated blocks) is to run dd (1) to create a file full of zeroes that takes up the entire free @@ -94,10 +103,19 @@ mount -o remount,ro filesystem. - &dhpackage; has been written to be - run from GNU/Linux systems installed as guest OSes inside a - virtual machine. It may however be useful in other - situations. + &dhpackage; has been written to be run + from GNU/Linux systems installed as guest OSes inside a virtual + machine. In this case, it is typically run from within the guest + system, and a utility is then run from the host system to shrink + disk image (VBoxManage modifyhd --compact, + provided with virtualbox, is able to do that for some disk image + formats). + + It may however be useful in other situations: for instance + it can be used to make it more difficult to retrieve deleted + data. Beware that securely deleting sensitive data is not in + general an easy task and usually requires writing several times + on the deleted blocks. @@ -115,7 +133,19 @@ - Be verbose. + Be verbose: show the number of blocks modified by + &dhpackage; (or that would be modified, + in case the is used), the number of free + blocks and the total number of blocks on the + filesystem; + + + + + + + Specify the octet value to fill empty blocks with (defaults to + 0). Argument must be within the range 0 to 255. diff --git a/zerofree.spec b/zerofree.spec index c424ecd..45118bc 100644 --- a/zerofree.spec +++ b/zerofree.spec @@ -1,36 +1,26 @@ -Summary: Utility to force unused ext2 inodes and blocks to zero +Summary: Utility to force unused ext2/3/4 inodes and blocks to zero Name: zerofree -Version: 1.0.1 -Release: 11%{?dist} -License: GPL+ -Group: System Environment/Libraries - -Source0: http://intgat.tigress.co.uk/rmy/uml/%{name}-%{version}.tgz -Source1: http://intgat.tigress.co.uk/rmy/uml/sparsify.c -Source2: http://intgat.tigress.co.uk/rmy/uml/index.html - +Version: 1.1.1 +Release: 18%{?dist} +License: GPL-2.0-only +URL: https://frippery.org/uml/ +Source0: https://frippery.org/uml/%{name}-%{version}.tgz +Source1: https://frippery.org/uml/sparsify.c +Source2: https://frippery.org/uml/index.html # zerofree.sgml is the source for the man page from Debian. -# Unfortunately we cannot build this in Fedora because of an apparent -# bug in our DocBook tools. Therefore I also include the generated -# man page (generated on a Debian system from this source). +# Unfortunately we cannot build this in Fedora because we do not have +# docbook-to-man, just docbook2man and db2x_docbook2man. The included +# man page was generated on a Debian system from this source. Source3: zerofree.sgml Source4: zerofree.8 - -# e2fsprogs >= 1.42 prevents you from accessing the block group -# descriptor struct directly. -Patch1: sparsify-opaque-group-desc.patch - -URL: http://intgat.tigress.co.uk/rmy/uml/ - +BuildRequires: gcc +BuildRequires: make BuildRequires: e2fsprogs-devel -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - - %description zerofree is a utility to set unused filesystem inodes and blocks of an -ext2 filesystem to zero. This can improve the compressibility and -privacy of an ext2 filesystem. +ext2/3/4 filesystem to zero. This can improve the compressibility and +privacy of an ext2/3/4 filesystem. This tool was inspired by the ext2fs privacy (i.e. secure deletion) patch described in a Linux kernel mailing list thread. @@ -39,40 +29,124 @@ WARNING: The filesystem to be processed should be unmounted or mounted read-only. The tool tries to check this before running, but you should be careful. - %prep %setup -q -cp -p %{SOURCE1} . -cp -p %{SOURCE2} . -%patch1 -p1 - +cp -p %{SOURCE1} %{SOURCE2} . %build -make CC="gcc $RPM_OPT_FLAGS" -gcc $RPM_OPT_FLAGS sparsify.c -o sparsify -lext2fs - +make CC="%{__cc} $RPM_OPT_FLAGS $RPM_LD_FLAGS" +%{__cc} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o sparsify sparsify.c -lext2fs %install -rm -rf $RPM_BUILD_ROOT - install -D -p -m 755 zerofree $RPM_BUILD_ROOT%{_sbindir}/zerofree install -D -p -m 755 sparsify $RPM_BUILD_ROOT%{_sbindir}/sparsify install -D -p -m 644 %{SOURCE4} $RPM_BUILD_ROOT%{_mandir}/man8/zerofree.8 - %files -%defattr(-,root,root,-) -%doc COPYING index.html +%license COPYING +%doc index.html %{_sbindir}/zerofree %{_sbindir}/sparsify %{_mandir}/man8/zerofree.8* - -%clean -rm -rf $RPM_BUILD_ROOT - - %changelog +* Fri Jul 17 2026 Fedora Release Engineering - 1.1.1-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild + +* Sat Jan 17 2026 Fedora Release Engineering - 1.1.1-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + +* Fri Jul 25 2025 Fedora Release Engineering - 1.1.1-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Sun Jan 19 2025 Fedora Release Engineering - 1.1.1-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Sat Jul 20 2024 Fedora Release Engineering - 1.1.1-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Sat Jan 27 2024 Fedora Release Engineering - 1.1.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Sat Jul 22 2023 Fedora Release Engineering - 1.1.1-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Sat Jan 21 2023 Fedora Release Engineering - 1.1.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Sat Jul 23 2022 Fedora Release Engineering - 1.1.1-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Sat Jan 22 2022 Fedora Release Engineering - 1.1.1-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Fri Jul 23 2021 Fedora Release Engineering - 1.1.1-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Thu Jan 28 2021 Fedora Release Engineering - 1.1.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Wed Jul 29 2020 Fedora Release Engineering - 1.1.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Fri Jan 31 2020 Fedora Release Engineering - 1.1.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Sat Jul 27 2019 Fedora Release Engineering - 1.1.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Sun Feb 03 2019 Fedora Release Engineering - 1.1.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Sat Jul 14 2018 Fedora Release Engineering - 1.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Feb 20 2018 Robert Scheck - 1.1.1-1 +- Upgrade to 1.1.1 + +* Mon Feb 19 2018 Robert Scheck - 1.1.0-1 +- Upgrade to 1.1.0 + +* Fri Feb 09 2018 Fedora Release Engineering - 1.0.3-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 1.0.3-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 1.0.3-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 1.0.3-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Apr 06 2016 Robert Scheck - 1.0.3-6 +- Build with ext4 support for RHEL 5 (#862934, thanks to Mike Swanson) + +* Fri Feb 05 2016 Fedora Release Engineering - 1.0.3-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Fri Jun 19 2015 Fedora Release Engineering - 1.0.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon Aug 18 2014 Fedora Release Engineering - 1.0.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 1.0.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Nov 18 2013 Richard W.M. Jones - 1.0.3-1 +- New upstream version 1.0.3. +- New upstream version of sparsify.c. +- Fix the license. +- Modernize the spec file. +- Remove sparsify patch (equivalent patch has gone upstream). + +* Sun Aug 04 2013 Fedora Release Engineering - 1.0.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Fri Feb 15 2013 Fedora Release Engineering - 1.0.1-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + * Sun Jul 22 2012 Fedora Release Engineering - 1.0.1-11 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild