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;
}