From leres@ee.lbl.gov  Mon Jan 26 19:07:51 1998
Received: from ell.ee.lbl.gov (ell.ee.lbl.gov [131.243.1.20])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id TAA21203
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 26 Jan 1998 19:07:51 -0800 (PST)
          (envelope-from leres@ee.lbl.gov)
Received: by ell.ee.lbl.gov (8.8.8/8.8.5)
	id TAA19217; Mon, 26 Jan 1998 19:07:50 -0800 (PST)
Message-Id: <199801270307.TAA19217@ell.ee.lbl.gov>
Date: Mon, 26 Jan 98 19:07:50 PST
From: leres@ee.lbl.gov (Craig Leres)
Sender: leres@ee.lbl.gov
Reply-To: leres@ee.lbl.gov
To: FreeBSD-gnats-submit@freebsd.org
Cc: leres@ee.lbl.gov
Subject: Unnecessary disk I/O and noatime fixes
X-Send-Pr-Version: 3.2

>Number:         5577
>Category:       kern
>Synopsis:       Unnecessary disk I/O and noatime ffs fixes
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bde
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 26 19:10:01 PST 1998
>Closed-Date:    Sat Feb 16 10:55:54 UTC 2008
>Last-Modified:  Sat Feb 16 10:55:54 UTC 2008
>Originator:     Craig Leres
>Release:        FreeBSD 2.2.5-STABLE i386
>Organization:
Lawrence Berkeley National Laboratory
>Environment:

	

>Description:

	When running FreeBSD on notebook computers, we noticed a lot of
	extra disk activity. Turning on the noatime mount option didn't
	seem to help.

>How-To-Repeat:

	Notice that the disk on a completely idle notebook will spin up
	ever few minutes.

>Fix:
	
	Appended are context diffs of Van's fixes.

	For ufs/ffs/ffs_inode.c:

	    If no MNT_NOATIME is set then ignore access time update
	    requests.

	For ufs/ffs/ffs_vfsops.c:

	    If MNT_NOATIME is set, ignore access time changes. Don't
	    bother flushing the mount point (e.g., for root) since it
	    gets flushed anyway. If MNT_NOATIME is set, don't update
	    the on-disk access times for /dev inodes (but do update the
	    in-core times so finger and w work).

	For ufs/ffs/ffs_vnops.c:

	    Don't defer flushing the inode or else we will end up with
	    new I/O activity on the next sync.

------
RCS file: RCS/ffs_inode.c,v
retrieving revision 1.2
diff -c -r1.2 ffs_inode.c
*** /tmp/,RCSt1001826	Mon Jan 26 16:19:12 1998
--- ffs_inode.c	Mon Jan 26 16:02:06 1998
***************
*** 98,107 ****
  		    ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
  		return (0);
  	}
! 	if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) &&
! 	    (ip->i_flag & (IN_CHANGE|IN_MODIFIED|IN_UPDATE) == 0)) {
  		ip->i_flag &=~ IN_ACCESS;
- 		return (0);
  	}
  	if ((ip->i_flag &
  	    (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)
--- 98,105 ----
  		    ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
  		return (0);
  	}
! 	if (ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) {
  		ip->i_flag &=~ IN_ACCESS;
  	}
  	if ((ip->i_flag &
  	    (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)
RCS file: RCS/ffs_vfsops.c,v
retrieving revision 1.2
diff -c -r1.2 ffs_vfsops.c
*** /tmp/,RCSt1001831	Mon Jan 26 16:19:18 1998
--- ffs_vfsops.c	Mon Jan 26 16:08:03 1998
***************
*** 780,785 ****
--- 780,786 ----
  	register struct fs *fs;
  	struct timeval tv;
  	int error, allerror = 0, didsomething = 0;
+ 	u_long fmask;
  
  	fs = ump->um_fs;
  	/*
***************
*** 799,804 ****
--- 800,808 ----
  	/*
  	 * Write back each (modified) inode.
  	 */
+ 	fmask = (mp->mnt_flag & MNT_NOATIME)?
+ 			(IN_CHANGE | IN_MODIFIED | IN_UPDATE) :
+ 			(IN_CHANGE | IN_MODIFIED | IN_UPDATE | IN_ACCESS);
  loop:
  	for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
  		/*
***************
*** 817,835 ****
  		if (VOP_ISLOCKED(vp))
  			continue;
  		ip = VTOI(vp);
! 		if ((((ip->i_flag &
! 		    (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)) &&
  		    vp->v_dirtyblkhd.lh_first == NULL)
  			continue;
- 		didsomething = 1;
  		if (vp->v_type != VCHR) {
  			if (vget(vp, 1))
  				goto loop;
  			error = VOP_FSYNC(vp, cred, waitfor, p);
  			if (error)
  				allerror = error;
  			vput(vp);
  		} else {
  			tv = time;
  			/* VOP_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); */
  			VOP_UPDATE(vp, &tv, &tv, 0);
--- 821,853 ----
  		if (VOP_ISLOCKED(vp))
  			continue;
  		ip = VTOI(vp);
! 		if ((((ip->i_flag & fmask) == 0)) &&
  		    vp->v_dirtyblkhd.lh_first == NULL)
  			continue;
  		if (vp->v_type != VCHR) {
  			if (vget(vp, 1))
  				goto loop;
+ 			++didsomething;
  			error = VOP_FSYNC(vp, cred, waitfor, p);
  			if (error)
  				allerror = error;
  			vput(vp);
  		} else {
+ 			/* XXX
+ 			 * if we're not keeping track of access time
+ 			 * (which means we're trying to minimize disk
+ 			 * activity) and the inode hasn't been modified
+ 			 * & it's for a non-disk device, update the
+ 			 * in-memory mtime/ctime but don't bother to
+ 			 * update the on-disk ones.
+ 			 */
+ 			if ((fmask & IN_ACCESS) == 0 &&
+ 			    (ip->i_flag & IN_MODIFIED) == 0 &&
+ 			    !isdisk(vp->v_specinfo->si_rdev, VCHR)) {
+ 				ITIMES(ip, &time, &time)
+ 				continue;
+ 			}
+ 			++didsomething;
  			tv = time;
  			/* VOP_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); */
  			VOP_UPDATE(vp, &tv, &tv, 0);
RCS file: RCS/ffs_vnops.c,v
retrieving revision 1.2
diff -c -r1.2 ffs_vnops.c
*** /tmp/,RCSt1001836	Mon Jan 26 16:19:25 1998
--- ffs_vnops.c	Mon Jan 26 16:11:53 1998
***************
*** 243,251 ****
  
  #include <ufs/ufs/ufs_readwrite.c>
  
- int ffs_log_sync = 0;
- 
- 
  /*
   * Synch an open file.
   */
--- 243,248 ----
***************
*** 266,276 ****
  	int pass;
  	int s;
  
- if (ffs_log_sync) {
-   struct inode* ip = VTOI(vp);
-   printf("fsync i %u iflags 0x%x vn 0x%x vtype %d tag %d vflags 0x%x\n",
-    ip->i_number, ip->i_flag, vp, vp->v_type, vp->v_tag, vp->v_flag);
- }
  	pass = 0;
  	/*
  	 * Flush all dirty buffers associated with a vnode.
--- 263,268 ----
***************
*** 284,293 ****
  		if ((bp->b_flags & B_DELWRI) == 0)
  			panic("ffs_fsync: not dirty");
  
- if (ffs_log_sync) {
-   printf("  blk %u (%u) flags 0x%x vn 0x%x\n", bp->b_lblkno, bp->b_blkno,
-    bp->b_flags, bp->b_vp);
- }
  		if (bp->b_vp != vp || ap->a_waitfor != MNT_NOWAIT) {
  
  			bremfree(bp);
--- 276,281 ----
***************
*** 330,334 ****
  	}
  
  	tv = time;
! 	return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
  }
--- 318,326 ----
  	}
  
  	tv = time;
! 	/*
! 	 * Don't defer flushing this inode or else we will end
! 	 * up with new I/O activity on the next sync.
! 	 */
! 	return (VOP_UPDATE(ap->a_vp, &tv, &tv, 1));
  }
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: jkh 
State-Changed-When: Mon Feb 2 00:19:53 PST 1998 
State-Changed-Why:  
Submitted patch applied by John (who forgot to close this PR ;-) 
State-Changed-From-To: closed->open 
State-Changed-By: steve 
State-Changed-When: Sat Feb 7 13:29:05 PST 1998 
State-Changed-Why:  
John later reverted these changes.  Bruce mentioned that the 
patch didn't cleanly to any version of FreeBSD and at least 
one failed attempt to contact the orginator about problems 
with the patch.  Exactly what those problems were, I don't 
know. 
Responsible-Changed-From-To: freebsd-bugs->bde 
Responsible-Changed-By: bde 
Responsible-Changed-When: Sat May 2 07:28:47 PDT 1998 
Responsible-Changed-Why:  
I'm working on this. 
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Sat Feb 16 10:53:08 UTC 2008 
State-Changed-Why:  
Apparently was committed Fri Jul 3 22:17:03 1998 UTC (9 years, 7 months ago) 
by bde in rev 1.92 of ufs_vnops.c. 

This week's award for "closing antique PRs" to: Dylan Cochran 

http://www.freebsd.org/cgi/query-pr.cgi?pr=5577 
>Unformatted:
