Index: fs/nilfs/nilfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/nilfs/nilfs_vnops.c,v
retrieving revision 1.15
diff -u -u -r1.15 nilfs_vnops.c
--- fs/nilfs/nilfs_vnops.c	16 Oct 2011 12:41:45 -0000	1.15
+++ fs/nilfs/nilfs_vnops.c	18 Nov 2011 18:57:36 -0000
@@ -280,6 +280,8 @@
 
 	/* mark node changed and request update */
 	nilfs_node->i_flags |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		nilfs_node->i_flags |= IN_ACCESS;
 
 	/*
 	 * XXX TODO FFS has code here to reset setuid & setgid when we're not
Index: fs/ptyfs/ptyfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vnops.c,v
retrieving revision 1.36
diff -u -u -r1.36 ptyfs_vnops.c
--- fs/ptyfs/ptyfs_vnops.c	16 Sep 2011 18:43:44 -0000	1.36
+++ fs/ptyfs/ptyfs_vnops.c	18 Nov 2011 18:57:37 -0000
@@ -426,8 +426,11 @@
 		if (vap->va_atime.tv_sec != VNOVAL)
 			if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
 				ptyfs->ptyfs_flag |= PTYFS_ACCESS;
-		if (vap->va_mtime.tv_sec != VNOVAL)
+		if (vap->va_mtime.tv_sec != VNOVAL) {
 			ptyfs->ptyfs_flag |= PTYFS_CHANGE | PTYFS_MODIFY;
+			if (vp->v_mount->mnt_flag & MNT_RELATIME)
+				ptyfs->ptyfs_flag |= PTYFS_ACCESS;
+		}
 		if (vap->va_birthtime.tv_sec != VNOVAL)
 			ptyfs->ptyfs_birthtime = vap->va_birthtime;
 		ptyfs->ptyfs_flag |= PTYFS_CHANGE;
Index: fs/puffs/puffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v
retrieving revision 1.161
diff -u -u -r1.161 puffs_vnops.c
--- fs/puffs/puffs_vnops.c	30 Oct 2011 13:24:13 -0000	1.161
+++ fs/puffs/puffs_vnops.c	18 Nov 2011 18:57:38 -0000
@@ -1967,6 +1967,8 @@
 
 		origoff = uio->uio_offset;
 		while (uio->uio_resid > 0) {
+			if (vp->v_mount->mnt_flag & MNT_RELATIME)
+				uflags |= PUFFS_UPDATEATIME;
 			uflags |= PUFFS_UPDATECTIME;
 			uflags |= PUFFS_UPDATEMTIME;
 			oldoff = uio->uio_offset;
Index: fs/tmpfs/tmpfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_vnops.c,v
retrieving revision 1.92
diff -u -u -r1.92 tmpfs_vnops.c
--- fs/tmpfs/tmpfs_vnops.c	27 Sep 2011 01:32:21 -0000	1.92
+++ fs/tmpfs/tmpfs_vnops.c	18 Nov 2011 18:57:39 -0000
@@ -2465,8 +2465,11 @@
 		if ((vp->v_mount->mnt_flag & MNT_NOATIME) == 0)
 			node->tn_status |= TMPFS_NODE_ACCESSED;
 
-		if ((access_type & VM_PROT_WRITE) != 0)
+		if ((access_type & VM_PROT_WRITE) != 0) {
 			node->tn_status |= TMPFS_NODE_MODIFIED;
+			if (vp->v_mount->mnt_flag & MNT_RELATIME)
+				node->tn_status |= TMPFS_NODE_ACCESSED;
+		}
 	}
 
 	/*
Index: fs/udf/udf_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/udf/udf_vnops.c,v
retrieving revision 1.68
diff -u -u -r1.68 udf_vnops.c
--- fs/udf/udf_vnops.c	18 Oct 2011 20:20:29 -0000	1.68
+++ fs/udf/udf_vnops.c	18 Nov 2011 18:57:40 -0000
@@ -376,6 +376,8 @@
 
 	/* mark node changed and request update */
 	udf_node->i_flags |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		udf_node->i_flags |= IN_ACCESS;
 
 	/*
 	 * XXX TODO FFS has code here to reset setuid & setgid when we're not
@@ -977,6 +979,8 @@
 
 	/* mark node changed */
 	udf_node->i_flags |= IN_CHANGE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		udf_node->i_flags |= IN_ACCESS;
 
 	return 0;
 }
@@ -1013,6 +1017,8 @@
 
 	/* mark node changed */
 	udf_node->i_flags |= IN_CHANGE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		udf_node->i_flags |= IN_ACCESS;
 
 	return 0;
 }
@@ -1063,6 +1069,8 @@
 	if (error == 0) {
 		/* mark change */
 		udf_node->i_flags |= IN_CHANGE | IN_MODIFY;
+		if (vp->v_mount->mnt_flag & MNT_RELATIME)
+			udf_node->i_flags |= IN_ACCESS;
 		VN_KNOTE(vp, NOTE_ATTRIB | (extended ? NOTE_EXTEND : 0));
 		udf_update(vp, NULL, NULL, NULL, 0);
 	}
@@ -1116,8 +1124,11 @@
 	if (atime->tv_sec != VNOVAL)
 		if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
 			udf_node->i_flags |= IN_ACCESS;
-	if ((mtime->tv_sec != VNOVAL) || (birthtime->tv_sec != VNOVAL))
+	if ((mtime->tv_sec != VNOVAL) || (birthtime->tv_sec != VNOVAL)) {
 		udf_node->i_flags |= IN_CHANGE | IN_UPDATE;
+		if (vp->v_mount->mnt_flag & MNT_RELATIME)
+			udf_node->i_flags |= IN_ACCESS;
+	}
 
 	return udf_update(vp, atime, mtime, birthtime, 0);
 }
Index: ufs/ext2fs/ext2fs_readwrite.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_readwrite.c,v
retrieving revision 1.57
diff -u -u -r1.57 ext2fs_readwrite.c
--- ufs/ext2fs/ext2fs_readwrite.c	12 Jun 2011 03:36:00 -0000	1.57
+++ ufs/ext2fs/ext2fs_readwrite.c	18 Nov 2011 18:57:41 -0000
@@ -374,6 +374,8 @@
 
 out:
 	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		ip->i_flag |= IN_ACCESS;
 	if (resid > uio->uio_resid && ap->a_cred &&
 	    kauth_authorize_generic(ap->a_cred, KAUTH_GENERIC_ISSUSER, NULL))
 		ip->i_e2fs_mode &= ~(ISUID | ISGID);
Index: ufs/ext2fs/ext2fs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v
retrieving revision 1.100
diff -u -u -r1.100 ext2fs_vnops.c
--- ufs/ext2fs/ext2fs_vnops.c	12 Jul 2011 16:59:48 -0000	1.100
+++ ufs/ext2fs/ext2fs_vnops.c	18 Nov 2011 18:57:41 -0000
@@ -431,8 +431,11 @@
 		if (vap->va_atime.tv_sec != VNOVAL)
 			if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
 				ip->i_flag |= IN_ACCESS;
-		if (vap->va_mtime.tv_sec != VNOVAL)
+		if (vap->va_mtime.tv_sec != VNOVAL) {
 			ip->i_flag |= IN_CHANGE | IN_UPDATE;
+			if (vp->v_mount->mnt_flag & MNT_RELATIME)
+				ip->i_flag |= IN_ACCESS;
+		}
 		error = ext2fs_update(vp, &vap->va_atime, &vap->va_mtime,
 			UPDATE_WAIT);
 		if (error)
@@ -1282,6 +1285,8 @@
 		if (error)
 			goto bad;
 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		if (vp->v_mount->mnt_flag & MNT_RELATIME)
+			ip->i_flag |= IN_ACCESS;
 		uvm_vnp_setsize(vp, len);
 	} else
 		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
Index: ufs/ufs/ufs_readwrite.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_readwrite.c,v
retrieving revision 1.99
diff -u -u -r1.99 ufs_readwrite.c
--- ufs/ufs/ufs_readwrite.c	11 Jul 2011 08:27:41 -0000	1.99
+++ ufs/ufs/ufs_readwrite.c	18 Nov 2011 18:57:42 -0000
@@ -507,6 +507,8 @@
 	 */
 out:
 	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		ip->i_flag |= IN_ACCESS;
 	if (resid > uio->uio_resid && ap->a_cred &&
 	    kauth_authorize_generic(ap->a_cred, KAUTH_GENERIC_ISSUSER, NULL)) {
 		ip->i_mode &= ~(ISUID | ISGID);
Index: ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.205
diff -u -u -r1.205 ufs_vnops.c
--- ufs/ufs/ufs_vnops.c	27 Sep 2011 02:10:32 -0000	1.205
+++ ufs/ufs/ufs_vnops.c	18 Nov 2011 18:57:43 -0000
@@ -638,8 +638,11 @@
 		if (vap->va_atime.tv_sec != VNOVAL)
 			if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
 				ip->i_flag |= IN_ACCESS;
-		if (vap->va_mtime.tv_sec != VNOVAL)
+		if (vap->va_mtime.tv_sec != VNOVAL) {
 			ip->i_flag |= IN_CHANGE | IN_UPDATE;
+			if (vp->v_mount->mnt_flag & MNT_RELATIME)
+				ip->i_flag |= IN_ACCESS;
+		}
 		if (vap->va_birthtime.tv_sec != VNOVAL &&
 		    ip->i_ump->um_fstype == UFS2) {
 			ip->i_ffs2_birthtime = vap->va_birthtime.tv_sec;
@@ -2092,7 +2095,7 @@
 		goto bad;
 	ip->i_size = dirblksiz;
 	DIP_ASSIGN(ip, size, dirblksiz);
-	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
 	uvm_vnp_setsize(tvp, ip->i_size);
 	memcpy((void *)bp->b_data, (void *)&dirtemplate, sizeof dirtemplate);
 
@@ -2286,6 +2289,8 @@
 		DIP_ASSIGN(ip, size, len);
 		uvm_vnp_setsize(vp, ip->i_size);
 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		if (vp->v_mount->mnt_flag & MNT_RELATIME)
+			ip->i_flag |= IN_ACCESS;
 		UFS_WAPBL_UPDATE(vp, NULL, NULL, 0);
 	} else
 		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
Index: sys/fstypes.h
===================================================================
RCS file: /cvsroot/src/sys/sys/fstypes.h,v
retrieving revision 1.29
diff -u -u -r1.29 fstypes.h
--- sys/fstypes.h	17 Jun 2011 14:23:51 -0000	1.29
+++ sys/fstypes.h	18 Nov 2011 18:57:43 -0000
@@ -83,9 +83,8 @@
  * one of the __MNT_UNUSED flags.
  */
 
-#define	__MNT_UNUSED1	0x00020000
-#define	__MNT_UNUSED2	0x00200000
-#define	__MNT_UNUSED3	0x00800000
+#define	__MNT_UNUSED1	0x00200000
+#define	__MNT_UNUSED2	0x00800000
 
 #define	MNT_RDONLY	0x00000001	/* read only filesystem */
 #define	MNT_SYNCHRONOUS	0x00000002	/* file system written synchronously */
@@ -95,6 +94,7 @@
 #define	MNT_UNION	0x00000020	/* union with underlying filesystem */
 #define	MNT_ASYNC	0x00000040	/* file system written asynchronously */
 #define	MNT_NOCOREDUMP	0x00008000	/* don't write core dumps to this FS */
+#define	MNT_RELATIME	0x00020000	/* only update access time if mod/ch */
 #define	MNT_IGNORE	0x00100000	/* don't show entry in df */
 #define	MNT_EXTATTR	0x01000000	/* enable extended attributes */
 #define	MNT_LOG		0x02000000	/* Use logging */
@@ -104,22 +104,27 @@
 #define	MNT_SOFTDEP	0x80000000	/* Use soft dependencies */
 
 #define	__MNT_BASIC_FLAGS \
-	{ MNT_RDONLY,		0,	"read-only" }, \
-	{ MNT_SYNCHRONOUS,	0,	"synchronous" }, \
-	{ MNT_NOEXEC,		0,	"noexec" }, \
-	{ MNT_NOSUID,		0,	"nosuid" }, \
-	{ MNT_NODEV,		0,	"nodev" }, \
-	{ MNT_UNION,		0,	"union" }, \
 	{ MNT_ASYNC,		0,	"asynchronous" }, \
-	{ MNT_NOCOREDUMP,	0,	"nocoredump" }, \
+	{ MNT_EXTATTR,		0,	"extattr" }, \
 	{ MNT_IGNORE,		0,	"hidden" }, \
+	{ MNT_LOG,		0,	"log" }, \
 	{ MNT_NOATIME,		0,	"noatime" }, \
-	{ MNT_SYMPERM,		0,	"symperm" }, \
+	{ MNT_NOCOREDUMP,	0,	"nocoredump" }, \
+	{ MNT_NODEV,		0,	"nodev" }, \
 	{ MNT_NODEVMTIME,	0,	"nodevmtime" }, \
+	{ MNT_NOEXEC,		0,	"noexec" }, \
+	{ MNT_NOSUID,		0,	"nosuid" }, \
+	{ MNT_RDONLY,		0,	"read-only" }, \
+	{ MNT_RELATIME,		0,	"relatime" }, \
 	{ MNT_SOFTDEP,		0,	"soft dependencies" }, \
-	{ MNT_LOG,		0,	"log" }, \
-	{ MNT_EXTATTR,		0,	"extattr" }, 
+	{ MNT_SYMPERM,		0,	"symperm" }, \
+	{ MNT_SYNCHRONOUS,	0,	"synchronous" }, \
+	{ MNT_UNION,		0,	"union" }, \
 
+#define MNT_BASIC_FLAGS (MNT_ASYNC | MNT_EXTATTR | MNT_LOG | MNT_NOATIME | \
+    MNT_NOCOREDUMP | MNT_NODEV | MNT_NODEVMTIME | MNT_NOEXEC | MNT_NOSUID | \
+    MNT_RDONLY | MNT_RELATIME | MNT_SOFTDEP | MNT_SYMPERM | \
+    MNT_SYNCHRONOUS | MNT_UNION)
 /*
  * exported mount flags.
  */
@@ -236,7 +241,7 @@
 	"\25MNT_IGNORE" \
 	"\24MNT_FORCE" \
 	"\23MNT_RELOAD" \
-	"\22MNT_UNUSED" \
+	"\22MNT_RELATIME" \
 	"\21MNT_UPDATE" \
 	"\20MNT_NOCOREDUMP" \
 	"\17MNT_ROOTFS" \
Index: sys/statvfs.h
===================================================================
RCS file: /cvsroot/src/sys/sys/statvfs.h,v
retrieving revision 1.16
diff -u -u -r1.16 statvfs.h
--- sys/statvfs.h	17 Jun 2011 14:23:51 -0000	1.16
+++ sys/statvfs.h	18 Nov 2011 18:57:43 -0000
@@ -113,6 +113,7 @@
 #define	ST_UNION	MNT_UNION
 #define	ST_ASYNC	MNT_ASYNC
 #define	ST_NOCOREDUMP	MNT_NOCOREDUMP
+#define	ST_RELATIME	MNT_RELATIME
 #define	ST_IGNORE	MNT_IGNORE
 #define	ST_NOATIME	MNT_NOATIME
 #define	ST_SYMPERM	MNT_SYMPERM
Index: kern/vfs_mount.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_mount.c,v
retrieving revision 1.11
diff -u -u -r1.11 vfs_mount.c
--- kern/vfs_mount.c	14 Oct 2011 09:23:31 -0000	1.11
+++ kern/vfs_mount.c	18 Nov 2011 18:57:46 -0000
@@ -696,11 +698,7 @@
 	 *
 	 * Set the mount level flags.
 	 */
-	mp->mnt_flag = flags &
-	   (MNT_FORCE | MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
-	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOCOREDUMP |
-	    MNT_NOATIME | MNT_NODEVMTIME | MNT_SYMPERM | MNT_SOFTDEP |
-	    MNT_LOG | MNT_IGNORE | MNT_RDONLY);
+	mp->mnt_flag = flags & (MNT_BASIC_FLAGS | MNT_FORCE | MNT_IGNORE);
 
 	mutex_enter(&mp->mnt_updating);
 	error = VFS_MOUNT(mp, path, data, data_len);
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.440
diff -u -u -r1.440 vfs_syscalls.c
--- kern/vfs_syscalls.c	14 Oct 2011 09:23:31 -0000	1.440
+++ kern/vfs_syscalls.c	18 Nov 2011 18:57:47 -0000
@@ -221,7 +221,7 @@
 	mutex_enter(&mp->mnt_updating);
 
 	mp->mnt_flag &= ~MNT_OP_FLAGS;
-	mp->mnt_flag |= flags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
+	mp->mnt_flag |= flags & MNT_OP_FLAGS;
 
 	/*
 	 * Set the mount level flags.
@@ -230,17 +230,8 @@
 		mp->mnt_flag |= MNT_RDONLY;
 	else if (mp->mnt_flag & MNT_RDONLY)
 		mp->mnt_iflag |= IMNT_WANTRDWR;
-	mp->mnt_flag &=
-	  ~(MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
-	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOCOREDUMP |
-	    MNT_NOATIME | MNT_NODEVMTIME | MNT_SYMPERM | MNT_SOFTDEP |
-	    MNT_LOG | MNT_EXTATTR);
-	mp->mnt_flag |= flags &
-	   (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
-	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOCOREDUMP |
-	    MNT_NOATIME | MNT_NODEVMTIME | MNT_SYMPERM | MNT_SOFTDEP |
-	    MNT_LOG | MNT_EXTATTR | MNT_IGNORE);
-
+	mp->mnt_flag &= ~MNT_BASIC_FLAGS;
+	mp->mnt_flag |= flags & MNT_BASIC_FLAGS;
 	error = VFS_MOUNT(mp, path, data, data_len);
 
 	if (error && data != NULL) {