Whamcloud - gitweb
mke2fs: use lazy inode init on some discard-able devices
authorEric Sandeen <sandeen@redhat.com>
Fri, 20 Aug 2010 21:41:14 +0000 (16:41 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 20 Sep 2010 13:20:25 +0000 (09:20 -0400)
If a device supports discard -and- returns 0s for discarded blocks,
then we can skip the inode table initialization -and- the inode table
zeroing at mkfs time, and skip the lazy init as well since they are
already zeroed out.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
misc/mke2fs.c

index e725cd1..7c337a0 100644 (file)
@@ -85,7 +85,7 @@ int   force;
 int    noaction;
 int    journal_size;
 int    journal_flags;
-int    lazy_itable_init;
+int    lazy_itable_init;       /* use lazy inode table init */
 char   *bad_blocks_filename;
 __u32  fs_stride;
 
@@ -350,7 +350,7 @@ static void progress_close(struct progress_struct *progress)
        fputs(_("done                            \n"), stdout);
 }
 
-static void write_inode_tables(ext2_filsys fs, int lazy_flag)
+static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed)
 {
        errcode_t       retval;
        blk_t           blk;
@@ -377,7 +377,8 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag)
                                 EXT2_INODE_SIZE(fs->super)) +
                                EXT2_BLOCK_SIZE(fs->super) - 1) /
                               EXT2_BLOCK_SIZE(fs->super));
-               } else {
+               }
+               if (!lazy_flag || itable_zeroed) {
                        /* The kernel doesn't need to zero the itable blocks */
                        fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
                        ext2fs_group_desc_csum_set(fs, i);
@@ -1943,7 +1944,14 @@ static int mke2fs_setup_tdb(const char *name, io_manager *io_ptr)
 #define BLKDISCARD     _IO(0x12,119)
 #endif
 
-static void mke2fs_discard_blocks(ext2_filsys fs)
+#ifndef BLKDISCARDZEROES
+#define BLKDISCARDZEROES _IO(0x12,124)
+#endif
+
+/*
+ * Return zero if the discard succeeds, and -1 if the discard fails.
+ */
+static int mke2fs_discard_blocks(ext2_filsys fs)
 {
        int fd;
        int ret;
@@ -1958,10 +1966,6 @@ static void mke2fs_discard_blocks(ext2_filsys fs)
 
        fd = open64(fs->device_name, O_RDWR);
 
-       /*
-        * We don't care about whether the ioctl succeeds; it's only an
-        * optmization for SSDs or sparse storage.
-        */
        if (fd > 0) {
                ret = ioctl(fd, BLKDISCARD, &range);
                if (verbose) {
@@ -1975,9 +1979,26 @@ static void mke2fs_discard_blocks(ext2_filsys fs)
                }
                close(fd);
        }
+       return ret;
+}
+
+static int mke2fs_discard_zeroes_data(ext2_filsys fs)
+{
+       int fd;
+       int ret;
+       int discard_zeroes_data = 0;
+
+       fd = open64(fs->device_name, O_RDWR);
+
+       if (fd > 0) {
+               ioctl(fd, BLKDISCARDZEROES, &discard_zeroes_data);
+               close(fd);
+       }
+       return discard_zeroes_data;
 }
 #else
-#define mke2fs_discard_blocks(fs)
+#define mke2fs_discard_blocks(fs)      1
+#define mke2fs_discard_zeroes_data(fs) 0
 #endif
 
 int main (int argc, char *argv[])
@@ -1991,6 +2012,7 @@ int main (int argc, char *argv[])
        io_manager      io_ptr;
        char            tdb_string[40];
        char            *hash_alg_str;
+       int             itable_zeroed = 0;
 
 #ifdef ENABLE_NLS
        setlocale(LC_MESSAGES, "");
@@ -2025,8 +2047,17 @@ int main (int argc, char *argv[])
        }
 
        /* Can't undo discard ... */
-       if (discard && (io_ptr != undo_io_manager))
-               mke2fs_discard_blocks(fs);
+       if (discard && (io_ptr != undo_io_manager)) {
+               retval = mke2fs_discard_blocks(fs);
+
+               if (!retval && mke2fs_discard_zeroes_data(fs)) {
+                       if (verbose)
+                               printf(_("Discard succeeded and will return 0s "
+                                        " - skipping inode table wipe\n"));
+                       lazy_itable_init = 1;
+                       itable_zeroed = 1;
+               }
+       }
 
        sprintf(tdb_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
                32768 : fs->blocksize * 8);
@@ -2172,7 +2203,7 @@ int main (int argc, char *argv[])
                                _("while zeroing block %u at end of filesystem"),
                                ret_blk);
                }
-               write_inode_tables(fs, lazy_itable_init);
+               write_inode_tables(fs, lazy_itable_init, itable_zeroed);
                create_root_dir(fs);
                create_lost_and_found(fs);
                reserve_inodes(fs);