Whamcloud - gitweb
libext2fs/e2fsck: refactor everyone who writes zero blocks to disk
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 13 Oct 2014 08:31:17 +0000 (04:31 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 13 Oct 2014 08:31:17 +0000 (04:31 -0400)
Convert all call sites that write zero blocks to disk to use
ext2fs_zero_blocks2() since it can use Linux's zero out feature to do
the writes more quickly.  Reclaim the zero buffer at freefs time and
make the write-zeroes fallback use a larger buffer.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/pass3.c
e2fsck/util.c
lib/ext2fs/alloc.c
lib/ext2fs/expanddir.c
lib/ext2fs/freefs.c
lib/ext2fs/mkjournal.c
misc/mke2fs.c
resize/resize2fs.c

index 6ca3a6a..615ad75 100644 (file)
@@ -524,8 +524,6 @@ extern void e2fsck_read_bitmaps(e2fsck_t ctx);
 extern void e2fsck_write_bitmaps(e2fsck_t ctx);
 extern void preenhalt(e2fsck_t ctx);
 extern char *string_copy(e2fsck_t ctx, const char *str, int len);
-extern errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
-                                   blk_t *ret_blk, int *ret_count);
 extern int fs_proc_check(const char *fs_name);
 extern int check_for_modules(const char *fs_name);
 #ifdef RESOURCE_TRACK
index db5273e..af64fd1 100644 (file)
@@ -3511,12 +3511,15 @@ static void new_table_block(e2fsck_t ctx, blk64_t first_block, dgrp_t group,
                                   old_block + i, 1, buf);
                        if (pctx.errcode)
                                fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
-               } else
-                       memset(buf, 0, fs->blocksize);
+                       pctx.blk = (*new_block) + i;
+                       pctx.errcode = io_channel_write_blk64(fs->io, pctx.blk,
+                                                             1, buf);
+               } else {
+                       pctx.blk = (*new_block) + i;
+                       pctx.errcode = ext2fs_zero_blocks2(fs, pctx.blk, 1,
+                                                          NULL, NULL);
+               }
 
-               pctx.blk = (*new_block) + i;
-               pctx.errcode = io_channel_write_blk64(fs->io, pctx.blk,
-                                             1, buf);
                if (pctx.errcode)
                        fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
        }
index f03c7ae..2d94ece 100644 (file)
@@ -809,20 +809,13 @@ static int expand_dir_proc(ext2_filsys fs,
                es->num--;
                retval = ext2fs_write_dir_block4(fs, new_blk, block, 0,
                                                 es->dir);
-       } else {
-               retval = ext2fs_get_mem(fs->blocksize, &block);
-               if (retval) {
-                       es->err = retval;
-                       return BLOCK_ABORT;
-               }
-               memset(block, 0, fs->blocksize);
-               retval = io_channel_write_blk64(fs->io, new_blk, 1, block);
-       }
+               ext2fs_free_mem(&block);
+       } else
+               retval = ext2fs_zero_blocks2(fs, new_blk, 1, NULL, NULL);
        if (retval) {
                es->err = retval;
                return BLOCK_ABORT;
        }
-       ext2fs_free_mem(&block);
        *blocknr = new_blk;
        ext2fs_mark_block_bitmap2(ctx->block_found_map, new_blk);
 
index 8237328..2de45f8 100644 (file)
@@ -608,59 +608,6 @@ int ext2_file_type(unsigned int mode)
        return 0;
 }
 
-#define STRIDE_LENGTH 8
-/*
- * Helper function which zeros out _num_ blocks starting at _blk_.  In
- * case of an error, the details of the error is returned via _ret_blk_
- * and _ret_count_ if they are non-NULL pointers.  Returns 0 on
- * success, and an error code on an error.
- *
- * As a special case, if the first argument is NULL, then it will
- * attempt to free the static zeroizing buffer.  (This is to keep
- * programs that check for memory leaks happy.)
- */
-errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
-                            blk_t *ret_blk, int *ret_count)
-{
-       int             j, count;
-       static char     *buf;
-       errcode_t       retval;
-
-       /* If fs is null, clean up the static buffer and return */
-       if (!fs) {
-               if (buf) {
-                       free(buf);
-                       buf = 0;
-               }
-               return 0;
-       }
-       /* Allocate the zeroizing buffer if necessary */
-       if (!buf) {
-               buf = malloc(fs->blocksize * STRIDE_LENGTH);
-               if (!buf) {
-                       com_err("malloc", ENOMEM, "%s",
-                               _("while allocating zeroizing buffer"));
-                       exit(1);
-               }
-               memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
-       }
-       /* OK, do the write loop */
-       for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
-               count = num - j;
-               if (count > STRIDE_LENGTH)
-                       count = STRIDE_LENGTH;
-               retval = io_channel_write_blk64(fs->io, blk, count, buf);
-               if (retval) {
-                       if (ret_count)
-                               *ret_count = count;
-                       if (ret_blk)
-                               *ret_blk = blk;
-                       return retval;
-               }
-       }
-       return 0;
-}
-
 /*
  * Check to see if a filesystem is in /proc/filesystems.
  * Returns 1 if found, 0 if not
index 578fd7f..54535c4 100644 (file)
@@ -183,15 +183,9 @@ errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
 {
        errcode_t       retval;
        blk64_t         block;
-       char            *buf = 0;
 
-       if (!block_buf) {
-               retval = ext2fs_get_mem(fs->blocksize, &buf);
-               if (retval)
-                       return retval;
-               block_buf = buf;
-       }
-       memset(block_buf, 0, fs->blocksize);
+       if (block_buf)
+               memset(block_buf, 0, fs->blocksize);
 
        if (fs->get_alloc_block) {
                retval = (fs->get_alloc_block)(fs, goal, &block);
@@ -209,7 +203,7 @@ errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
                        goto fail;
        }
 
-       retval = io_channel_write_blk64(fs->io, block, 1, block_buf);
+       retval = ext2fs_zero_blocks2(fs, block, 1, NULL, NULL);
        if (retval)
                goto fail;
 
@@ -217,8 +211,6 @@ errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
        *ret = block;
 
 fail:
-       if (buf)
-               ext2fs_free_mem(&buf);
        return retval;
 }
 
index d0f7287..ecc13ae 100644 (file)
@@ -67,22 +67,15 @@ static int expand_dir_proc(ext2_filsys      fs,
                es->done = 1;
                retval = ext2fs_write_dir_block4(fs, new_blk, block, 0,
                                                 es->dir);
-       } else {
-               retval = ext2fs_get_mem(fs->blocksize, &block);
-               if (retval) {
-                       es->err = retval;
-                       return BLOCK_ABORT;
-               }
-               memset(block, 0, fs->blocksize);
-               retval = io_channel_write_blk64(fs->io, new_blk, 1, block);
-       }
+               ext2fs_free_mem(&block);
+       } else
+               retval = ext2fs_zero_blocks2(fs, new_blk, 1, NULL, NULL);
        if (blockcnt >= 0)
                es->goal = new_blk;
        if (retval) {
                es->err = retval;
                return BLOCK_ABORT;
        }
-       ext2fs_free_mem(&block);
        *blocknr = new_blk;
 
        if (es->done)
index 89a157b..ea9742e 100644 (file)
@@ -61,6 +61,7 @@ void ext2fs_free(ext2_filsys fs)
 
        fs->magic = 0;
 
+       ext2fs_zero_blocks2(NULL, 0, 0, NULL, NULL);
        ext2fs_free_mem(&fs);
 }
 
index 6f3a862..e8f8b30 100644 (file)
@@ -148,7 +148,7 @@ errfree:
  * attempt to free the static zeroizing buffer.  (This is to keep
  * programs that check for memory leaks happy.)
  */
-#define STRIDE_LENGTH 8
+#define STRIDE_LENGTH (4194304 / fs->blocksize)
 errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
                              blk64_t *ret_blk, int *ret_count)
 {
@@ -366,20 +366,20 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
        retval = ext2fs_block_iterate3(fs, journal_ino, BLOCK_FLAG_APPEND,
                                       0, mkjournal_proc, &es);
        if (retval)
-               goto errout;
+               goto out2;
        if (es.err) {
                retval = es.err;
-               goto errout;
+               goto out2;
        }
        if (es.zero_count) {
                retval = ext2fs_zero_blocks2(fs, es.blk_to_zero,
                                            es.zero_count, 0, 0);
                if (retval)
-                       goto errout;
+                       goto out2;
        }
 
        if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
-               goto errout;
+               goto out2;
 
        inode_size = (unsigned long long)fs->blocksize * num_blocks;
        ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
@@ -388,10 +388,10 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
        inode.i_mode = LINUX_S_IFREG | 0600;
        retval = ext2fs_inode_size_set(fs, &inode, inode_size);
        if (retval)
-               goto errout;
+               goto out2;
 
        if ((retval = ext2fs_write_new_inode(fs, journal_ino, &inode)))
-               goto errout;
+               goto out2;
        retval = 0;
 
        memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
@@ -400,8 +400,6 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
        fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
        ext2fs_mark_super_dirty(fs);
 
-errout:
-       ext2fs_zero_blocks2(0, 0, 0, 0, 0);
 out2:
        ext2fs_free_mem(&buf);
        return retval;
index a7bd35a..0f571ad 100644 (file)
@@ -435,7 +435,6 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed)
                                sync();
                }
        }
-       ext2fs_zero_blocks2(0, 0, 0, 0, 0);
        ext2fs_numeric_progress_close(fs, &progress,
                                      _("done                            \n"));
 
@@ -624,7 +623,6 @@ static void create_journal_dev(ext2_filsys fs)
                count -= c;
                ext2fs_numeric_progress_update(fs, &progress, blk);
        }
-       ext2fs_zero_blocks2(0, 0, 0, 0, 0);
 
        ext2fs_numeric_progress_close(fs, &progress, NULL);
 write_superblock:
index b59f482..57fe485 100644 (file)
@@ -758,11 +758,11 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
                /*
                 * Write out the new inode table
                 */
-               retval = io_channel_write_blk64(fs->io,
-                                               ext2fs_inode_table_loc(fs, i),
-                                               fs->inode_blocks_per_group,
-                                               rfs->itable_buf);
-               if (retval) goto errout;
+               retval = ext2fs_zero_blocks2(fs, ext2fs_inode_table_loc(fs, i),
+                                            fs->inode_blocks_per_group, NULL,
+                                            NULL);
+               if (retval)
+                       goto errout;
 
                io_channel_flush(fs->io);
                if (rfs->progress) {
@@ -2186,15 +2186,11 @@ static errcode_t fix_resize_inode(ext2_filsys fs)
 {
        struct ext2_inode       inode;
        errcode_t               retval;
-       char                    *block_buf = NULL;
 
        if (!(fs->super->s_feature_compat &
              EXT2_FEATURE_COMPAT_RESIZE_INODE))
                return 0;
 
-       retval = ext2fs_get_mem(fs->blocksize, &block_buf);
-       if (retval) goto errout;
-
        retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
        if (retval) goto errout;
 
@@ -2214,19 +2210,16 @@ static errcode_t fix_resize_inode(ext2_filsys fs)
                exit(1);
        }
 
-       memset(block_buf, 0, fs->blocksize);
-
-       retval = io_channel_write_blk64(fs->io, inode.i_block[EXT2_DIND_BLOCK],
-                                       1, block_buf);
-       if (retval) goto errout;
+       retval = ext2fs_zero_blocks2(fs, inode.i_block[EXT2_DIND_BLOCK], 1,
+                                    NULL, NULL);
+       if (retval)
+               goto errout;
 
        retval = ext2fs_create_resize_inode(fs);
        if (retval)
                goto errout;
 
 errout:
-       if (block_buf)
-               ext2fs_free_mem(&block_buf);
        return retval;
 }