summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2011-01-24 20:52:00 +0100
committerTheodore Ts'o <tytso@mit.edu>2011-02-20 21:55:33 -0500
commit7d9e31655fca48e9d6c2647ad443124113508b73 (patch)
tree228fb600ba0b95bcd7155791067d7bbba587ca8f
parent214580a339a18b0539b5998d3b47934956a30a1c (diff)
downloade2fsprogs-7d9e31655fca48e9d6c2647ad443124113508b73.tar.gz
mke2fs: Display progress report during the device discard
For some time now we are doing initial discard of the device prior to filesystem creation. However, there is no feedback for the user and hence on some devices with slow TRIM implementation it may appear that mke2fs is stuck. This commit introduce new function mke2fs_discard_device(), which is a wrapper for io_channel_discard(). The discard is done in chunks of 2GB, which seems reasonably well for both slow and fast devices, and discard progress is reported back to the user. I gave up on doing fancy things like align discard according to discard_alignment, checking for discard granularity and computing estimate time. First of all, because it would require either new ioctl to retrieve those information or use of libudev library, none of it seems to be worth it. Regarding discard_granularity, I doubt there is any sane device with discard granularity that big it would affect this. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--misc/mke2fs.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 2978b028..23f8c103 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -72,6 +72,8 @@ extern int optind;
#define ZAP_BOOTBLOCK
#endif
+#define DISCARD_STEP_MB (2048)
+
extern int isatty(int);
extern FILE *fpopen(const char *cmd, const char *mode);
@@ -1997,6 +1999,44 @@ errout:
return retval;
}
+static int mke2fs_discard_device(ext2_filsys fs)
+{
+ struct ext2fs_numeric_progress_struct progress;
+ blk64_t blocks = ext2fs_blocks_count(fs->super);
+ blk64_t count = DISCARD_STEP_MB;
+ blk64_t cur = 0;
+ int retval = 0;
+
+ count *= (1024 * 1024);
+ count /= fs->blocksize;
+
+ ext2fs_numeric_progress_init(fs, &progress,
+ _("Discarding device blocks: "),
+ blocks);
+ while (cur < blocks) {
+ ext2fs_numeric_progress_update(fs, &progress, cur);
+
+ if (cur + count > blocks)
+ count = blocks - cur;
+
+ retval = io_channel_discard(fs->io, cur, count, fs->blocksize);
+ if (retval)
+ break;
+ cur += count;
+ }
+
+ if (retval) {
+ ext2fs_numeric_progress_close(fs, &progress,
+ _("failed - "));
+ if (!quiet)
+ printf("%s\n",error_message(retval));
+ } else
+ ext2fs_numeric_progress_close(fs, &progress,
+ _("done \n"));
+
+ return retval;
+}
+
int main (int argc, char *argv[])
{
errcode_t retval = 0;
@@ -2057,19 +2097,7 @@ int main (int argc, char *argv[])
/* Can't undo discard ... */
if (discard && (io_ptr != undo_io_manager)) {
- blk64_t blocks = ext2fs_blocks_count(fs->super);
- if (verbose)
- printf(_("Calling BLKDISCARD from 0 to %llu... "),
- (unsigned long long) blocks);
- retval = io_channel_discard(fs->io, 0, blocks, fs->blocksize);
- if (verbose) {
- if (retval)
- printf(_("failed (%s)\n"),
- error_message(retval));
- else
- printf(_("succeeded\n"));
- }
-
+ retval = mke2fs_discard_device(fs);
if (!retval && io_channel_discard_zeroes_data(fs->io)) {
if (verbose)
printf(_("Discard succeeded and will return 0s "