Eliminate a race in VOP_FSYNC() when softupdates is enabled.

Submitted by:	Kirk McKusick	<mckusick@McKusick.COM>
Two minor changes are also included,
1. Remove gratuitious checks for error return from vn_lock with LK_RETRY set,
   vn_lock should always succeed in these cases.
2. Back out change rev. 1.36->1.37, which unnecessarily makes async mount
   a little more unstable. It also keeps us in sync with other BSDs.
Suggested by:	Bruce Evans	<bde@zeta.org.au>
This commit is contained in:
Luoqi Chen 1998-09-24 15:02:46 +00:00
parent de77c42832
commit e266594c25
8 changed files with 44 additions and 83 deletions

View File

@ -54,7 +54,7 @@
* SUCH DAMAGE.
*
* from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98
* $Id: ffs_softdep.c,v 1.12 1998/06/12 21:21:26 julian Exp $
* $Id: ffs_softdep.c,v 1.13 1998/08/12 20:46:47 julian Exp $
*/
/*
@ -209,6 +209,7 @@ struct bio_ops bioops = {
softdep_disk_io_initiation, /* io_start */
softdep_disk_write_complete, /* io_complete */
softdep_deallocate_dependencies, /* io_deallocate */
softdep_fsync, /* io_fsync */
softdep_process_worklist, /* io_sync */
};

View File

@ -54,7 +54,7 @@
* SUCH DAMAGE.
*
* from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98
* $Id: ffs_softdep.c,v 1.12 1998/06/12 21:21:26 julian Exp $
* $Id: ffs_softdep.c,v 1.13 1998/08/12 20:46:47 julian Exp $
*/
/*
@ -209,6 +209,7 @@ struct bio_ops bioops = {
softdep_disk_io_initiation, /* io_start */
softdep_disk_write_complete, /* io_complete */
softdep_deallocate_dependencies, /* io_deallocate */
softdep_fsync, /* io_fsync */
softdep_process_worklist, /* io_sync */
};

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.105 1998/07/15 02:32:13 bde Exp $
* $Id: vfs_syscalls.c,v 1.106 1998/09/10 02:27:52 tegge Exp $
*/
/* For 4.3 integer FS ID compatibility */
@ -1818,10 +1818,7 @@ setfflags(p, vp, flags)
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_flags = flags;
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
@ -1892,12 +1889,9 @@ setfmode(p, vp, mode)
{
int error;
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_mode = mode & ALLPERMS;
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
@ -1998,12 +1992,9 @@ setfown(p, vp, uid, gid)
{
int error;
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_uid = uid;
vattr.va_gid = gid;
@ -2115,11 +2106,7 @@ setutimes(p, vp, tv, nullflag)
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_atime.tv_sec = tv[0].tv_sec;
vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
@ -2421,22 +2408,14 @@ fsync(p, uap)
if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) == NULL) {
if (vp->v_object) {
vm_object_page_clean(vp->v_object, 0, 0, FALSE);
}
if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP)) {
error = VOP_FSYNC(vp, fp->f_cred, MNT_LAZY, p);
} else {
error = VOP_FSYNC(vp, fp->f_cred,
(vp->v_mount && (vp->v_mount->mnt_flag & MNT_ASYNC)) ?
MNT_NOWAIT : MNT_WAIT, p);
}
VOP_UNLOCK(vp, 0, p);
if ((vp->v_mount->mnt_flag & MNT_SOFTDEP) && bioops.io_sync)
(*bioops.io_sync)(NULL);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_object)
vm_object_page_clean(vp->v_object, 0, 0, FALSE);
if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 &&
vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) &&
bioops.io_fsync)
error = (*bioops.io_fsync)(vp);
VOP_UNLOCK(vp, 0, p);
return (error);
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.105 1998/07/15 02:32:13 bde Exp $
* $Id: vfs_syscalls.c,v 1.106 1998/09/10 02:27:52 tegge Exp $
*/
/* For 4.3 integer FS ID compatibility */
@ -1818,10 +1818,7 @@ setfflags(p, vp, flags)
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_flags = flags;
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
@ -1892,12 +1889,9 @@ setfmode(p, vp, mode)
{
int error;
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_mode = mode & ALLPERMS;
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
@ -1998,12 +1992,9 @@ setfown(p, vp, uid, gid)
{
int error;
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_uid = uid;
vattr.va_gid = gid;
@ -2115,11 +2106,7 @@ setutimes(p, vp, tv, nullflag)
struct vattr vattr;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
if (error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) {
return error;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
VATTR_NULL(&vattr);
vattr.va_atime.tv_sec = tv[0].tv_sec;
vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
@ -2421,22 +2408,14 @@ fsync(p, uap)
if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp))
return (error);
vp = (struct vnode *)fp->f_data;
if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p)) == NULL) {
if (vp->v_object) {
vm_object_page_clean(vp->v_object, 0, 0, FALSE);
}
if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP)) {
error = VOP_FSYNC(vp, fp->f_cred, MNT_LAZY, p);
} else {
error = VOP_FSYNC(vp, fp->f_cred,
(vp->v_mount && (vp->v_mount->mnt_flag & MNT_ASYNC)) ?
MNT_NOWAIT : MNT_WAIT, p);
}
VOP_UNLOCK(vp, 0, p);
if ((vp->v_mount->mnt_flag & MNT_SOFTDEP) && bioops.io_sync)
(*bioops.io_sync)(NULL);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_object)
vm_object_page_clean(vp->v_object, 0, 0, FALSE);
if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 &&
vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) &&
bioops.io_fsync)
error = (*bioops.io_fsync)(vp);
VOP_UNLOCK(vp, 0, p);
return (error);
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)buf.h 8.9 (Berkeley) 3/30/95
* $Id: buf.h,v 1.55 1998/09/05 14:13:12 phk Exp $
* $Id: buf.h,v 1.56 1998/09/15 08:55:01 gibbs Exp $
*/
#ifndef _SYS_BUF_H_
@ -48,6 +48,7 @@
struct buf;
struct mount;
struct vnode;
/*
* To avoid including <ufs/ffs/softdep.h>
@ -63,6 +64,7 @@ extern struct bio_ops {
void (*io_start) __P((struct buf *));
void (*io_complete) __P((struct buf *));
void (*io_deallocate) __P((struct buf *));
int (*io_fsync) __P((struct vnode *));
int (*io_sync) __P((struct mount *));
} bioops;

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)buf.h 8.9 (Berkeley) 3/30/95
* $Id: buf.h,v 1.55 1998/09/05 14:13:12 phk Exp $
* $Id: buf.h,v 1.56 1998/09/15 08:55:01 gibbs Exp $
*/
#ifndef _SYS_BUF_H_
@ -48,6 +48,7 @@
struct buf;
struct mount;
struct vnode;
/*
* To avoid including <ufs/ffs/softdep.h>
@ -63,6 +64,7 @@ extern struct bio_ops {
void (*io_start) __P((struct buf *));
void (*io_complete) __P((struct buf *));
void (*io_deallocate) __P((struct buf *));
int (*io_fsync) __P((struct vnode *));
int (*io_sync) __P((struct mount *));
} bioops;

View File

@ -54,7 +54,7 @@
* SUCH DAMAGE.
*
* from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98
* $Id: ffs_softdep.c,v 1.12 1998/06/12 21:21:26 julian Exp $
* $Id: ffs_softdep.c,v 1.13 1998/08/12 20:46:47 julian Exp $
*/
/*
@ -209,6 +209,7 @@ struct bio_ops bioops = {
softdep_disk_io_initiation, /* io_start */
softdep_disk_write_complete, /* io_complete */
softdep_deallocate_dependencies, /* io_deallocate */
softdep_fsync, /* io_fsync */
softdep_process_worklist, /* io_sync */
};

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95
* $Id: ffs_vnops.c,v 1.50 1998/06/10 19:27:56 julian Exp $
* $Id: ffs_vnops.c,v 1.51 1998/09/07 11:50:19 bde Exp $
*/
#include <sys/param.h>
@ -249,9 +249,5 @@ loop2:
}
splx(s);
getmicrotime(&tv);
if ((error = UFS_UPDATE(vp, &tv, &tv, ap->a_waitfor == MNT_WAIT)) != 0)
return (error);
if (DOINGSOFTDEP(vp) && ap->a_waitfor == MNT_WAIT)
error = softdep_fsync(vp);
return (error);
return (UFS_UPDATE(vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
}