From infofarmer@FreeBSD.org  Fri Apr 11 07:22:50 2008
Return-Path: <infofarmer@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 778D21065671
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 11 Apr 2008 07:22:50 +0000 (UTC)
	(envelope-from infofarmer@FreeBSD.org)
Received: from heka.cenkes.org (heka.cenkes.org [208.79.80.110])
	by mx1.freebsd.org (Postfix) with ESMTP id 3B4C88FC19
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 11 Apr 2008 07:22:50 +0000 (UTC)
	(envelope-from infofarmer@FreeBSD.org)
Received: from amilo.cenkes.org (ppp85-140-149-151.pppoe.mtu-net.ru [85.140.149.151])
	(Authenticated sender: sat)
	by heka.cenkes.org (Postfix) with ESMTPSA id 25C3D242F886
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 11 Apr 2008 11:05:07 +0400 (MSD)
Message-Id: <20080411070507.25C3D242F886@heka.cenkes.org>
Date: Fri, 11 Apr 2008 11:05:07 +0400 (MSD)
From: Andrew Pantyukhin <sat>
Reply-To: Andrew Pantyukhin <infofarmer@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] du(1) support for inode count
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         122652
>Category:       bin
>Synopsis:       [patch] du(1) support for inode count
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 11 07:30:01 UTC 2008
>Closed-Date:    
>Last-Modified:  Sat May  3 09:50:01 UTC 2008
>Originator:     Andrew Pantyukhin
>Release:        FreeBSD 8.0-CURRENT amd64
>Organization:
>Environment:
System: FreeBSD amilo.cenkes.org 8.0-CURRENT FreeBSD 8.0-CURRENT #5: Mon Mar 17 17:42:39 MSK 2008 sat@amilo.cenkes.org:/usr/obj/usr/src/sys/AMILO amd64


	
>Description:
This patch adds support for inode count to du. Mirrored here:
http://heka.cenkes.org/sat/diffs/du_inode.diff

Based on NetBSD's bin/22405 by
	Jonathan Perkin <jonathan@perkin.org.uk>
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=22405
>How-To-Repeat:
	
>Fix:

	

--- du_inode.diff begins here ---
Index: du/du.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/du/du.1,v
retrieving revision 1.33
diff -u -r1.33 du.1
--- du/du.1	25 Feb 2008 19:06:43 -0000	1.33
+++ du/du.1	11 Apr 2008 06:56:02 -0000
@@ -44,7 +44,7 @@
 .Op Fl a | s | d Ar depth
 .Op Fl c
 .Op Fl l
-.Op Fl h | k | m
+.Op Fl h | k | m | i
 .Op Fl n
 .Op Fl x
 .Op Fl I Ar mask
@@ -52,10 +52,10 @@
 .Sh DESCRIPTION
 The
 .Nm
-utility displays the file system block usage for each file argument
+utility displays the file system block or inode usage for each file argument
 and for each directory in the file hierarchy rooted in each directory
 argument.
-If no file is specified, the block usage of the hierarchy rooted in
+If no file is specified, the block or inode usage of the hierarchy rooted in
 the current directory is displayed.
 .Pp
 The options are as follows:
@@ -77,6 +77,8 @@
 "Human-readable" output.
 Use unit suffixes: Byte, Kilobyte, Megabyte,
 Gigabyte, Terabyte and Petabyte.
+.It Fl i
+Display inode usage instead of block usage.
 .It Fl r
 Generate messages about directories that cannot be read, files
 that cannot be opened, and so on.
Index: du/du.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/du/du.c,v
retrieving revision 1.45
diff -u -r1.45 du.c
--- du/du.c	25 Feb 2008 19:06:43 -0000	1.45
+++ du/du.c	11 Apr 2008 06:56:02 -0000
@@ -65,6 +65,9 @@
 #include <sysexits.h>
 #include <unistd.h>
 
+/* Count inodes or file size */
+#define		COUNT	(iflag ? 1 : p->fts_statp->st_blocks)
+
 SLIST_HEAD(ignhead, ignentry) ignores;
 struct ignentry {
 	char			*mask;
@@ -91,21 +94,21 @@
 	int		listall;
 	int		depth;
 	int		Hflag, Lflag, Pflag, aflag, sflag, dflag, cflag;
-	int		hflag, lflag, ch, notused, rval;
+	int		hflag, iflag, lflag, ch, notused, rval;
 	char 		**save;
 	static char	dot[] = ".";
 
 	setlocale(LC_ALL, "");
 
 	Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag =
-	    lflag = 0;
+	    iflag = 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, "HI:LPasd:chiklmnrx")) != -1)
 		switch (ch) {
 			case 'H':
 				Hflag = 1;
@@ -147,6 +150,9 @@
 					    "setenv: cannot set BLOCKSIZE=512");
 				hflag = 1;
 				break;
+			case 'i':
+				iflag = 1;
+				break;
 			case 'k':
 				hflag = 0;
 				if (setenv("BLOCKSIZE", "1024", 1) == -1)
@@ -241,10 +247,14 @@
 					break;
 
 				p->fts_parent->fts_bignum +=
-				    p->fts_bignum += p->fts_statp->st_blocks;
+				    p->fts_bignum += COUNT;
 
 				if (p->fts_level <= depth) {
-					if (hflag) {
+					if (iflag) {
+					(void) printf("%jd\t%s\n",
+						(intmax_t)p->fts_bignum,
+						p->fts_path);
+					} else if (hflag) {
 						(void) prthumanval(howmany(p->fts_bignum, blocksize));
 						(void) printf("\t%s\n", p->fts_path);
 					} else {
@@ -271,18 +281,22 @@
 					break;
 
 				if (listall || p->fts_level == 0) {
-					if (hflag) {
-						(void) prthumanval(howmany(p->fts_statp->st_blocks,
+					if (iflag) {
+						(void) printf("%jd\t%s\n",
+							(intmax_t)COUNT,
+							p->fts_path);
+					} else if (hflag) {
+						(void) prthumanval(howmany(COUNT,
 							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),
+							(intmax_t)howmany(COUNT, blocksize),
 							p->fts_path);
 					}
 				}
 
-				p->fts_parent->fts_bignum += p->fts_statp->st_blocks;
+				p->fts_parent->fts_bignum += COUNT;
 		}
 		savednumber = p->fts_parent->fts_bignum;
 	}
@@ -291,7 +305,9 @@
 		err(1, "fts_read");
 
 	if (cflag) {
-		if (hflag) {
+		if (iflag) {
+			(void) printf("%jd\ttotal\n", (intmax_t)savednumber);
+		} else if (hflag) {
 			(void) prthumanval(howmany(savednumber, blocksize));
 			(void) printf("\ttotal\n");
 		} else {
@@ -454,7 +470,7 @@
 {
 	(void)fprintf(stderr,
 		"usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] "
-		"[-l] [-h | -k | -m] [-n] [-x] [-I mask] [file ...]\n");
+		"[-l] [-h | -k | -m | -i] [-n] [-x] [-I mask] [file ...]\n");
 	exit(EX_USAGE);
 }
 
--- du_inode.diff ends here ---


>Release-Note:
>Audit-Trail:

From: David Schultz <das@FreeBSD.ORG>
To: Andrew Pantyukhin <infofarmer@FreeBSD.ORG>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/122652: [patch] du(1) support for inode count
Date: Fri, 11 Apr 2008 17:18:07 -0400

 Correct me if I'm mistaken, but doesn't this get the wrong answer
 when a file has multiple hard links?

From: Andrew Pantyukhin <infofarmer@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc: David Schultz <das@FreeBSD.org>
Subject: Re: bin/122652: [patch] du(1) support for inode count
Date: Sat, 3 May 2008 13:43:23 +0400

 Well, du doesn't count size multiple times in case of hard links,
 so why should the same loop count inodes the wrong way? I just
 tested, and it acts as expected: neither "df -i" nor "du -i"
 counters increase when a new hard link is created.
>Unformatted:
