Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 May 2003 11:42:24 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Kirk McKusick <mckusick@McKusick.COM>
Cc:        Jens Schweikhardt <schweikh@FreeBSD.org>
Subject:   Re: Access times on executables (kern/25777)
Message-ID:  <20030504110643.Q1248@gamplex.bde.org>
In-Reply-To: <200305040032.h440WvTh015707@beastie.mckusick.com>
References:  <200305040032.h440WvTh015707@beastie.mckusick.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 3 May 2003, Kirk McKusick wrote:

> I was asked to review kern/25777 which points out that FreeBSD at
> some point stopped updating access times on files being executed
> which is counter to its earlier behavior and to POSIX. I propose
> that the fix below be put in to restore this behavior. Those
> concerned with the overhead of the updates can use the "noatimes"
> mount option to disable it. Comments?

> Index: sys/kern_exec.c
> ===================================================================
> RCS file: /usr/ncvs/src/sys/kern/kern_exec.c,v
> retrieving revision 1.218
> diff -c -r1.218 kern_exec.c
> *** kern_exec.c	1 Apr 2003 01:26:20 -0000	1.218
> --- kern_exec.c	4 May 2003 00:26:00 -0000
> ***************
> *** 598,603 ****
> --- 598,618 ----
>   		exec_setregs(td, imgp->entry_addr,
>   		    (u_long)(uintptr_t)stack_base, imgp->ps_strings);
>
> + 	/*
> + 	 * At this point, it counts as an access.
> + 	 * Ensure that atime gets updated if needed.
> + 	 */
> + 	if (!(textvp->v_mount->mnt_flag & MNT_NOATIME)) {
> + 		struct vattr vattr;
> +
> + 		VATTR_NULL(&vattr);
> + 		vfs_timestamp(&vattr.va_atime);
> + 		VOP_LEASE(textvp, td, p->p_ucred, LEASE_WRITE);
> + 		vn_lock(textvp, LK_EXCLUSIVE | LK_RETRY, td);
> + 		(void) VOP_SETATTR(textvp, &vattr, p->p_ucred, td);
> + 		VOP_UNLOCK(textvp, 0, td);
> + 	}
> +
>   done1:
>   	/*
>   	 * Free any resources malloc'd earlier that we didn't use.
>

This doesn't work unless the user has permission to change the atime
using utimes(2) with a non-NULL times pointer.

My version of it has a VA_EXECVE_ATIME flag which tells VOP_SETATTR()
to bypass the permissions checks.  I only implemented checking this
flag for ufs.

Another problem with setting the atime like utimes() would instead of
like read() would is that utimes() is required to update the times
immediately, so VOP_SETATTR() does this, but updates for read() are
normally optimized to just set a flag.  The difference is not large
for ufs since the UFS_UPDATE() call in ufs_setattr() doesn't wait.
The VA_EXECVE_ATIME flag could be used to optimize this, but I didn't
try this.

The overhead for setting atimes on exec only seemed to be large for
nfs.  This was before nfs had an attribute cache, and I think it
is unavoidable for utimes()-like updates.  On one of my systems now,
futimes() takes about 12.5 times longer than reading 1 byte from
a file on an nfs-mounted file system with the server's file system
mounted -async (239 usec versus 19 usec averaged over for 10^4
futimes()s and 10^6 read()s).

Bruce


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