Subject: Re: kern/25279: NFS read doesn't update atime
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 06/29/2005 11:00:43
--XsQoSWH+UP9D9v3l
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Jun 29, 2005 at 09:43:18AM +0900, YAMAMOTO Takashi wrote:
> > 
> > You mean VOP_WRITE ?
> 
> no, i meant GOP_WRITE, which starts i/o.
> ffs currently uses genfs_gop_write for it.

Ha yes. Sorry, I didn't know these functions.
Yes, this works. Here is a new patch. LFS and ext2fs currently untested.

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--

--XsQoSWH+UP9D9v3l
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.getpage"

Index: ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.85
diff -u -b -r1.85 ext2fs_vfsops.c
--- ext2fs/ext2fs_vfsops.c	29 May 2005 21:25:24 -0000	1.85
+++ ext2fs/ext2fs_vfsops.c	29 Jun 2005 08:59:09 -0000
@@ -107,6 +107,7 @@
 
 int ext2fs_sbupdate __P((struct ufsmount *, int));
 static int ext2fs_checksb __P((struct ext2fs *, int));
+int ext2fs_gop_write __P((struct vnode *, struct vm_page **, int, int));
 
 extern const struct vnodeopv_desc ext2fs_vnodeop_opv_desc;
 extern const struct vnodeopv_desc ext2fs_specop_opv_desc;
@@ -146,7 +147,7 @@
 struct genfs_ops ext2fs_genfsops = {
 	genfs_size,
 	ext2fs_gop_alloc,
-	genfs_gop_write,
+	ext2fs_gop_write,
 };
 
 /*
@@ -1221,3 +1222,17 @@
 	}
 	return (0);
 }
+
+int
+ext2fs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags)
+{
+	struct inode *ip = VTOI(vp);
+	int error;
+
+	error = genfs_gop_write(vp, pgs, npages, flags);
+	if (error == 0) {
+		/* file has been written, update mtime */
+		ip->i_e2fs_flags |= IN_CHANGE | IN_UPDATE;
+	}
+	return error;
+}
Index: ext2fs/ext2fs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v
retrieving revision 1.59
diff -u -b -r1.59 ext2fs_vnops.c
--- ext2fs/ext2fs_vnops.c	26 Feb 2005 22:32:20 -0000	1.59
+++ ext2fs/ext2fs_vnops.c	29 Jun 2005 08:59:09 -0000
@@ -106,6 +106,7 @@
 	__P((struct vnode *, int, struct ucred *, struct proc *));
 static int ext2fs_chown
 	__P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
+static int ext2fs_getpages __P((void *));
 
 union _qcvt {
 	int64_t	qcvt;
@@ -1475,6 +1476,28 @@
 	return (0);
 }
 
+static int
+ext2fs_getpages(void *v)
+{
+	struct vop_getpages_args /* {
+		struct vnode *a_vp;
+		voff_t a_offset;
+		struct vm_page **a_m;
+		int *a_count;
+		int a_centeridx;
+		vm_prot_t a_access_type;
+		int a_advice;
+		int a_flags;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+
+	if (!(vp->v_mount->mnt_flag & MNT_NOATIME) &&
+	    !(ap->a_access_type & VM_PROT_WRITE))
+		ip->i_e2fs_flags |= IN_ACCESS;
+	return genfs_getpages(v);
+}
+
 /* Global vfs data structures for ext2fs. */
 int (**ext2fs_vnodeop_p) __P((void *));
 const struct vnodeopv_entry_desc ext2fs_vnodeop_entries[] = {
@@ -1523,7 +1546,7 @@
 	{ &vop_truncate_desc, ext2fs_truncate },	/* truncate */
 	{ &vop_update_desc, ext2fs_update },		/* update */
 	{ &vop_bwrite_desc, vn_bwrite },		/* bwrite */
-	{ &vop_getpages_desc, genfs_getpages },		/* getpages */
+	{ &vop_getpages_desc, ext2fs_getpages },	/* getpages */
 	{ &vop_putpages_desc, genfs_putpages },		/* putpages */
 	{ NULL, NULL }
 };
Index: ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.164
diff -u -b -r1.164 ffs_vfsops.c
--- ffs/ffs_vfsops.c	29 May 2005 21:25:24 -0000	1.164
+++ ffs/ffs_vfsops.c	29 Jun 2005 08:59:09 -0000
@@ -116,7 +116,7 @@
 struct genfs_ops ffs_genfsops = {
 	ffs_gop_size,
 	ufs_gop_alloc,
-	genfs_gop_write,
+	ufs_gop_write,
 };
 
 POOL_INIT(ffs_inode_pool, sizeof(struct inode), 0, 0, 0, "ffsinopl",
Index: ffs/ffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vnops.c,v
retrieving revision 1.69
diff -u -b -r1.69 ffs_vnops.c
--- ffs/ffs_vnops.c	26 Feb 2005 22:32:20 -0000	1.69
+++ ffs/ffs_vnops.c	29 Jun 2005 08:59:09 -0000
@@ -535,6 +535,9 @@
 		}
 		return EINVAL;
 	}
+	if (!(vp->v_mount->mnt_flag & MNT_NOATIME) &&
+	    (ap->a_access_type & VM_PROT_READ))
+		ip->i_flag |= IN_ACCESS;
 	return genfs_getpages(v);
 }
 
Index: lfs/lfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vfsops.c,v
retrieving revision 1.182
diff -u -b -r1.182 lfs_vfsops.c
--- lfs/lfs_vfsops.c	9 Jun 2005 02:19:59 -0000	1.182
+++ lfs/lfs_vfsops.c	29 Jun 2005 08:59:09 -0000
@@ -2178,6 +2178,9 @@
 		}
 		splx(s);
 	}
+	/* file has been written, update mtime */
+	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+
 	UVMHIST_LOG(ubchist, "returning 0", 0,0,0,0);
 	return (0);
 
Index: lfs/lfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v
retrieving revision 1.152
diff -u -b -r1.152 lfs_vnops.c
--- lfs/lfs_vnops.c	29 May 2005 21:25:24 -0000	1.152
+++ lfs/lfs_vnops.c	29 Jun 2005 08:59:09 -0000
@@ -1424,6 +1424,9 @@
 	if ((ap->a_access_type & VM_PROT_WRITE) != 0) {
 		LFS_SET_UINO(VTOI(ap->a_vp), IN_MODIFIED);
 	}
+	if (!(ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) &&
+	    !(ap->a_access_type & VM_PROT_WRITE))
+		VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
 
 	/*
 	 * we're relying on the fact that genfs_getpages() always read in
Index: ufs/ufs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extern.h,v
retrieving revision 1.43
diff -u -b -r1.43 ufs_extern.h
--- ufs/ufs_extern.h	29 May 2005 21:25:24 -0000	1.43
+++ ufs/ufs_extern.h	29 Jun 2005 08:59:09 -0000
@@ -168,6 +168,7 @@
 int ufs_makeinode __P((int, struct vnode *, struct vnode **,
 		       struct componentname *));
 int ufs_gop_alloc __P((struct vnode *, off_t, off_t, int, struct ucred *));
+int ufs_gop_write __P((struct vnode *, struct vm_page **, int, int));
 
 /*
  * Snapshot function prototypes.
Index: ufs/ufs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_inode.c,v
retrieving revision 1.47
diff -u -b -r1.47 ufs_inode.c
--- ufs/ufs_inode.c	23 Jan 2005 19:37:05 -0000	1.47
+++ ufs/ufs_inode.c	29 Jun 2005 08:59:09 -0000
@@ -240,7 +240,7 @@
 	memset(pgs, 0, npages * sizeof(struct vm_page *));
 	simple_lock(&uobj->vmobjlock);
 	error = VOP_GETPAGES(vp, pagestart, pgs, &npages, 0,
-	    VM_PROT_READ, 0, PGO_SYNCIO|PGO_PASTEOF);
+	    VM_PROT_WRITE, 0, PGO_SYNCIO|PGO_PASTEOF);
 	if (error) {
 		return error;
 	}
Index: ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.127
diff -u -b -r1.127 ufs_vnops.c
--- ufs/ufs_vnops.c	23 Mar 2005 00:12:51 -0000	1.127
+++ ufs/ufs_vnops.c	29 Jun 2005 08:59:09 -0000
@@ -2195,3 +2195,17 @@
 out:
         return error;
 }
+
+int
+ufs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags)
+{
+	struct inode *ip = VTOI(vp);
+	int error;
+
+	error = genfs_gop_write(vp, pgs, npages, flags);
+	if (error == 0) {
+		/* file has been written, update mtime */
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	}
+	return error;
+}

--XsQoSWH+UP9D9v3l--