Module Name:    src
Committed By:   riastradh
Date:           Sat Mar 28 17:06:15 UTC 2015

Modified Files:
        src/sys/ufs/ext2fs: ext2fs_readwrite.c
        src/sys/ufs/lfs: ulfs_readwrite.c
        src/sys/ufs/ufs: ufs_readwrite.c

Log Message:
Factor out post-read/write inode updates in UFS.


To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/sys/ufs/ext2fs/ext2fs_readwrite.c
cvs rdiff -u -r1.10 -r1.11 src/sys/ufs/lfs/ulfs_readwrite.c
cvs rdiff -u -r1.111 -r1.112 src/sys/ufs/ufs/ufs_readwrite.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/ext2fs/ext2fs_readwrite.c
diff -u src/sys/ufs/ext2fs/ext2fs_readwrite.c:1.70 src/sys/ufs/ext2fs/ext2fs_readwrite.c:1.71
--- src/sys/ufs/ext2fs/ext2fs_readwrite.c:1.70	Sat Mar 28 03:53:36 2015
+++ src/sys/ufs/ext2fs/ext2fs_readwrite.c	Sat Mar 28 17:06:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_readwrite.c,v 1.70 2015/03/28 03:53:36 riastradh Exp $	*/
+/*	$NetBSD: ext2fs_readwrite.c,v 1.71 2015/03/28 17:06:15 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.70 2015/03/28 03:53:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.71 2015/03/28 17:06:15 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -81,6 +81,10 @@ __KERNEL_RCSID(0, "$NetBSD: ext2fs_readw
 #include <ufs/ext2fs/ext2fs.h>
 #include <ufs/ext2fs/ext2fs_extern.h>
 
+static int	ext2fs_post_read_update(struct vnode *, int, int);
+static int	ext2fs_post_write_update(struct vnode *, struct uio *, int,
+		    kauth_cred_t, off_t, int, int, int);
+
 /*
  * Vnode op for reading.
  */
@@ -137,11 +141,7 @@ ext2fs_read(void *v)
 	}
 
 out:
-	if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
-		ip->i_flag |= IN_ACCESS;
-		if ((ap->a_ioflag & IO_SYNC) == IO_SYNC)
-			error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
-	}
+	error = ext2fs_post_read_update(vp, ap->a_ioflag, error);
 	return (error);
 }
 
@@ -227,12 +227,22 @@ ext2fs_bufrd(struct vnode *vp, struct ui
 		brelse(bp, 0);
 
 out:
+	error = ext2fs_post_read_update(vp, ioflag, error);
+	return (error);
+}
+
+static int
+ext2fs_post_read_update(struct vnode *vp, int ioflag, int error)
+{
+	struct inode *ip = VTOI(vp);
+
 	if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
 		ip->i_flag |= IN_ACCESS;
 		if ((ioflag & IO_SYNC) == IO_SYNC)
 			error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
 	}
-	return (error);
+
+	return error;
 }
 
 /*
@@ -335,36 +345,8 @@ ext2fs_write(void *v)
 		    PGO_CLEANIT | PGO_SYNCIO);
 	}
 
-	/*
-	 * If we successfully wrote any data, and we are not the superuser
-	 * we clear the setuid and setgid bits as a precaution against
-	 * tampering.
-	 */
-	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) {
-		if (ip->i_e2fs_mode & ISUID) {
-			if (kauth_authorize_vnode(ap->a_cred,
-			    KAUTH_VNODE_RETAIN_SUID, vp, NULL, EPERM) != 0)
-				ip->i_e2fs_mode &= ISUID;
-		}
-
-		if (ip->i_e2fs_mode & ISGID) {
-			if (kauth_authorize_vnode(ap->a_cred,
-			    KAUTH_VNODE_RETAIN_SGID, vp, NULL, EPERM) != 0)
-				ip->i_e2fs_mode &= ~ISGID;
-		}
-	}
-	if (resid > uio->uio_resid)
-		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
-	if (error) {
-		(void) ext2fs_truncate(vp, osize, ioflag & IO_SYNC, ap->a_cred);
-		uio->uio_offset -= resid - uio->uio_resid;
-		uio->uio_resid = resid;
-	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC)
-		error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
-	KASSERT(vp->v_size == ext2fs_size(ip));
+	error = ext2fs_post_write_update(vp, uio, ioflag, ap->a_cred, osize,
+	    resid, extended, error);
 	return (error);
 }
 
@@ -445,14 +427,27 @@ ext2fs_bufwr(struct vnode *vp, struct ui
 			break;
 	}
 
+	error = ext2fs_post_write_update(vp, uio, ioflag, cred, osize, resid,
+	    extended, error);
+	return (error);
+}
+
+static int
+ext2fs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag,
+    kauth_cred_t cred, off_t osize, int resid, int extended, int error)
+{
+	struct inode *ip = VTOI(vp);
+
+	/* Trigger ctime and mtime updates, and atime if MNT_RELATIME.  */
+	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		ip->i_flag |= IN_ACCESS;
+
 	/*
-	 * If we successfully wrote any data, and we are not the superuser
+	 * If we successfully wrote any data and we are not the superuser,
 	 * we clear the setuid and setgid bits as a precaution against
 	 * tampering.
 	 */
-	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 && cred) {
 		if (ip->i_e2fs_mode & ISUID) {
 			if (kauth_authorize_vnode(cred,
@@ -466,14 +461,24 @@ ext2fs_bufwr(struct vnode *vp, struct ui
 				ip->i_e2fs_mode &= ~ISGID;
 		}
 	}
+
+	/* If we successfully wrote anything, notify kevent listeners.  */
 	if (resid > uio->uio_resid)
 		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
+
+	/*
+	 * Update the size on disk: truncate back to original size on
+	 * error, or reflect the new size on success.
+	 */
 	if (error) {
 		(void) ext2fs_truncate(vp, osize, ioflag & IO_SYNC, cred);
 		uio->uio_offset -= resid - uio->uio_resid;
 		uio->uio_resid = resid;
 	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC)
 		error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
+
+	/* Make sure the vnode uvm size matches the inode file size.  */
 	KASSERT(vp->v_size == ext2fs_size(ip));
-	return (error);
+
+	return error;
 }

Index: src/sys/ufs/lfs/ulfs_readwrite.c
diff -u src/sys/ufs/lfs/ulfs_readwrite.c:1.10 src/sys/ufs/lfs/ulfs_readwrite.c:1.11
--- src/sys/ufs/lfs/ulfs_readwrite.c:1.10	Sat Mar 28 03:53:36 2015
+++ src/sys/ufs/lfs/ulfs_readwrite.c	Sat Mar 28 17:06:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ulfs_readwrite.c,v 1.10 2015/03/28 03:53:36 riastradh Exp $	*/
+/*	$NetBSD: ulfs_readwrite.c,v 1.11 2015/03/28 17:06:15 riastradh Exp $	*/
 /*  from NetBSD: ufs_readwrite.c,v 1.105 2013/01/22 09:39:18 dholland Exp  */
 
 /*-
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: ulfs_readwrite.c,v 1.10 2015/03/28 03:53:36 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: ulfs_readwrite.c,v 1.11 2015/03/28 17:06:15 riastradh Exp $");
 
 #ifdef LFS_READWRITE
 #define	FS			struct lfs
@@ -57,6 +57,10 @@ __KERNEL_RCSID(1, "$NetBSD: ulfs_readwri
 #define	BUFWR			ffs_bufwr
 #endif
 
+static int	ulfs_post_read_update(struct vnode *, int, int);
+static int	ulfs_post_write_update(struct vnode *, struct uio *, int,
+		    kauth_cred_t, off_t, int, int, int);
+
 /*
  * Vnode op for reading.
  */
@@ -126,13 +130,7 @@ READ(void *v)
 	}
 
  out:
-	if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
-		ip->i_flag |= IN_ACCESS;
-		if ((ap->a_ioflag & IO_SYNC) == IO_SYNC) {
-			error = lfs_update(vp, NULL, NULL, UPDATE_WAIT);
-		}
-	}
-
+	error = ulfs_post_read_update(vp, ap->a_ioflag, error);
 	fstrans_done(vp->v_mount);
 	return (error);
 }
@@ -223,6 +221,16 @@ BUFRD(struct vnode *vp, struct uio *uio,
 		brelse(bp, 0);
 
  out:
+	error = ulfs_post_read_update(vp, ioflag, error);
+	fstrans_done(vp->v_mount);
+	return (error);
+}
+
+static int
+ulfs_post_read_update(struct vnode *vp, int ioflag, int error)
+{
+	struct inode *ip = VTOI(vp);
+
 	if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
 		ip->i_flag |= IN_ACCESS;
 		if ((ioflag & IO_SYNC) == IO_SYNC) {
@@ -230,8 +238,7 @@ BUFRD(struct vnode *vp, struct uio *uio,
 		}
 	}
 
-	fstrans_done(vp->v_mount);
-	return (error);
+	return error;
 }
 
 /*
@@ -436,44 +443,9 @@ WRITE(void *v)
 		    PGO_CLEANIT | PGO_SYNCIO | PGO_JOURNALLOCKED);
 	}
 
-	/*
-	 * If we successfully wrote any data, and we are not the superuser
-	 * we clear the setuid and setgid bits as a precaution against
-	 * tampering.
-	 */
 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) {
-		if (ip->i_mode & ISUID) {
-			if (kauth_authorize_vnode(ap->a_cred,
-			    KAUTH_VNODE_RETAIN_SUID, vp, NULL, EPERM) != 0) {
-				ip->i_mode &= ~ISUID;
-				DIP_ASSIGN(ip, mode, ip->i_mode);
-			}
-		}
-
-		if (ip->i_mode & ISGID) {
-			if (kauth_authorize_vnode(ap->a_cred,
-			    KAUTH_VNODE_RETAIN_SGID, vp, NULL, EPERM) != 0) {
-				ip->i_mode &= ~ISGID;
-				DIP_ASSIGN(ip, mode, ip->i_mode);
-			}
-		}
-	}
-	if (resid > uio->uio_resid)
-		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
-	if (error) {
-		(void) lfs_truncate(vp, osize, ioflag & IO_SYNC, ap->a_cred);
-		uio->uio_offset -= resid - uio->uio_resid;
-		uio->uio_resid = resid;
-	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC) {
-		error = lfs_update(vp, NULL, NULL, UPDATE_WAIT);
-	} else {
-		/* nothing */
-	}
-	KASSERT(vp->v_size == ip->i_size);
+	error = ulfs_post_write_update(vp, uio, ioflag, cred, osize, resid,
+	    extended, error);
 	fstrans_done(vp->v_mount);
 
 	return (error);
@@ -603,14 +575,29 @@ BUFWR(struct vnode *vp, struct uio *uio,
 	}
 #endif
 
+	error = ulfs_post_write_update(vp, uio, ioflag, cred, osize, resid,
+	    extended, error);
+	fstrans_done(vp->v_mount);
+
+	return (error);
+}
+
+static int
+ulfs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag,
+    kauth_cred_t cred, off_t osize, int resid, int extended, int error)
+{
+	struct inode *ip = VTOI(vp);
+
+	/* Trigger ctime and mtime updates, and atime if MNT_RELATIME.  */
+	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		ip->i_flag |= IN_ACCESS;
+
 	/*
-	 * If we successfully wrote any data, and we are not the superuser
+	 * If we successfully wrote any data and we are not the superuser,
 	 * we clear the setuid and setgid bits as a precaution against
 	 * tampering.
 	 */
-	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 && cred) {
 		if (ip->i_mode & ISUID) {
 			if (kauth_authorize_vnode(cred,
@@ -628,8 +615,15 @@ BUFWR(struct vnode *vp, struct uio *uio,
 			}
 		}
 	}
+
+	/* If we successfully wrote anything, notify kevent listeners.  */
 	if (resid > uio->uio_resid)
 		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
+
+	/*
+	 * Update the size on disk: truncate back to original size on
+	 * error, or reflect the new size on success.
+	 */
 	if (error) {
 		(void) lfs_truncate(vp, osize, ioflag & IO_SYNC, cred);
 		uio->uio_offset -= resid - uio->uio_resid;
@@ -640,7 +634,6 @@ BUFWR(struct vnode *vp, struct uio *uio,
 		/* nothing */
 	}
 	KASSERT(vp->v_size == ip->i_size);
-	fstrans_done(vp->v_mount);
 
-	return (error);
+	return error;
 }

Index: src/sys/ufs/ufs/ufs_readwrite.c
diff -u src/sys/ufs/ufs/ufs_readwrite.c:1.111 src/sys/ufs/ufs/ufs_readwrite.c:1.112
--- src/sys/ufs/ufs/ufs_readwrite.c:1.111	Sat Mar 28 04:13:25 2015
+++ src/sys/ufs/ufs/ufs_readwrite.c	Sat Mar 28 17:06:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_readwrite.c,v 1.111 2015/03/28 04:13:25 riastradh Exp $	*/
+/*	$NetBSD: ufs_readwrite.c,v 1.112 2015/03/28 17:06:15 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.111 2015/03/28 04:13:25 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.112 2015/03/28 17:06:15 riastradh Exp $");
 
 #ifdef LFS_READWRITE
 #define	FS			struct lfs
@@ -69,6 +69,10 @@ __KERNEL_RCSID(1, "$NetBSD: ufs_readwrit
 #define ufs_blkroundup		ffs_blkroundup
 #endif
 
+static int	ufs_post_read_update(struct vnode *, int, int);
+static int	ufs_post_write_update(struct vnode *, struct uio *, int,
+		    kauth_cred_t, off_t, int, int, int);
+
 /*
  * Vnode op for reading.
  */
@@ -138,19 +142,7 @@ READ(void *v)
 	}
 
  out:
-	if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
-		ip->i_flag |= IN_ACCESS;
-		if ((ap->a_ioflag & IO_SYNC) == IO_SYNC) {
-			error = UFS_WAPBL_BEGIN(vp->v_mount);
-			if (error) {
-				fstrans_done(vp->v_mount);
-				return error;
-			}
-			error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
-			UFS_WAPBL_END(vp->v_mount);
-		}
-	}
-
+	error = ufs_post_read_update(vp, ap->a_ioflag, error);
 	fstrans_done(vp->v_mount);
 	return (error);
 }
@@ -240,21 +232,28 @@ BUFRD(struct vnode *vp, struct uio *uio,
 		brelse(bp, 0);
 
  out:
+	error = ufs_post_read_update(vp, ioflag, error);
+	fstrans_done(vp->v_mount);
+	return (error);
+}
+
+static int
+ufs_post_read_update(struct vnode *vp, int ioflag, int error)
+{
+	struct inode *ip = VTOI(vp);
+
 	if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
 		ip->i_flag |= IN_ACCESS;
 		if ((ioflag & IO_SYNC) == IO_SYNC) {
 			error = UFS_WAPBL_BEGIN(vp->v_mount);
-			if (error) {
-				fstrans_done(vp->v_mount);
+			if (error)
 				return error;
-			}
 			error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
 			UFS_WAPBL_END(vp->v_mount);
 		}
 	}
 
-	fstrans_done(vp->v_mount);
-	return (error);
+	return error;
 }
 
 /*
@@ -467,43 +466,9 @@ WRITE(void *v)
 		    PGO_CLEANIT | PGO_SYNCIO | PGO_JOURNALLOCKED);
 	}
 
-	/*
-	 * If we successfully wrote any data, and we are not the superuser
-	 * we clear the setuid and setgid bits as a precaution against
-	 * tampering.
-	 */
 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) {
-		if (ip->i_mode & ISUID) {
-			if (kauth_authorize_vnode(ap->a_cred,
-			    KAUTH_VNODE_RETAIN_SUID, vp, NULL, EPERM) != 0) {
-				ip->i_mode &= ~ISUID;
-				DIP_ASSIGN(ip, mode, ip->i_mode);
-			}
-		}
-
-		if (ip->i_mode & ISGID) {
-			if (kauth_authorize_vnode(ap->a_cred,
-			    KAUTH_VNODE_RETAIN_SGID, vp, NULL, EPERM) != 0) {
-				ip->i_mode &= ~ISGID;
-				DIP_ASSIGN(ip, mode, ip->i_mode);
-			}
-		}
-	}
-	if (resid > uio->uio_resid)
-		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
-	if (error) {
-		(void) UFS_TRUNCATE(vp, osize, ioflag & IO_SYNC, ap->a_cred);
-		uio->uio_offset -= resid - uio->uio_resid;
-		uio->uio_resid = resid;
-	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC)
-		error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
-	else
-		UFS_WAPBL_UPDATE(vp, NULL, NULL, 0);
-	KASSERT(vp->v_size == ip->i_size);
+	error = ufs_post_write_update(vp, uio, ioflag, cred, osize, resid,
+	    extended, error);
 	UFS_WAPBL_END(vp->v_mount);
 	fstrans_done(vp->v_mount);
 
@@ -638,14 +603,31 @@ BUFWR(struct vnode *vp, struct uio *uio,
 	}
 #endif
 
+	error = ufs_post_write_update(vp, uio, ioflag, cred, osize, resid,
+	    extended, error);
+	if ((ioflag & IO_JOURNALLOCKED) == 0)
+		UFS_WAPBL_END(vp->v_mount);
+	fstrans_done(vp->v_mount);
+
+	return (error);
+}
+
+static int
+ufs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag,
+    kauth_cred_t cred, off_t osize, int resid, int extended, int error)
+{
+	struct inode *ip = VTOI(vp);
+
+	/* Trigger ctime and mtime updates, and atime if MNT_RELATIME.  */
+	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	if (vp->v_mount->mnt_flag & MNT_RELATIME)
+		ip->i_flag |= IN_ACCESS;
+
 	/*
-	 * If we successfully wrote any data, and we are not the superuser
+	 * If we successfully wrote any data and we are not the superuser,
 	 * we clear the setuid and setgid bits as a precaution against
 	 * tampering.
 	 */
-	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 && cred) {
 		if (ip->i_mode & ISUID) {
 			if (kauth_authorize_vnode(cred,
@@ -663,8 +645,15 @@ BUFWR(struct vnode *vp, struct uio *uio,
 			}
 		}
 	}
+
+	/* If we successfully wrote anything, notify kevent listeners.  */
 	if (resid > uio->uio_resid)
 		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
+
+	/*
+	 * Update the size on disk: truncate back to original size on
+	 * error, or reflect the new size on success.
+	 */
 	if (error) {
 		(void) UFS_TRUNCATE(vp, osize, ioflag & IO_SYNC, cred);
 		uio->uio_offset -= resid - uio->uio_resid;
@@ -673,10 +662,9 @@ BUFWR(struct vnode *vp, struct uio *uio,
 		error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
 	else
 		UFS_WAPBL_UPDATE(vp, NULL, NULL, 0);
+
+	/* Make sure the vnode uvm size matches the inode file size.  */
 	KASSERT(vp->v_size == ip->i_size);
-	if ((ioflag & IO_JOURNALLOCKED) == 0)
-		UFS_WAPBL_END(vp->v_mount);
-	fstrans_done(vp->v_mount);
 
-	return (error);
+	return error;
 }

Reply via email to