Page MenuHomeFreeBSD

D39441.id119964.diff
No OneTemporary

D39441.id119964.diff

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -601,7 +601,8 @@
if (error)
goto error;
vp = nd.ni_vp;
- if (vp != NULL || vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vp != NULL || vn_start_write(nd.ni_dvp, &mp, V_NOWAIT |
+ V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
if (nd.ni_dvp == vp)
vrele(nd.ni_dvp);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1386,7 +1386,7 @@
panic("kern_mknod: invalid mode");
}
}
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
@@ -1473,7 +1473,7 @@
vrele(nd.ni_vp);
return (EEXIST);
}
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
@@ -1654,7 +1654,7 @@
NDFREE_PNBUF(&nd);
return (error);
}
- error = vn_start_write(vp, &mp, V_NOWAIT);
+ error = vn_start_write(vp, &mp, V_NOWAIT | V_FORXSLEEP);
if (error != 0) {
vput(vp);
vput(nd.ni_dvp);
@@ -1752,7 +1752,7 @@
error = EEXIST;
goto out;
}
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
@@ -1817,7 +1817,7 @@
vrele(nd.ni_vp);
return (EEXIST);
}
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
@@ -1945,7 +1945,8 @@
error = EBUSY;
}
if (error == 0) {
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT |
+ V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if (vp == nd.ni_dvp)
@@ -3699,7 +3700,7 @@
}
tdvp = tond.ni_dvp;
tvp = tond.ni_vp;
- error = vn_start_write(fvp, &mp, V_NOWAIT);
+ error = vn_start_write(fvp, &mp, V_NOWAIT | V_FORXSLEEP);
if (error != 0) {
NDFREE_PNBUF(&fromnd);
NDFREE_PNBUF(&tond);
@@ -3828,7 +3829,7 @@
segflg, path, fd, &cap_mkdirat_rights);
if ((error = namei(&nd)) != 0)
return (error);
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
@@ -3933,7 +3934,7 @@
if (error != 0)
goto out;
#endif
- if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(vp);
if (nd.ni_dvp == vp)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -267,7 +267,8 @@
vap->va_mode = cmode;
if (fmode & O_EXCL)
vap->va_vaflags |= VA_EXCLUSIVE;
- if (vn_start_write(ndp->ni_dvp, &mp, V_NOWAIT) != 0) {
+ if (vn_start_write(ndp->ni_dvp, &mp, V_NOWAIT |
+ V_FORXSLEEP) != 0) {
NDFREE_PNBUF(ndp);
vput(ndp->ni_dvp);
if ((error = vn_start_write(NULL, &mp,
@@ -1848,11 +1849,13 @@
* suspension is over, and then proceed.
*/
static int
-vn_start_write_refed(struct mount *mp, int flags, bool mplocked)
+vn_start_write_refed(struct mount **mpp, int flags, bool mplocked)
{
struct mount_pcpu *mpcpu;
+ struct mount *mp;
int error, mflags;
+ mp = *mpp;
if (__predict_true(!mplocked) && (flags & V_XSLEEP) == 0 &&
vfs_op_thread_enter(mp, mpcpu)) {
MPASS((mp->mnt_kern_flag & MNTK_SUSPEND) == 0);
@@ -1880,14 +1883,18 @@
}
mflags |= (PUSER - 1);
while ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
- if (flags & V_NOWAIT) {
+ if ((flags & V_NOWAIT) != 0) {
+ if ((flags & V_FORXSLEEP) == 0)
+ *mpp = NULL;
error = EWOULDBLOCK;
goto unlock;
}
error = msleep(&mp->mnt_flag, MNT_MTX(mp), mflags,
"suspfs", 0);
- if (error)
+ if (error != 0) {
+ *mpp = NULL;
goto unlock;
+ }
}
}
if (flags & V_XSLEEP)
@@ -1908,6 +1915,7 @@
KASSERT((flags & ~V_VALID_FLAGS) == 0,
("%s: invalid flags passed %d\n", __func__, flags));
+ MPASS((flags & (V_FORXSLEEP | V_NOWAIT)) != V_FORXSLEEP);
error = 0;
/*
@@ -1935,7 +1943,7 @@
if (vp == NULL)
vfs_ref(mp);
- return (vn_start_write_refed(mp, flags, false));
+ return (vn_start_write_refed(mpp, flags, false));
}
/*
@@ -1951,7 +1959,7 @@
struct mount *mp;
int error, mflags;
- KASSERT((flags & ~V_VALID_FLAGS) == 0,
+ KASSERT((flags & (~V_VALID_FLAGS | V_XSLEEP | V_FORXSLEEP)) == 0,
("%s: invalid flags passed %d\n", __func__, flags));
retry:
@@ -1989,6 +1997,7 @@
if (flags & V_NOWAIT) {
MNT_REL(mp);
MNT_IUNLOCK(mp);
+ *mpp = NULL;
return (EWOULDBLOCK);
}
/*
@@ -2004,6 +2013,7 @@
vfs_rel(mp);
if (error == 0)
goto retry;
+ *mpp = NULL;
return (error);
}
@@ -2140,7 +2150,7 @@
vfs_op_exit(mp);
} else if ((flags & VR_START_WRITE) != 0) {
MNT_REF(mp);
- vn_start_write_refed(mp, 0, true);
+ vn_start_write_refed(&mp, 0, true);
} else {
MNT_IUNLOCK(mp);
}
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -409,7 +409,8 @@
#define V_NOWAIT 0x0002 /* vn_start_write: don't sleep for suspend */
#define V_XSLEEP 0x0004 /* vn_start_write: just return after sleep */
#define V_PCATCH 0x0008 /* vn_start_write: make the sleep interruptible */
-#define V_VALID_FLAGS (V_WAIT | V_NOWAIT | V_XSLEEP | V_PCATCH)
+#define V_FORXSLEEP 0x0010 /* vn_start_write: keep *mpp for V_XSLEEP */
+#define V_VALID_FLAGS (V_WAIT | V_NOWAIT | V_XSLEEP | V_PCATCH | V_FORXSLEEP)
#define VR_START_WRITE 0x0001 /* vfs_write_resume: start write atomically */
#define VR_NO_SUSPCLR 0x0002 /* vfs_write_resume: do not clear suspension */
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -273,7 +273,7 @@
if (wrtmp != mp)
panic("ffs_snapshot: mount mismatch");
vfs_rel(wrtmp);
- if (vn_start_write(NULL, &wrtmp, V_NOWAIT) != 0) {
+ if (vn_start_write(NULL, &wrtmp, V_NOWAIT | V_FORXSLEEP) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
if ((error = vn_start_write(NULL, &wrtmp,

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 9, 8:15 PM (6 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38609189
Default Alt Text
D39441.id119964.diff (6 KB)

Event Timeline