du -A / -B options [Re: zfs quota question]
Max Laier
max at love2party.net
Sat Nov 1 13:14:47 PDT 2008
Hi,
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.
Any objections against the general concept? It's rather complicated to get
the apparent size of a directory hierarchy without scripting. I often wonder
if some hierarchy will fit on a CD/DVD and compressed zfs makes this really
difficult.
As for the code, I know that there are a couple of style(9) errors in there -
mostly because the lines already exceeded 80 chars before my changes and I
plan to clean that up before I commit - should there be enough support for the
change itself.
Thoughts?
[1] http://lists.freebsd.org/pipermail/freebsd-stable/2008-October/045698.html
--
/"\ Best regards, | mlaier at freebsd.org
\ / Max Laier | ICQ #67774661
X http://pf4freebsd.love2party.net/ | mlaier at EFnet
/ \ ASCII Ribbon Campaign | Against HTML Mail and News
-------------- next part --------------
Index: du.1
===================================================================
--- du.1 (revision 184513)
+++ 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,14 @@
.Pp
The options are as follows:
.Bl -tag -width indent
+.It Fl A
+Display the apparent size instead of the diskusage.
+This can be helpful to find sparse files and when operating on
+compressed volumes.
+.It Fl B Ar blocksize
+Display block counts in
+.Ar blocksize
+byte blocks.
.It Fl H
Symbolic links on the command line are followed, symbolic links in file
hierarchies are not followed.
@@ -136,14 +145,14 @@
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
+.Fl k, m, h, B
+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, h, B
+options are not specified, the block counts will be displayed in 512-byte blocks.
.El
.Sh SEE ALSO
.Xr df 1 ,
Index: du.c
===================================================================
--- du.c (revision 184513)
+++ du.c (working copy)
@@ -86,27 +86,39 @@
FTS *fts;
FTSENT *p;
off_t savednumber = 0;
- long blocksize;
+ long blocksize = 0;
int ftsoptions;
int listall;
int depth;
int Hflag, Lflag, Pflag, aflag, sflag, dflag, cflag;
- int hflag, lflag, ch, notused, rval;
+ int Aflag, hflag, lflag, ch, notused, rval;
char **save;
static char dot[] = ".";
setlocale(LC_ALL, "");
Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag =
- lflag = 0;
+ Aflag = lflag = 0;
save = argv;
ftsoptions = 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 'A':
+ Aflag = 1;
+ if (blocksize == 0)
+ blocksize = 1;
+ break;
+ case 'B':
+ blocksize = atoi(optarg);
+ if (errno == ERANGE || blocksize < 0) {
+ warnx("invalid argument to option B: %s", optarg);
+ usage();
+ }
+ break;
case 'H':
Hflag = 1;
break;
@@ -142,23 +154,18 @@
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");
+ blocksize = 1024;
break;
case 'l':
lflag = 1;
break;
case 'm':
hflag = 0;
- if (setenv("BLOCKSIZE", "1048576", 1) == -1)
- warn("setenv: cannot set BLOCKSIZE=1048576");
+ blocksize = 1048576;
break;
case 'n':
nodumpflag = 1;
@@ -222,8 +229,8 @@
argv[1] = NULL;
}
- (void) getbsize(¬used, &blocksize);
- blocksize /= 512;
+ if (blocksize == 0)
+ (void) getbsize(¬used, &blocksize);
rval = 0;
@@ -241,15 +248,21 @@
break;
p->fts_parent->fts_bignum +=
- p->fts_bignum += p->fts_statp->st_blocks;
+ p->fts_bignum += Aflag ?
+ p->fts_statp->st_size :
+ p->fts_statp->st_blocks;
if (p->fts_level <= depth) {
if (hflag) {
- (void) prthumanval(howmany(p->fts_bignum, blocksize));
+ (void) prthumanval(Aflag ?
+ p->fts_bignum :
+ p->fts_bignum * DEV_BSIZE);
(void) printf("\t%s\n", p->fts_path);
} else {
(void) printf("%jd\t%s\n",
- (intmax_t)howmany(p->fts_bignum, blocksize),
+ (intmax_t)howmany(Aflag ?
+ p->fts_bignum :
+ p->fts_bignum * DEV_BSIZE, blocksize),
p->fts_path);
}
}
@@ -272,17 +285,23 @@
if (listall || p->fts_level == 0) {
if (hflag) {
- (void) prthumanval(howmany(p->fts_statp->st_blocks,
- blocksize));
+ (void) prthumanval(Aflag ?
+ p->fts_statp->st_size :
+ p->fts_statp->st_blocks * DEV_BSIZE);
(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);
+ (intmax_t)howmany( Aflag ?
+ p->fts_statp->st_size :
+ p->fts_statp->st_blocks *
+ DEV_BSIZE, blocksize),
+ p->fts_path);
}
}
- p->fts_parent->fts_bignum += p->fts_statp->st_blocks;
+ p->fts_parent->fts_bignum += Aflag ?
+ p->fts_statp->st_size :
+ p->fts_statp->st_blocks;
}
savednumber = p->fts_parent->fts_bignum;
}
@@ -441,8 +460,6 @@
{
char buf[5];
- bytes *= DEV_BSIZE;
-
humanize_number(buf, sizeof(buf), bytes, "", HN_AUTOSCALE,
HN_B | HN_NOSPACE | HN_DECIMAL);
@@ -453,8 +470,9 @@
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);
}
More information about the freebsd-hackers
mailing list