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>