On Wednesday 05 November 2008 03:31:26 Giorgos Keramidas wrote: > On Tue, 4 Nov 2008 23:42:49 +0100, Max Laier <[EMAIL PROTECTED]> wrote: > > Hi again, > > > > On Saturday 01 November 2008 21:14:42 I wrote: > >> a thread on freebsd-stable@ [1] about problems with du(1) and compressed > >> zfs filesystems got me looking for a possible solution. Attached is a > >> diff for du(1) that adds two new options: > >> > >> -A to display the apparent size of the file instead of the used blocks. > >> -B bsize to specify a custom blocksize. In particular one <512byte > >> > >> The GNU du(1) has --apparent-size for -A, but we don't like long > >> options. That's not to say that it couldn't be added for script compat. > >> -B is probably not that interesting, but it can be helpful and came for > >> free. > > > > Attached is an updated patch. This refines the -B option to something > > more useful (and fixes a bug in the original patch). > > > > From the man page: > > > > -B blocksize > > Calculate block counts in blocksize byte blocks. This is > > differ- ent from the -k, -m options or setting BLOCKSIZE and gives an > > estimate of how many space the examined file hierachy would require on a > > filesystem with the given blocksize. Unless in -A mode, blocksize is > > rounded up to the next multiple of 512. > > That looks nice! With a small fix (``how _much_ space'') I like the > idea a lot :) > > The patch fails to apply on a recent /head snapshot of du though: ... > Can you please refresh and repost it?
Hum ... are you sure your snapshot is up to date? I did some style(9) cleanup in r184654/6 that you might not have yet. Anyways ... here is a diff with those revisions included. -- /"\ Best regards, | [EMAIL PROTECTED] \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | [EMAIL PROTECTED] / \ ASCII Ribbon Campaign | Against HTML Mail and News
Index: du.c =================================================================== --- du.c (revision 176561) +++ du.c (working copy) @@ -73,20 +73,21 @@ static int linkchk(FTSENT *); static void usage(void); -void prthumanval(int64_t); -void ignoreadd(const char *); -void ignoreclean(void); -int ignorep(FTSENT *); +static void prthumanval(int64_t); +static void ignoreadd(const char *); +static void ignoreclean(void); +static int ignorep(FTSENT *); -int nodumpflag = 0; +static int nodumpflag = 0; +static int Aflag; +static long blocksize, cblocksize; int main(int argc, char *argv[]) { FTS *fts; FTSENT *p; - off_t savednumber = 0; - long blocksize; + off_t savednumber, curblocks; int ftsoptions; int listall; int depth; @@ -98,79 +99,91 @@ setlocale(LC_ALL, ""); Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag = - lflag = 0; + lflag = Aflag = 0; save = argv; ftsoptions = 0; + savednumber = 0; + cblocksize = DEV_BSIZE; + blocksize = 0; depth = INT_MAX; SLIST_INIT(&ignores); - while ((ch = getopt(argc, argv, "HI:LPasd:chklmnrx")) != -1) + while ((ch = getopt(argc, argv, "AB:HI:LPasd:chklmnrx")) != -1) switch (ch) { - case 'H': - Hflag = 1; - break; - case 'I': - ignoreadd(optarg); - break; - case 'L': - if (Pflag) - usage(); - Lflag = 1; - break; - case 'P': - if (Lflag) - usage(); - Pflag = 1; - break; - case 'a': - aflag = 1; - break; - case 's': - sflag = 1; - break; - case 'd': - dflag = 1; - errno = 0; - depth = atoi(optarg); - if (errno == ERANGE || depth < 0) { - warnx("invalid argument to option d: %s", optarg); - usage(); - } - break; - case 'c': - cflag = 1; - break; - case 'h': - if (setenv("BLOCKSIZE", "512", 1) == -1) - warn( - "setenv: cannot set BLOCKSIZE=512"); - hflag = 1; - break; - case 'k': - hflag = 0; - if (setenv("BLOCKSIZE", "1024", 1) == -1) - warn("setenv: cannot set BLOCKSIZE=1024"); - break; - case 'l': - lflag = 1; - break; - case 'm': - hflag = 0; - if (setenv("BLOCKSIZE", "1048576", 1) == -1) - warn("setenv: cannot set BLOCKSIZE=1048576"); - break; - case 'n': - nodumpflag = 1; - break; - case 'r': /* Compatibility. */ - break; - case 'x': - ftsoptions |= FTS_XDEV; - break; - case '?': - default: + case 'A': + Aflag = 1; + break; + case 'B': + errno = 0; + cblocksize = atoi(optarg); + if (errno == ERANGE || cblocksize < 0) { + warnx("invalid argument to option B: %s", + optarg); usage(); + } + break; + case 'H': + Hflag = 1; + break; + case 'I': + ignoreadd(optarg); + break; + case 'L': + if (Pflag) + usage(); + Lflag = 1; + break; + case 'P': + if (Lflag) + usage(); + Pflag = 1; + break; + case 'a': + aflag = 1; + break; + case 's': + sflag = 1; + break; + case 'd': + dflag = 1; + errno = 0; + depth = atoi(optarg); + if (errno == ERANGE || depth < 0) { + warnx("invalid argument to option d: %s", + optarg); + usage(); + } + break; + case 'c': + cflag = 1; + break; + case 'h': + hflag = 1; + break; + case 'k': + hflag = 0; + blocksize = 1024; + break; + case 'l': + lflag = 1; + break; + case 'm': + hflag = 0; + blocksize = 1048576; + break; + case 'n': + nodumpflag = 1; + break; + case 'r': /* Compatibility. */ + break; + case 'x': + ftsoptions |= FTS_XDEV; + break; + case '?': + default: + usage(); + /* NOTREACHED */ } argc -= optind; @@ -204,6 +217,9 @@ if (Pflag) ftsoptions |= FTS_PHYSICAL; + if (!Aflag && (cblocksize % DEV_BSIZE) != 0) + cblocksize = howmany(cblocksize, DEV_BSIZE) * DEV_BSIZE; + listall = 0; if (aflag) { @@ -222,9 +238,14 @@ argv[1] = NULL; } - (void) getbsize(¬used, &blocksize); - blocksize /= 512; + if (blocksize == 0) + (void)getbsize(¬used, &blocksize); + if (!Aflag) { + cblocksize /= DEV_BSIZE; + blocksize /= DEV_BSIZE; + } + rval = 0; if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL) @@ -232,57 +253,63 @@ while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { - case FTS_D: /* Ignore. */ - if (ignorep(p)) - fts_set(fts, p, FTS_SKIP); + case FTS_D: /* Ignore. */ + if (ignorep(p)) + fts_set(fts, p, FTS_SKIP); + break; + case FTS_DP: + if (ignorep(p)) break; - case FTS_DP: - if (ignorep(p)) - break; - p->fts_parent->fts_bignum += - p->fts_bignum += p->fts_statp->st_blocks; + curblocks = Aflag ? + howmany(p->fts_statp->st_size, cblocksize) : + howmany(p->fts_statp->st_blocks, cblocksize); + p->fts_parent->fts_bignum += p->fts_bignum += + curblocks; - if (p->fts_level <= depth) { - if (hflag) { - (void) prthumanval(howmany(p->fts_bignum, blocksize)); - (void) printf("\t%s\n", p->fts_path); - } else { - (void) printf("%jd\t%s\n", - (intmax_t)howmany(p->fts_bignum, blocksize), - p->fts_path); - } + if (p->fts_level <= depth) { + if (hflag) { + prthumanval(p->fts_bignum); + (void)printf("\t%s\n", p->fts_path); + } else { + (void)printf("%jd\t%s\n", + howmany(p->fts_bignum * cblocksize, + blocksize), p->fts_path); } + } + break; + case FTS_DC: /* Ignore. */ + break; + case FTS_DNR: /* Warn, continue. */ + case FTS_ERR: + case FTS_NS: + warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + rval = 1; + break; + default: + if (ignorep(p)) break; - case FTS_DC: /* Ignore. */ + + if (lflag == 0 && p->fts_statp->st_nlink > 1 && + linkchk(p)) break; - case FTS_DNR: /* Warn, continue. */ - case FTS_ERR: - case FTS_NS: - warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); - rval = 1; - break; - default: - if (ignorep(p)) - break; - if (lflag == 0 && - p->fts_statp->st_nlink > 1 && linkchk(p)) - break; + curblocks = Aflag ? + howmany(p->fts_statp->st_size, cblocksize) : + howmany(p->fts_statp->st_blocks, cblocksize); - if (listall || p->fts_level == 0) { - if (hflag) { - (void) prthumanval(howmany(p->fts_statp->st_blocks, - blocksize)); - (void) printf("\t%s\n", p->fts_path); - } else { - (void) printf("%jd\t%s\n", - (intmax_t)howmany(p->fts_statp->st_blocks, blocksize), - p->fts_path); - } + if (listall || p->fts_level == 0) { + if (hflag) { + prthumanval(curblocks); + (void)printf("\t%s\n", p->fts_path); + } else { + (void)printf("%jd\t%s\n", + howmany(curblocks * cblocksize, + blocksize), p->fts_path); } + } - p->fts_parent->fts_bignum += p->fts_statp->st_blocks; + p->fts_parent->fts_bignum += curblocks; } savednumber = p->fts_parent->fts_bignum; } @@ -292,10 +319,11 @@ if (cflag) { if (hflag) { - (void) prthumanval(howmany(savednumber, blocksize)); - (void) printf("\ttotal\n"); + prthumanval(savednumber); + (void)printf("\ttotal\n"); } else { - (void) printf("%jd\ttotal\n", (intmax_t)howmany(savednumber, blocksize)); + (void)printf("%jd\ttotal\n", (intmax_t)howmany( + savednumber * cblocksize, blocksize)); } } @@ -348,7 +376,8 @@ free_list = le->next; free(le); } - new_buckets = malloc(new_size * sizeof(new_buckets[0])); + new_buckets = malloc(new_size * + sizeof(new_buckets[0])); } if (new_buckets == NULL) { @@ -436,12 +465,14 @@ return (0); } -void +static void prthumanval(int64_t bytes) { char buf[5]; - bytes *= DEV_BSIZE; + bytes *= cblocksize; + if (!Aflag) + bytes *= DEV_BSIZE; humanize_number(buf, sizeof(buf), bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); @@ -453,12 +484,13 @@ usage(void) { (void)fprintf(stderr, - "usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] " - "[-l] [-h | -k | -m] [-n] [-x] [-I mask] [file ...]\n"); + "usage: du [-A] [-H | -L | -P] [-a | -s | -d depth] [-c] " + "[-l] [-h | -k | -m | -B bsize] [-n] [-x] [-I mask] " + "[file ...]\n"); exit(EX_USAGE); } -void +static void ignoreadd(const char *mask) { struct ignentry *ign; @@ -472,7 +504,7 @@ SLIST_INSERT_HEAD(&ignores, ign, next); } -void +static void ignoreclean(void) { struct ignentry *ign; @@ -485,7 +517,7 @@ } } -int +static int ignorep(FTSENT *ent) { struct ignentry *ign; Index: du.1 =================================================================== --- du.1 (revision 184666) +++ du.1 (working copy) @@ -40,11 +40,12 @@ .Nd display disk usage statistics .Sh SYNOPSIS .Nm +.Op Fl A .Op Fl H | L | P .Op Fl a | s | d Ar depth .Op Fl c .Op Fl l -.Op Fl h | k | m +.Op Fl h | k | m | B Ar blocksize .Op Fl n .Op Fl x .Op Fl I Ar mask @@ -60,6 +61,25 @@ .Pp The options are as follows: .Bl -tag -width indent +.It Fl A +Display the apparent size instead of the disk usage. +This can be helpful when operating on compressed volumes or sparse files. +.It Fl B Ar blocksize +Calculate block counts in +.Ar blocksize +byte blocks. +This is different from the +.Fl k, m +options or setting +.Ev BLOCKSIZE +and gives an estimate of how many space the examined file hierachy would +require on a filesystem with the given +.Ar blocksize . +Unless in +.Fl A +mode, +.Ar blocksize +is rounded up to the next multiple of 512. .It Fl H Symbolic links on the command line are followed, symbolic links in file hierarchies are not followed. @@ -136,14 +156,19 @@ If the environment variable .Ev BLOCKSIZE is set, and the -.Fl k -option is not specified, the block counts will be displayed in units of that -size block. +.Fl k, m +or +.Fl h +options are not specified, the block counts will be displayed in units of +that size block. If .Ev BLOCKSIZE is not set, and the -.Fl k -option is not specified, the block counts will be displayed in 512-byte blocks. +.Fl k, m +or +.Fl h +options are not specified, the block counts will be displayed in 512-byte +blocks. .El .Sh SEE ALSO .Xr df 1 ,
_______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"