diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c index 13f00cf7099c..0417d86095ec 100644 --- a/usr.sbin/makefs/ffs.c +++ b/usr.sbin/makefs/ffs.c @@ -493,13 +493,25 @@ ffs_create_image(const char *image, fsinfo_t *fsopts) bufsize = sfs.f_iosize; #endif bufrem = fsopts->size; - if (debug & DEBUG_FS_CREATE_IMAGE) - printf( - "zero-ing image `%s', %lld sectors, using %d byte chunks\n", - image, (long long)bufrem, bufsize); - if ((buf = calloc(1, bufsize)) == NULL) { - warn("Can't create buffer for sector"); - return (-1); + if (fsopts->sparse) { + if (ftruncate(fsopts->fd, bufrem) == -1) { + warn("sparse option disabled.\n"); + fsopts->sparse = 0; + } + } + if (fsopts->sparse) { + /* File truncated at bufrem. Remaining is 0 */ + bufrem = 0; + buf = NULL; + } else { + if (debug & DEBUG_FS_CREATE_IMAGE) + printf("zero-ing image `%s', %lld sectors, " + "using %d byte chunks\n", image, (long long)bufrem, + bufsize); + if ((buf = calloc(1, bufsize)) == NULL) { + warn("Can't create buffer for sector"); + return (-1); + } } while (bufrem > 0) { i = write(fsopts->fd, buf, MIN(bufsize, bufrem)); @@ -511,7 +523,8 @@ ffs_create_image(const char *image, fsinfo_t *fsopts) } bufrem -= i; } - free(buf); + if (buf) + free(buf); /* make the file system */ if (debug & DEBUG_FS_CREATE_IMAGE) diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8 index cc6e38928932..7c5f37332bf0 100644 --- a/usr.sbin/makefs/makefs.8 +++ b/usr.sbin/makefs/makefs.8 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 30, 2012 +.Dd August 22, 2012 .Dt MAKEFS 8 .Os .Sh NAME @@ -43,6 +43,7 @@ .Nd create a file system image from a directory tree or a mtree manifest .Sh SYNOPSIS .Nm +.Op Fl p .Op Fl x .Op Fl B Ar byte-order .Op Fl b Ar free-blocks @@ -188,6 +189,8 @@ Set file system specific options. .Ar fs-options is a comma separated list of options. Valid file system specific options are detailed below. +.It Fl p +Create the image as a sparse file. .It Fl S Ar sector-size Set the file system sector size to .Ar sector-size . diff --git a/usr.sbin/makefs/makefs.c b/usr.sbin/makefs/makefs.c index 623ca8ac4e97..7aebbbbbc510 100644 --- a/usr.sbin/makefs/makefs.c +++ b/usr.sbin/makefs/makefs.c @@ -112,7 +112,7 @@ main(int argc, char *argv[]) start_time.tv_sec = start.tv_sec; start_time.tv_nsec = start.tv_usec * 1000; - while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:o:s:S:t:x")) != -1) { + while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:o:ps:S:t:x")) != -1) { switch (ch) { case 'B': @@ -199,6 +199,9 @@ main(int argc, char *argv[]) } break; } + case 'p': + fsoptions.sparse = 1; + break; case 's': fsoptions.minsize = fsoptions.maxsize = @@ -346,7 +349,7 @@ usage(void) fprintf(stderr, "usage: %s [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]\n" "\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-s image-size]\n" -"\t[-b free-blocks] [-f free-files] [-F mtree-specfile] [-x]\n" +"\t[-b free-blocks] [-f free-files] [-F mtree-specfile] [-x] [-p]\n" "\t[-N userdb-dir] image-file directory | manifest [extra-directory ...]\n", prog); exit(1); diff --git a/usr.sbin/makefs/makefs.h b/usr.sbin/makefs/makefs.h index f6cadeb98c4f..483ccff96141 100644 --- a/usr.sbin/makefs/makefs.h +++ b/usr.sbin/makefs/makefs.h @@ -129,6 +129,7 @@ typedef struct { int freeblockpc; /* free block % */ int needswap; /* non-zero if byte swapping needed */ int sectorsize; /* sector size */ + int sparse; /* sparse image, don't fill it with zeros */ void *fs_specific; /* File system specific additions. */ } fsinfo_t;