Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F175696532
D27789.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D27789.diff
View Options
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -3736,8 +3736,8 @@
#define CACHE_FPL_SUPPORTED_CN_FLAGS \
(NC_NOMAKEENTRY | NC_KEEPPOSENTRY | LOCKLEAF | LOCKPARENT | WANTPARENT | \
- FOLLOW | LOCKSHARED | SAVENAME | SAVESTART | WILLBEDIR | ISOPEN | \
- NOMACCHECK | AUDITVNODE1 | AUDITVNODE2 | NOCAPCHECK)
+ FAILIFEXISTS | FOLLOW | LOCKSHARED | SAVENAME | SAVESTART | WILLBEDIR | \
+ ISOPEN | NOMACCHECK | AUDITVNODE1 | AUDITVNODE2 | NOCAPCHECK)
#define CACHE_FPL_INTERNAL_CN_FLAGS \
(ISDOTDOT | MAKEENTRY | ISLASTCN)
@@ -3990,6 +3990,11 @@
return (cache_fpl_handled(fpl, EROFS));
}
+ if (fpl->tvp != NULL && (cnp->cn_flags & FAILIFEXISTS) != 0) {
+ cache_fpl_smr_exit(fpl);
+ return (cache_fpl_handled(fpl, EEXIST));
+ }
+
/*
* Secure access to dvp; check cache_fplookup_partial_setup for
* reasoning.
@@ -4070,6 +4075,12 @@
return (cache_fpl_aborted(fpl));
}
+ if ((cnp->cn_flags & FAILIFEXISTS) != 0) {
+ vput(dvp);
+ vput(tvp);
+ return (cache_fpl_handled(fpl, EEXIST));
+ }
+
if ((cnp->cn_flags & LOCKLEAF) == 0) {
VOP_UNLOCK(tvp);
}
@@ -4221,6 +4232,7 @@
MPASS(!cache_fpl_isdotdot(cnp));
if (cnp->cn_nameiop != LOOKUP) {
+ fpl->tvp = NULL;
return (cache_fplookup_modifying(fpl));
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -545,6 +545,16 @@
ndp->ni_debugflags |= NAMEI_DBG_CALLED;
if (ndp->ni_startdir != NULL)
ndp->ni_debugflags |= NAMEI_DBG_HADSTARTDIR;
+ if (cnp->cn_flags & FAILIFEXISTS) {
+ KASSERT(cnp->cn_nameiop == CREATE,
+ ("%s: FAILIFEXISTS passed for op %d", __func__, cnp->cn_nameiop));
+ /*
+ * The limitation below is to restrict hairy corner cases.
+ */
+ KASSERT((cnp->cn_flags & (LOCKPARENT | LOCKLEAF)) == LOCKPARENT,
+ ("%s: FAILIFEXISTS must be passed with LOCKPARENT and without LOCKLEAF",
+ __func__));
+ }
/*
* For NDVALIDATE.
*
@@ -1295,8 +1305,11 @@
goto bad2;
}
}
- if (ndp->ni_vp != NULL && ndp->ni_vp->v_type == VDIR)
+ if (ndp->ni_vp != NULL) {
nameicap_tracker_add(ndp, ndp->ni_vp);
+ if ((cnp->cn_flags & (FAILIFEXISTS | ISSYMLINK)) == FAILIFEXISTS)
+ goto bad_eexist;
+ }
return (0);
bad2:
@@ -1311,6 +1324,24 @@
vput(dp);
ndp->ni_vp = NULL;
return (error);
+bad_eexist:
+ /*
+ * FAILIFEXISTS handling.
+ *
+ * XXX namei called with LOCKPARENT but not LOCKLEAF has the strange
+ * behaviour of leaving the vnode unlocked if the target is the same
+ * vnode as the parent.
+ */
+ MPASS((cnp->cn_flags & ISSYMLINK) == 0);
+ if (ndp->ni_vp == ndp->ni_dvp)
+ vrele(ndp->ni_dvp);
+ else
+ vput(ndp->ni_dvp);
+ vrele(ndp->ni_vp);
+ ndp->ni_dvp = NULL;
+ ndp->ni_vp = NULL;
+ NDFREE(ndp, NDF_ONLY_PNBUF);
+ return (EEXIST);
}
/*
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
@@ -3768,7 +3768,6 @@
int mode)
{
struct mount *mp;
- struct vnode *vp;
struct vattr vattr;
struct nameidata nd;
int error;
@@ -3777,26 +3776,11 @@
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
- NC_NOMAKEENTRY | NC_KEEPPOSENTRY, segflg, path, fd,
+ NC_NOMAKEENTRY | NC_KEEPPOSENTRY | FAILIFEXISTS, segflg, path, fd,
&cap_mkdirat_rights, td);
nd.ni_cnd.cn_flags |= WILLBEDIR;
if ((error = namei(&nd)) != 0)
return (error);
- vp = nd.ni_vp;
- if (vp != NULL) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- /*
- * XXX namei called with LOCKPARENT but not LOCKLEAF has
- * the strange behaviour of leaving the vnode unlocked
- * if the target is the same vnode as the parent.
- */
- if (vp == nd.ni_dvp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- vrele(vp);
- return (EEXIST);
- }
if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_dvp);
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -143,7 +143,7 @@
#define LOCKLEAF 0x0004 /* lock vnode on return */
#define LOCKPARENT 0x0008 /* want parent vnode returned locked */
#define WANTPARENT 0x0010 /* want parent vnode returned unlocked */
-/* UNUSED 0x0020 */
+#define FAILIFEXISTS 0x0020 /* return EEXIST if found */
#define FOLLOW 0x0040 /* follow symbolic links */
#define BENEATH 0x0080 /* No escape from the start dir */
#define LOCKSHARED 0x0100 /* Shared lock leaf */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 13, 2:38 PM (14 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40755632
Default Alt Text
D27789.diff (4 KB)
Attached To
Mode
D27789: vfs: add FAILIFEXISTS flag
Attached
Detach File
Event Timeline
Log In to Comment