Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Jan 98 19:07:50 PST
From:      leres@ee.lbl.gov (Craig Leres)
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Cc:        leres@ee.lbl.gov
Subject:   kern/5577: Unnecessary disk I/O and noatime fixes
Message-ID:  <199801270307.TAA19217@ell.ee.lbl.gov>

next in thread | raw e-mail | index | archive | help

>Number:         5577
>Category:       kern
>Synopsis:       Unnecessary disk I/O and noatime ffs fixes
>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:   Mon Jan 26 19:10:01 PST 1998
>Last-Modified:
>Originator:     Craig Leres
>Organization:
Lawrence Berkeley National Laboratory
>Release:        FreeBSD 2.2.5-STABLE i386
>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));
  }
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199801270307.TAA19217>