Whamcloud - gitweb
libext2fs: use fallocate for creating journals and hugefiles
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 10 Jun 2015 23:57:50 +0000 (19:57 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 10 Jun 2015 23:57:52 +0000 (19:57 -0400)
Use the new fallocate API for creating the journal and the mk_hugefile
feature.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/mkjournal.c
misc/mk_hugefiles.c
tests/t_enable_mcsum_ext3/expect

index abae9c3..80a1021 100644 (file)
@@ -228,89 +228,6 @@ errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
 }
 
 /*
- * Helper function for creating the journal using direct I/O routines
- */
-struct mkjournal_struct {
-       int             num_blocks;
-       int             newblocks;
-       blk64_t         goal;
-       blk64_t         blk_to_zero;
-       int             zero_count;
-       int             flags;
-       char            *buf;
-       errcode_t       err;
-};
-
-static int mkjournal_proc(ext2_filsys  fs,
-                         blk64_t       *blocknr,
-                         e2_blkcnt_t   blockcnt,
-                         blk64_t       ref_block EXT2FS_ATTR((unused)),
-                         int           ref_offset EXT2FS_ATTR((unused)),
-                         void          *priv_data)
-{
-       struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data;
-       blk64_t new_blk;
-       errcode_t       retval;
-
-       if (*blocknr) {
-               es->goal = *blocknr;
-               return 0;
-       }
-       if (blockcnt &&
-           (EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1)))
-               new_blk = es->goal+1;
-       else {
-               es->goal &= ~EXT2FS_CLUSTER_MASK(fs);
-               retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk);
-               if (retval) {
-                       es->err = retval;
-                       return BLOCK_ABORT;
-               }
-               ext2fs_block_alloc_stats2(fs, new_blk, +1);
-               es->newblocks++;
-       }
-       if (blockcnt >= 0)
-               es->num_blocks--;
-
-       retval = 0;
-       if (blockcnt <= 0)
-               retval = io_channel_write_blk64(fs->io, new_blk, 1, es->buf);
-       else if (!(es->flags & EXT2_MKJOURNAL_LAZYINIT)) {
-               if (es->zero_count) {
-                       if ((es->blk_to_zero + es->zero_count == new_blk) &&
-                           (es->zero_count < 1024))
-                               es->zero_count++;
-                       else {
-                               retval = ext2fs_zero_blocks2(fs,
-                                                            es->blk_to_zero,
-                                                            es->zero_count,
-                                                            0, 0);
-                               es->zero_count = 0;
-                       }
-               }
-               if (es->zero_count == 0) {
-                       es->blk_to_zero = new_blk;
-                       es->zero_count = 1;
-               }
-       }
-
-       if (blockcnt == 0)
-               memset(es->buf, 0, fs->blocksize);
-
-       if (retval) {
-               es->err = retval;
-               return BLOCK_ABORT;
-       }
-       *blocknr = es->goal = new_blk;
-
-       if (es->num_blocks == 0)
-               return (BLOCK_CHANGED | BLOCK_ABORT);
-       else
-               return BLOCK_CHANGED;
-
-}
-
-/*
  * Calculate the initial goal block to be roughly at the middle of the
  * filesystem.  Pick a group that has the largest number of free
  * blocks.
@@ -351,7 +268,8 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
        errcode_t               retval;
        struct ext2_inode       inode;
        unsigned long long      inode_size;
-       struct mkjournal_struct es;
+       int                     falloc_flags = EXT2_FALLOCATE_FORCE_INIT;
+       blk64_t                 zblk;
 
        if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
                                                       &buf)))
@@ -368,40 +286,16 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
                goto out2;
        }
 
-       es.num_blocks = num_blocks;
-       es.newblocks = 0;
-       es.buf = buf;
-       es.err = 0;
-       es.flags = flags;
-       es.zero_count = 0;
-       es.goal = (goal != ~0ULL) ? goal : get_midpoint_journal_block(fs);
+       if (goal == ~0ULL)
+               goal = get_midpoint_journal_block(fs);
 
-       if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+       if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)
                inode.i_flags |= EXT4_EXTENTS_FL;
-               if ((retval = ext2fs_write_inode(fs, journal_ino, &inode)))
-                       goto out2;
-       }
 
-       retval = ext2fs_block_iterate3(fs, journal_ino, BLOCK_FLAG_APPEND,
-                                      0, mkjournal_proc, &es);
-       if (retval)
-               goto out2;
-       if (es.err) {
-               retval = es.err;
-               goto out2;
-       }
-       if (es.zero_count) {
-               retval = ext2fs_zero_blocks2(fs, es.blk_to_zero,
-                                           es.zero_count, 0, 0);
-               if (retval)
-                       goto out2;
-       }
-
-       if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
-               goto out2;
+       if (!(flags & EXT2_MKJOURNAL_LAZYINIT))
+               falloc_flags |= EXT2_FALLOCATE_ZERO_BLOCKS;
 
        inode_size = (unsigned long long)fs->blocksize * num_blocks;
-       ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
        inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
        inode.i_links_count = 1;
        inode.i_mode = LINUX_S_IFREG | 0600;
@@ -409,9 +303,21 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
        if (retval)
                goto out2;
 
+       retval = ext2fs_fallocate(fs, falloc_flags, journal_ino,
+                                 &inode, goal, 0, num_blocks);
+       if (retval)
+               goto out2;
+
        if ((retval = ext2fs_write_new_inode(fs, journal_ino, &inode)))
                goto out2;
-       retval = 0;
+
+       retval = ext2fs_bmap2(fs, journal_ino, &inode, NULL, 0, 0, NULL, &zblk);
+       if (retval)
+               goto out2;
+
+       retval = io_channel_write_blk64(fs->io, zblk, 1, buf);
+       if (retval)
+               goto out2;
 
        memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
        fs->super->s_jnl_blocks[15] = inode.i_size_high;
index e42c0b9..7dcebbd 100644 (file)
@@ -258,12 +258,7 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
 
 {
        errcode_t               retval;
-       blk64_t                 lblk, bend = 0;
-       __u64                   size;
-       blk64_t                 left;
-       blk64_t                 count = 0;
        struct ext2_inode       inode;
-       ext2_extent_handle_t    handle;
 
        retval = ext2fs_new_inode(fs, 0, LINUX_S_IFREG, NULL, ino);
        if (retval)
@@ -283,85 +278,20 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
 
        ext2fs_inode_alloc_stats2(fs, *ino, +1, 0);
 
-       retval = ext2fs_extent_open2(fs, *ino, &inode, &handle);
+       if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+                                     EXT3_FEATURE_INCOMPAT_EXTENTS))
+               inode.i_flags |= EXT4_EXTENTS_FL;
+       retval = ext2fs_fallocate(fs,
+                                 EXT2_FALLOCATE_FORCE_INIT |
+                                 EXT2_FALLOCATE_ZERO_BLOCKS,
+                                 *ino, &inode, goal, 0, num);
        if (retval)
                return retval;
-
-       lblk = 0;
-       left = num ? num : 1;
-       while (left) {
-               blk64_t pblk, end;
-               blk64_t n = left;
-
-               retval =  ext2fs_find_first_zero_block_bitmap2(fs->block_map,
-                       goal, ext2fs_blocks_count(fs->super) - 1, &end);
-               if (retval)
-                       goto errout;
-               goal = end;
-
-               retval =  ext2fs_find_first_set_block_bitmap2(fs->block_map, goal,
-                              ext2fs_blocks_count(fs->super) - 1, &bend);
-               if (retval == ENOENT) {
-                       bend = ext2fs_blocks_count(fs->super);
-                       if (num == 0)
-                               left = 0;
-               }
-               if (!num || bend - goal < left)
-                       n = bend - goal;
-               pblk = goal;
-               if (num)
-                       left -= n;
-               goal += n;
-               count += n;
-               ext2fs_block_alloc_stats_range(fs, pblk, n, +1);
-
-               if (zero_hugefile) {
-                       blk64_t ret_blk;
-                       retval = ext2fs_zero_blocks2(fs, pblk, n,
-                                                    &ret_blk, NULL);
-
-                       if (retval)
-                               com_err(program_name, retval,
-                                       _("while zeroing block %llu "
-                                         "for hugefile"), ret_blk);
-               }
-
-               while (n) {
-                       blk64_t l = n;
-                       struct ext2fs_extent newextent;
-
-                       if (l > EXT_INIT_MAX_LEN)
-                               l = EXT_INIT_MAX_LEN;
-
-                       newextent.e_len = l;
-                       newextent.e_pblk = pblk;
-                       newextent.e_lblk = lblk;
-                       newextent.e_flags = 0;
-
-                       retval = ext2fs_extent_insert(handle,
-                                       EXT2_EXTENT_INSERT_AFTER, &newextent);
-                       if (retval)
-                               return retval;
-                       pblk += l;
-                       lblk += l;
-                       n -= l;
-               }
-       }
-
-       retval = ext2fs_read_inode(fs, *ino, &inode);
-       if (retval)
-               goto errout;
-
-       retval = ext2fs_iblk_add_blocks(fs, &inode,
-                                       count / EXT2FS_CLUSTER_RATIO(fs));
-       if (retval)
-               goto errout;
-       size = (__u64) count * fs->blocksize;
-       retval = ext2fs_inode_size_set(fs, &inode, size);
+       retval = ext2fs_inode_size_set(fs, &inode, num * fs->blocksize);
        if (retval)
-               goto errout;
+               return retval;
 
-       retval = ext2fs_write_new_inode(fs, *ino, &inode);
+       retval = ext2fs_write_inode(fs, *ino, &inode);
        if (retval)
                goto errout;
 
@@ -379,13 +309,7 @@ retry:
                goto retry;
        }
 
-       if (retval)
-               goto errout;
-
 errout:
-       if (handle)
-               ext2fs_extent_free(handle);
-
        return retval;
 }
 
@@ -572,6 +496,8 @@ errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name)
                        printf(_("with %llu blocks each"), num_blocks);
                fputs(": ", stdout);
        }
+       if (num_blocks == 0)
+               num_blocks = ext2fs_blocks_count(fs->super) - goal;
        for (i=0; i < num_files; i++) {
                ext2_ino_t ino;
 
index 5460482..0f761a9 100644 (file)
@@ -49,8 +49,8 @@ Change in FS metadata:
    Reserved GDT blocks at 4-259
    Block bitmap at 260 (+259)
 @@ -45,7 +46,7 @@
-   7789 free blocks, 1013 free inodes, 2 directories
-   Free blocks: 404-8192
+   0 free blocks, 1013 free inodes, 2 directories
+   Free blocks: 
    Free inodes: 12-1024
 -Group 1: (Blocks 8193-16384)
 +Group 1: (Blocks 8193-16384) [ITABLE_ZEROED]
@@ -58,8 +58,8 @@ Change in FS metadata:
    Reserved GDT blocks at 8196-8451
    Block bitmap at 8452 (+259)
 @@ -54,6 +55,6 @@
-   7803 free blocks, 1024 free inodes, 0 directories
-   Free blocks: 8582-16384
+   0 free blocks, 1024 free inodes, 0 directories
+   Free blocks: 
    Free inodes: 1025-2048
 -Group 2: (Blocks 16385-24576)
 +Group 2: (Blocks 16385-24576) [ITABLE_ZEROED]