Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
diff -urBN /usr/src.orig/sys/fs/unionfs/union_subr.c /usr/src/sys/fs/unionfs/union_subr.c
--- /usr/src.orig/sys/fs/unionfs/union_subr.c Fri Oct 27 09:37:10 2006
+++ /usr/src/sys/fs/unionfs/union_subr.c Mon Jan 29 19:24:44 2007
@@ -1105,6 +1105,12 @@
return (0);
/* open vnode */
+#ifdef MAC
+ if ((error = mac_check_vnode_open(cred, vp, VEXEC|VREAD)) != 0)
+ return (error);
+#endif
+ if ((error = VOP_ACCESS(vp, VEXEC|VREAD, cred, td)) != 0)
+ return (error);
if ((error = VOP_OPEN(vp, FREAD, cred, td, -1)) != 0)
return (error);
diff -urBN /usr/src.orig/sys/fs/unionfs/union_vfsops.c /usr/src/sys/fs/unionfs/union_vfsops.c
--- /usr/src.orig/sys/fs/unionfs/union_vfsops.c Sun Dec 10 02:24:18 2006
+++ /usr/src/sys/fs/unionfs/union_vfsops.c Sat Jan 27 19:25:58 2007
@@ -288,6 +288,11 @@
ump->um_ufile = ufile;
ump->um_copymode = copymode;
+ MNT_ILOCK(mp);
+ if ((lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE) &&
+ (upperrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE))
+ mp->mnt_kern_flag |= MNTK_MPSAFE;
+ MNT_IUNLOCK(mp);
mp->mnt_data = (qaddr_t)ump;
/*
diff -urBN /usr/src.orig/sys/fs/unionfs/union_vnops.c /usr/src/sys/fs/unionfs/union_vnops.c
--- /usr/src.orig/sys/fs/unionfs/union_vnops.c Fri Oct 27 09:37:11 2006
+++ /usr/src/sys/fs/unionfs/union_vnops.c Tue Jan 30 13:13:49 2007
@@ -874,6 +874,7 @@
unp = VTOUNIONFS(ap->a_vp);
unionfs_get_node_status(unp, ap->a_td, &unsp);
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
+ unionfs_tryrem_node_status(unp, ap->a_td, unsp);
VOP_UNLOCK(ap->a_vp, 0, ap->a_td);
if (ovp == NULLVP)
@@ -898,6 +899,7 @@
unp = VTOUNIONFS(ap->a_vp);
unionfs_get_node_status(unp, ap->a_td, &unsp);
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
+ unionfs_tryrem_node_status(unp, ap->a_td, unsp);
VOP_UNLOCK(ap->a_vp, 0, ap->a_td);
if (ovp == NULLVP)
@@ -916,6 +918,7 @@
unp = VTOUNIONFS(ap->a_vp);
unionfs_get_node_status(unp, ap->a_td, &unsp);
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
+ unionfs_tryrem_node_status(unp, ap->a_td, unsp);
if (ovp == NULLVP)
return (EBADF);
@@ -1386,41 +1389,41 @@
/* check opaque */
if (uvp != NULLVP && lvp != NULLVP) {
if ((error = VOP_GETATTR(uvp, &va, ap->a_cred, td)) != 0)
- return (error);
+ goto unionfs_readdir_exit;
if (va.va_flags & OPAQUE)
lvp = NULLVP;
}
+ /* check the open count. unionfs needs to open before readdir. */
if (VOP_ISLOCKED(ap->a_vp, td) != LK_EXCLUSIVE) {
vn_lock(ap->a_vp, LK_UPGRADE | LK_RETRY, td);
locked = 1;
}
- unionfs_get_node_status(unp, curthread, &unsp);
+ unionfs_get_node_status(unp, td, &unsp);
+ if ((uvp != NULLVP && unsp->uns_upper_opencnt <= 0) ||
+ (lvp != NULLVP && unsp->uns_lower_opencnt <= 0)) {
+ unionfs_tryrem_node_status(unp, td, unsp);
+ error = EBADF;
+ }
if (locked == 1)
vn_lock(ap->a_vp, LK_DOWNGRADE | LK_RETRY, td);
+ if (error != 0)
+ goto unionfs_readdir_exit;
/* upper only */
if (uvp != NULLVP && lvp == NULLVP) {
- if (unsp->uns_upper_opencnt <= 0)
- error = EBADF;
- else {
- error = VOP_READDIR(uvp, uio, ap->a_cred, ap->a_eofflag,
- ap->a_ncookies, ap->a_cookies);
- unsp->uns_readdir_status = 0;
- }
+ error = VOP_READDIR(uvp, uio, ap->a_cred, ap->a_eofflag,
+ ap->a_ncookies, ap->a_cookies);
+ unsp->uns_readdir_status = 0;
goto unionfs_readdir_exit;
}
/* lower only */
if (uvp == NULLVP && lvp != NULLVP) {
- if (unsp->uns_lower_opencnt <= 0)
- error = EBADF;
- else {
- error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag,
- ap->a_ncookies, ap->a_cookies);
- unsp->uns_readdir_status = 2;
- }
+ error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag,
+ ap->a_ncookies, ap->a_cookies);
+ unsp->uns_readdir_status = 2;
goto unionfs_readdir_exit;
}
@@ -1428,11 +1431,6 @@
/*
* readdir upper and lower
*/
- if (unsp->uns_lower_opencnt <= 0 || unsp->uns_upper_opencnt <= 0) {
- error = EBADF;
- goto unionfs_readdir_exit;
- }
-
if (uio->uio_offset == 0)
unsp->uns_readdir_status = 0;
@@ -1441,10 +1439,8 @@
error = VOP_READDIR(uvp, uio, ap->a_cred, &eofflag,
ap->a_ncookies, ap->a_cookies);
- if (error != 0 || eofflag == 0) {
- UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error);
- return (error);
- }
+ if (error != 0 || eofflag == 0)
+ goto unionfs_readdir_exit;
unsp->uns_readdir_status = 1;
/*
@@ -1453,10 +1449,8 @@
* size of DIRBLKSIZ equals DEV_BSIZE.
* (see: ufs/ufs/ufs_vnops.c ufs_readdir func , ufs/ufs/dir.h)
*/
- if (uio->uio_resid <= (uio->uio_resid & (DEV_BSIZE -1))) {
- UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error);
- return (0);
- }
+ if (uio->uio_resid <= (uio->uio_resid & (DEV_BSIZE -1)))
+ goto unionfs_readdir_exit;
/*
* backup cookies
@@ -1506,6 +1500,9 @@
}
unionfs_readdir_exit:
+ if (error != 0 && ap->a_eofflag != NULL)
+ *(ap->a_eofflag) = 1;
+
UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error);
return (error);
@@ -1858,7 +1855,8 @@
unsp->uns_upper_opencnt++;
VOP_CLOSE(unp->un_lowervp, unsp->uns_lower_openmode, td->td_ucred, td);
unsp->uns_lower_opencnt--;
- }
+ } else
+ unionfs_tryrem_node_status(unp, td, unsp);
}
VOP_UNLOCK(vp, 0, td);