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>
index | next in thread | raw e-mail
>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:
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199801270307.TAA19217>
