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:
parent
de77c42832
commit
e266594c25
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user