diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index e2c02f3ff72b..97f301cd0b93 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnops.c,v 1.94 2005/07/23 18:19:51 erh Exp $ */ +/* $NetBSD: vfs_vnops.c,v 1.95 2005/09/20 09:49:01 yamt Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.94 2005/07/23 18:19:51 erh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.95 2005/09/20 09:49:01 yamt Exp $"); #include "opt_verified_exec.h" @@ -906,3 +906,93 @@ vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace, return (error); } + +/* + * Preparing to start a filesystem write operation. If the operation is + * permitted, then we bump the count of operations in progress and + * proceed. If a suspend request is in progress, we wait until the + * suspension is over, and then proceed. + * V_PCATCH adds PCATCH to the tsleep flags. + * V_WAIT waits until suspension is over. Otherwise returns EWOULDBLOCK. + * V_SLEEPONLY wait, but do not bump the operations count. + * V_LOWER this is a lower level operation. No further vnodes should be + * locked. Otherwise it is a upper level operation. No vnodes + * should be locked. + */ +int +vn_start_write(struct vnode *vp, struct mount **mpp, int flags) +{ + struct mount *mp; + int error, mask, prio; + + /* + * If a vnode is provided, get and return the mount point that + * to which it will write. + */ + if (vp != NULL) { + *mpp = vp->v_mount; + } + if ((mp = *mpp) == NULL) + return (0); + mp = mp->mnt_leaf; + /* + * Check on status of suspension. + */ + prio = PUSER - 1; + if (flags & V_PCATCH) + prio |= PCATCH; + + if ((flags & V_LOWER) == 0) + mask = IMNT_SUSPEND; + else + mask = IMNT_SUSPENDLOW; + + while ((mp->mnt_iflag & mask) != 0) { + if ((flags & V_WAIT) == 0) + return (EWOULDBLOCK); + error = tsleep(&mp->mnt_flag, prio, "suspfs", 0); + if (error) + return (error); + } + if (flags & V_SLEEPONLY) + return (0); + simple_lock(&mp->mnt_slock); + if ((flags & V_LOWER) == 0) + mp->mnt_writeopcountupper++; + else + mp->mnt_writeopcountlower++; + simple_unlock(&mp->mnt_slock); + return (0); +} + +/* + * Filesystem 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_write(struct mount *mp, int flags) +{ + if (mp == NULL) + return; + mp = mp->mnt_leaf; + simple_lock(&mp->mnt_slock); + if ((flags & V_LOWER) == 0) { + mp->mnt_writeopcountupper--; + if (mp->mnt_writeopcountupper < 0) + printf("vn_finished_write: neg cnt upper=%d\n", + mp->mnt_writeopcountupper); + if ((mp->mnt_iflag & IMNT_SUSPEND) != 0 && + mp->mnt_writeopcountupper <= 0) + wakeup(&mp->mnt_writeopcountupper); + } else { + mp->mnt_writeopcountlower--; + if (mp->mnt_writeopcountlower < 0) + printf("vn_finished_write: neg cnt lower=%d\n", + mp->mnt_writeopcountlower); + if ((mp->mnt_iflag & IMNT_SUSPENDLOW) != 0 && + mp->mnt_writeopcountupper <= 0) + wakeup(&mp->mnt_writeopcountlower); + } + simple_unlock(&mp->mnt_slock); +} diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 5f672ff0d149..4697b63746cb 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.143 2005/09/10 19:20:51 jmmv Exp $ */ +/* $NetBSD: vnode.h,v 1.144 2005/09/20 09:49:01 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -550,95 +550,8 @@ struct vop_generic_args { */ #include -/* - * Preparing to start a filesystem write operation. If the operation is - * permitted, then we bump the count of operations in progress and - * proceed. If a suspend request is in progress, we wait until the - * suspension is over, and then proceed. - * V_PCATCH adds PCATCH to the tsleep flags. - * V_WAIT waits until suspension is over. Otherwise returns EWOULDBLOCK. - * V_SLEEPONLY wait, but do not bump the operations count. - * V_LOWER this is a lower level operation. No further vnodes should be - * locked. Otherwise it is a upper level operation. No vnodes - * should be locked. - */ -static inline int -vn_start_write(struct vnode *vp, struct mount **mpp, int flags) -{ - struct mount *mp; - int error, mask, prio; - - /* - * If a vnode is provided, get and return the mount point that - * to which it will write. - */ - if (vp != NULL) { - *mpp = vp->v_mount; - } - if ((mp = *mpp) == NULL) - return (0); - mp = mp->mnt_leaf; - /* - * Check on status of suspension. - */ - prio = PUSER - 1; - if (flags & V_PCATCH) - prio |= PCATCH; - - if ((flags & V_LOWER) == 0) - mask = IMNT_SUSPEND; - else - mask = IMNT_SUSPENDLOW; - - while ((mp->mnt_iflag & mask) != 0) { - if ((flags & V_WAIT) == 0) - return (EWOULDBLOCK); - error = tsleep(&mp->mnt_flag, prio, "suspfs", 0); - if (error) - return (error); - } - if (flags & V_SLEEPONLY) - return (0); - simple_lock(&mp->mnt_slock); - if ((flags & V_LOWER) == 0) - mp->mnt_writeopcountupper++; - else - mp->mnt_writeopcountlower++; - simple_unlock(&mp->mnt_slock); - return (0); -} - -/* - * Filesystem 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. - */ -static inline void -vn_finished_write(struct mount *mp, int flags) -{ - if (mp == NULL) - return; - mp = mp->mnt_leaf; - simple_lock(&mp->mnt_slock); - if ((flags & V_LOWER) == 0) { - mp->mnt_writeopcountupper--; - if (mp->mnt_writeopcountupper < 0) - printf("vn_finished_write: neg cnt upper=%d\n", - mp->mnt_writeopcountupper); - if ((mp->mnt_iflag & IMNT_SUSPEND) != 0 && - mp->mnt_writeopcountupper <= 0) - wakeup(&mp->mnt_writeopcountupper); - } else { - mp->mnt_writeopcountlower--; - if (mp->mnt_writeopcountlower < 0) - printf("vn_finished_write: neg cnt lower=%d\n", - mp->mnt_writeopcountlower); - if ((mp->mnt_iflag & IMNT_SUSPENDLOW) != 0 && - mp->mnt_writeopcountupper <= 0) - wakeup(&mp->mnt_writeopcountlower); - } - simple_unlock(&mp->mnt_slock); -} +int vn_start_write(struct vnode *, struct mount **, int); +void vn_finished_write(struct mount *, int); /* * Finally, include the default set of vnode operations.