MFC Revs 1.237, 1.236, 1.234

VFS SMP fixes, stack api, softupdates fixes.

Sponsored by:	Isilon Systems, Inc.
Approved by:	re (scottl)
This commit is contained in:
jeff 2006-03-13 03:06:44 +00:00
parent d4dc0bfa32
commit d5d2e86c35

View File

@ -779,18 +779,10 @@ vn_poll(fp, events, active_cred, td)
* acquire requested lock.
*/
int
#ifndef DEBUG_LOCKS
vn_lock(vp, flags, td)
#else
debug_vn_lock(vp, flags, td, filename, line)
#endif
struct vnode *vp;
int flags;
struct thread *td;
#ifdef DEBUG_LOCKS
const char *filename;
int line;
#endif
{
int error;
@ -809,10 +801,6 @@ debug_vn_lock(vp, flags, td, filename, line)
VI_UNLOCK(vp);
return (0);
}
#ifdef DEBUG_LOCKS
vp->filename = filename;
vp->line = line;
#endif
/*
* lockmgr drops interlock before it will return for
* any reason. So force the code above to relock it.
@ -962,6 +950,58 @@ vn_write_suspend_wait(vp, mp, flags)
(PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0));
}
/*
* Secondary suspension. Used by operations such as vop_inactive
* routines that are needed by the higher level functions. These
* are allowed to proceed until all the higher level functions have
* completed (indicated by mnt_writeopcount dropping to zero). At that
* time, these operations are halted until the suspension is over.
*/
int
vn_start_secondary_write(vp, mpp, flags)
struct vnode *vp;
struct mount **mpp;
int flags;
{
struct mount *mp;
int error;
retry:
if (vp != NULL) {
if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
*mpp = NULL;
if (error != EOPNOTSUPP)
return (error);
return (0);
}
}
/*
* If we are not suspended or have not yet reached suspended
* mode, then let the operation proceed.
*/
if ((mp = *mpp) == NULL)
return (0);
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) {
mp->mnt_secondary_writes++;
mp->mnt_secondary_accwrites++;
MNT_IUNLOCK(mp);
return (0);
}
if (flags & V_NOWAIT) {
MNT_IUNLOCK(mp);
return (EWOULDBLOCK);
}
/*
* Wait for the suspension to finish.
*/
error = msleep(&mp->mnt_flag, MNT_MTX(mp),
(PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0);
if (error == 0)
goto retry;
return (error);
}
/*
* Filesystem write operation has completed. If we are suspending and this
* operation is the last one, notify the suspender that the suspension is
@ -983,6 +1023,30 @@ vn_finished_write(mp)
MNT_IUNLOCK(mp);
}
/*
* Filesystem secondary write operation has completed. If we are
* suspending and this operation is the last one, notify the suspender
* that the suspension is now in effect.
*/
void
vn_finished_secondary_write(mp)
struct mount *mp;
{
if (mp == NULL)
return;
MNT_ILOCK(mp);
mp->mnt_secondary_writes--;
if (mp->mnt_secondary_writes < 0)
panic("vn_finished_secondary_write: neg cnt");
if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 &&
mp->mnt_secondary_writes <= 0)
wakeup(&mp->mnt_secondary_writes);
MNT_IUNLOCK(mp);
}
/*
* Request a filesystem to suspend write operations.
*/
@ -1003,12 +1067,11 @@ vfs_write_suspend(mp)
MNT_MTX(mp), (PUSER - 1)|PDROP, "suspwt", 0);
else
MNT_IUNLOCK(mp);
if ((error = VFS_SYNC(mp, MNT_WAIT, td)) != 0) {
if ((error = VFS_SYNC(mp, MNT_SUSPEND, td)) != 0) {
vfs_write_resume(mp);
return (error);
}
MNT_ILOCK(mp);
mp->mnt_kern_flag |= MNTK_SUSPENDED;
unlock:
MNT_IUNLOCK(mp);
return (error);
@ -1024,7 +1087,8 @@ vfs_write_resume(mp)
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
mp->mnt_kern_flag &= ~(MNTK_SUSPEND | MNTK_SUSPENDED);
mp->mnt_kern_flag &= ~(MNTK_SUSPEND | MNTK_SUSPEND2 |
MNTK_SUSPENDED);
wakeup(&mp->mnt_writeopcount);
wakeup(&mp->mnt_flag);
}