[4445] in Athena Bugs

home help back first fref pref prev next nref lref last post

fixes for /bin/df

daemon@ATHENA.MIT.EDU (John Carr)
Wed Mar 7 17:55:54 1990

To: bugs@ATHENA.MIT.EDU
Date: Wed, 07 Mar 90 17:55:30 EST
From: John Carr <jfc@ATHENA.MIT.EDU>

The patches in this message improve the performance of "df".

	. df does not try to stat a file to determine if it is a block
	  special device.  A new flag, "-f", overrides this.

	. df scans /etc/mtab for an exact match between a passed filename
	  and a mountpoint before stat-ing every mounted filesystem.

	. df will now stop stat-ing files when it find the filesystem
	  containing the file passed as an argument (the current version
	  stats _every_ filesystem, not stopping when it finds the right
	  one).

This should prevent many problems when NFS servers are down or slow.
Updated documentation is included.

[see changes.70 #53]

*** /source/bsd-4.3/common/bin/df.c	Wed Apr 13 14:08:41 1988
--- df.new.c	Wed Mar  7 17:47:50 1990
***************
*** 15,21 ****
  #include <mntent.h>
  
  char	*mpath();
! int	iflag;
  int	type;
  char	*typestr;
  
--- 15,21 ----
  #include <mntent.h>
  
  char	*mpath();
! int	iflag, fflag;
  int	type;
  char	*typestr;
  
***************
*** 34,40 ****
  {
  	int i;
  	struct stat statb;
- 	char tmpname[1024];
  
  	while (argc > 1 && argv[1][0]=='-') {
  		switch (argv[1][1]) {
--- 34,39 ----
***************
*** 50,55 ****
--- 49,58 ----
  			argc--;
  			break;
  
+ 		case 'f':
+ 			fflag++;
+ 			break;
+ 
  		default:
  			usage();
  		}
***************
*** 74,94 ****
  		}
  		while (mnt = getmntent(mtabp)) {
  			if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
! 			    strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0)
  				continue;
! 			if (!strcmp(mnt->mnt_type, MNTTYPE_NFS) && iflag)
! 				continue;
! 			if (type && strcmp(typestr, mnt->mnt_type)) {
! 				continue;
! 			}
! 			if ((stat(mnt->mnt_fsname, &statb) >= 0) &&
! 			   (((statb.st_mode & S_IFBLK) == S_IFBLK) ||
! 			    ((statb.st_mode & S_IFCHR) == S_IFCHR))) {
! 				strcpy(tmpname, mnt->mnt_fsname);
! 				dfreedev(tmpname);
! 			} else {
! 				dfreemnt(mnt->mnt_dir, mnt);
! 			}
  		}
  		endmntent(mtabp);
  		exit(0);
--- 77,86 ----
  		}
  		while (mnt = getmntent(mtabp)) {
  			if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
! 			    strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0 ||
! 			    strcmp(mnt->mnt_type, MNTTYPE_NFS) == 0)
  				continue;
! 			dfreemnt(mnt->mnt_dir, mnt);
  		}
  		endmntent(mtabp);
  		exit(0);
***************
*** 96,115 ****
  	for (i=1; i<argc; i++) {
  		struct mntent *mnt;
  
! 		if (stat(argv[i], &statb) < 0) {
! 			perror(argv[i]);
  		} else {
! 			if ((statb.st_mode & S_IFBLK) == S_IFBLK ||
! 			    (statb.st_mode & S_IFCHR) == S_IFCHR) {
! 				dfreedev(argv[i]);
! 			} else {
! 				if ((mnt = getmntpt(argv[i])) != NULL)
! 					if (type &&
! 					    strcmp(typestr, mnt->mnt_type)) {
! 						continue;
! 					}
! 					dfreemnt(argv[i], mnt);
  			}
  		}
  	}
  	exit(0);
--- 88,114 ----
  	for (i=1; i<argc; i++) {
  		struct mntent *mnt;
  
! 		if(fflag) {
! 			if (stat(argv[i], &statb) < 0)
! 				perror(argv[i]);
! 			else
! 				if ((statb.st_mode & S_IFBLK) == S_IFBLK ||
! 				    (statb.st_mode & S_IFCHR) == S_IFCHR)
! 				  dfreedev(argv[i]);
! 				else
! 				  fprintf(stderr,
! 					  "df: %s: Not a block or character special device\n",
! 					  argv[i]);
  		} else {
! 			if((mnt = getmntpt(argv[i])) == NULL) {
! 				fprintf(stderr,
! 					"df: Can't find mount point for %s\n",
! 					argv[i]);
! 				continue;
  			}
+ 			if(type && strcmp(typestr, mnt->mnt_type))
+ 			  continue;
+ 			dfreemnt(argv[i], mnt);
  		}
  	}
  	exit(0);
***************
*** 216,221 ****
--- 215,225 ----
  		return(NULL);
  	}
  
+ 	/* Since it is faster to scan mtab than to stat a file
+ 	   on average (consdering the chance of contacting a hung
+ 	   remote file server), scan all of mtab first to find the mount
+ 	   point */
+ 
  	if ((mntp = setmntent(MOUNTED, "r")) == 0) {
  		perror(MOUNTED);
  		exit(1);
***************
*** 223,228 ****
--- 227,246 ----
  
  	mntsave = NULL;
  	while ((mnt = getmntent(mntp)) != 0) {
+ 		if(strcmp(mnt->mnt_dir, file))
+ 		  continue;
+ 		mntsave = mntdup(mnt);
+ 		endmntent(mntp);
+ 		return mntsave;
+ 	}
+ 	endmntent(mntp);
+ 
+ 	if ((mntp = setmntent(MOUNTED, "r")) == 0) {
+ 		perror(MOUNTED);
+ 		exit(1);
+ 	}
+ 
+ 	while ((mnt = getmntent(mntp)) != 0) {
  		if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
  		    strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0)
  			continue;
***************
*** 229,234 ****
--- 247,253 ----
  		if ((stat(mnt->mnt_dir, &dirstat) >= 0) &&
  		   (filestat.st_dev == dirstat.st_dev)) {
  			mntsave = mntdup(mnt);
+ 			break;
  		}
  	}
  	endmntent(mntp);


*** /source/bsd-4.3/common/man/man1/df.1	Fri Nov 17 01:35:09 1989
--- df.1	Wed Mar  7 17:47:21 1990
***************
*** 13,30 ****
  [
  .B \-i
  ] [
  .B \-t
! mount-type ] [ filesystem ... ] [ file ... ]
  .SH DESCRIPTION
  .I Df
  prints out the amount of free disk space
  available on the specified
! .I filesystem,
! e.g. ``/dev/rp0a'',
! or on the filesystem in which the specified
  .I file,
  e.g. ``$HOME'',
! is contained.
  If no file system is specified,
  the free space on all of
  the normally mounted file systems
--- 13,38 ----
  [
  .B \-i
  ] [
+ .B \-f
+ ] [
  .B \-t
! mount-type ] [ file ... ]
  .SH DESCRIPTION
  .I Df
  prints out the amount of free disk space
  available on the specified
! .I filesystem.
! If the
! .B \-f
! flag is used,
! .I file
! can be a special device, e.g. ``/dev/ra0a''.
! If 
! .B \-f
! is not used, the filesystem containing
  .I file,
  e.g. ``$HOME'',
! is used.
  If no file system is specified,
  the free space on all of
  the normally mounted file systems



home help back first fref pref prev next nref lref last post