Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Sep 1998 13:51:20 -0700
From:      Kirk McKusick <mckusick@McKusick.COM>
To:        Luoqi Chen <luoqi@watermarkgroup.com>
Cc:        Don.Lewis@tsc.tdk.com, current@FreeBSD.ORG
Subject:   Re: Yet another patch to try for softupdates panic 
Message-ID:  <199809222051.NAA14655@flamingo.McKusick.COM>
In-Reply-To: Your message of "Tue, 22 Sep 1998 18:11:27 EDT." <199809222211.SAA04717@lor.watermarkgroup.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
	Date: Tue, 22 Sep 1998 18:11:27 -0400 (EDT)
	From: Luoqi Chen <luoqi@watermarkgroup.com>
	To: luoqi@watermarkgroup.com, mckusick@McKusick.COM
	Subject: Re: Yet another patch to try for softupdates panic
	Cc: Don.Lewis@tsc.tdk.com, current@freebsd.org

	> In case (2), the fsync() syscall does call VOP_FSYNC with MNT_WAIT
	> and you most definitely *must* write out the parent directory
	> entries! When the fsync system call returns, it ensures that
	> the entire file, including its name, is on stable storage.
	> 
	> 	Kirk McKusick
	> 
	That's not what I see in FreeBSD's code. Here is the fsync() function
	copied from kern/vfs_syscalls.c [rev1.106],

int
fsync(p, uap)
	struct proc *p;
	struct fsync_args /* {
		syscallarg(int) fd;
	} */ *uap;
{
	register struct vnode *vp;
	struct file *fp;
	int error;

	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_ASY
NC)) ?
				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);
	}
	return (error);
}

	Ok, I did a little digging through the CVS log, the waitfor flag
	was changed to MNT_LAZY by John Dyson in March with the following
	log message:

	    Correct a significant problem with the softupdates
	    port.  Allow fsync to work properly within the softupdates
	    framework, and thereby eliminate some unfortunate panics.

	Does anyone know what significant problem John was refering to?

	-lq

That is very strange. The code that I put in was:

int
fsync(p, uap)
	struct proc *p;
	struct fsync_args /* {
		syscallarg(int) fd;
	} */ *uap;
{
	register struct vnode *vp;
	struct file *fp;
	int error;

	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);
		}
		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);
	}
	return (error);
}

The whole point of adding softdep_fsync was specifically to make sure
that the name got sync'ed when the user did an fsync syscall. Also the
addition of a call to bioops.io_sync is totally gratuitous and indeed
will cause terrible performance problems if fsyncs occur too rapidly.
I really wish that people that make changes that affect the soft update
code would at least send me the diffs before they commit them so I can
catch blatent errors like the change you sent me. Sigh.

I do think that you are moving in the right direction towards resolving
the problem. Specifically, I think that what we need to do is to break
softdep_fsync out of VOP_FSYNC and call it separately in those places
where it is really needed and desired. That way VOP_FSYNC will not 
violate the locking rule on the vnode with which it is called. I am
plowing through the list that you made to check whether there are any
other cases beside the fsync system call where softdep_fsync is needed.

	Kirk McKusick

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809222051.NAA14655>