summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_subr.c9
-rw-r--r--sys/ufs/ffs/ffs_inode.c6
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c8
-rw-r--r--sys/ufs/ufs/ufs_inode.c2
-rw-r--r--sys/ufs/ufs/ufs_vnops.c9
5 files changed, 24 insertions, 10 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 8f0b4cf..41a3530 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1863,6 +1863,7 @@ vflush(mp, rootrefs, flags)
{
struct thread *td = curthread; /* XXX */
struct vnode *vp, *nvp, *rootvp = NULL;
+ struct vattr vattr;
int busy = 0, error;
if (rootrefs > 0) {
@@ -1898,10 +1899,14 @@ loop:
continue;
}
/*
- * If WRITECLOSE is set, only flush out regular file vnodes
- * open for writing.
+ * If WRITECLOSE is set, flush out unlinked but still open
+ * files (even if open only for reading) and regular file
+ * vnodes open for writing.
*/
if ((flags & WRITECLOSE) &&
+ (vp->v_type == VNON ||
+ (VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td) == 0 &&
+ vattr.va_nlink > 0)) &&
(vp->v_writecount == 0 || vp->v_type != VREG)) {
mtx_unlock(&vp->v_interlock);
mtx_lock(&mntvnode_mtx);
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index 9014a60..6dcf2cc 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -87,9 +87,9 @@ ffs_update(vp, waitfor)
if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor == 0)
return (0);
ip->i_flag &= ~(IN_LAZYMOD | IN_MODIFIED);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (0);
fs = ip->i_fs;
+ if (fs->fs_ronly)
+ return (0);
/*
* Ensure that uid and gid are correct. This is a temporary
* fix until fsck has been changed to do the update.
@@ -152,6 +152,8 @@ ffs_truncate(vp, length, flags, cred, td)
oip = VTOI(ovp);
fs = oip->i_fs;
+ if (fs->fs_ronly)
+ panic("ffs_truncate: read-only filesystem");
if (length < 0)
return (EINVAL);
if (length > fs->fs_maxfilesize)
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index a9985d5..9025767 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -180,6 +180,14 @@ ffs_mount(mp, path, data, ndp, td)
if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
+ /*
+ * Flush any dirty data.
+ */
+ VFS_SYNC(mp, MNT_WAIT, td->td_proc->p_ucred, td);
+ /*
+ * Check for and optionally get rid of files open
+ * for writing.
+ */
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
diff --git a/sys/ufs/ufs/ufs_inode.c b/sys/ufs/ufs/ufs_inode.c
index c841c39..f7c7884 100644
--- a/sys/ufs/ufs/ufs_inode.c
+++ b/sys/ufs/ufs/ufs_inode.c
@@ -84,7 +84,7 @@ ufs_inactive(ap)
goto out;
if (ip->i_effnlink == 0 && DOINGSOFTDEP(vp))
softdep_releasefile(ip);
- if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+ if (ip->i_nlink <= 0) {
(void) vn_write_suspend_wait(vp, NULL, V_WAIT);
#ifdef QUOTA
if (!getinoquota(ip))
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index d5df52e..4b52d1e 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -158,13 +158,12 @@ ufs_itimes(vp)
ip = VTOI(vp);
if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
return;
+ if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp))
+ ip->i_flag |= IN_LAZYMOD;
+ else
+ ip->i_flag |= IN_MODIFIED;
if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
vfs_timestamp(&ts);
- if ((vp->v_type == VBLK || vp->v_type == VCHR) &&
- !DOINGSOFTDEP(vp))
- ip->i_flag |= IN_LAZYMOD;
- else
- ip->i_flag |= IN_MODIFIED;
if (ip->i_flag & IN_ACCESS) {
ip->i_atime = ts.tv_sec;
ip->i_atimensec = ts.tv_nsec;
OpenPOWER on IntegriCloud