Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164452924
D57658.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D57658.diff
View Options
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
@@ -3752,12 +3752,13 @@
#ifdef MAC
static int
kern_renameat_mac(struct thread *td, int oldfd, const char *old, int newfd,
- const char *new, enum uio_seg pathseg, struct nameidata *fromnd)
+ const char *new, enum uio_seg pathseg, struct nameidata *fromnd, int op,
+ int ndflags)
{
int error;
- NDINIT_ATRIGHTS(fromnd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1,
- pathseg, old, oldfd, &cap_renameat_source_rights);
+ NDINIT_ATRIGHTS(fromnd, op, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
+ ndflags, pathseg, old, oldfd, &cap_renameat_source_rights);
if ((error = namei(fromnd)) != 0)
return (error);
error = mac_vnode_check_rename_from(td->td_ucred, fromnd->ni_dvp,
@@ -3782,23 +3783,35 @@
struct vnode *tvp, *fvp, *tdvp;
struct nameidata fromnd, tond;
uint64_t tondflags;
- int error;
+ int error, fndflags, op;
short irflag;
+ bool exchange;
- if ((flags & ~(AT_RENAME_NOREPLACE)) != 0)
+ if ((flags & ~(AT_RENAME_NOREPLACE | AT_RENAME_EXCHANGE)) != 0)
+ return (EINVAL);
+ if ((flags & (AT_RENAME_NOREPLACE | AT_RENAME_EXCHANGE)) ==
+ (AT_RENAME_NOREPLACE | AT_RENAME_EXCHANGE))
return (EINVAL);
+ if ((flags & AT_RENAME_EXCHANGE) != 0) {
+ op = RENAME;
+ exchange = true;
+ } else {
+ op = DELETE;
+ exchange = false;
+ }
+ fndflags = 0;
again:
tmp = mp = NULL;
bwillwrite();
#ifdef MAC
if (mac_vnode_check_rename_from_enabled()) {
error = kern_renameat_mac(td, oldfd, old, newfd, new, pathseg,
- &fromnd);
+ &fromnd, op, fndflags);
if (error != 0)
return (error);
} else {
#endif
- NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | AUDITVNODE1,
+ NDINIT_ATRIGHTS(&fromnd, op, WANTPARENT | AUDITVNODE1 | fndflags,
pathseg, old, oldfd, &cap_renameat_source_rights);
if ((error = namei(&fromnd)) != 0)
return (error);
@@ -3806,6 +3819,11 @@
}
#endif
fvp = fromnd.ni_vp;
+ if (exchange && fvp == NULL) {
+ NDFREE_PNBUF(&fromnd);
+ vrele(fromnd.ni_dvp);
+ return (ENOENT);
+ }
tondflags = LOCKPARENT | LOCKLEAF | NOCACHE | AUDITVNODE2;
if (fromnd.ni_vp->v_type == VDIR)
tondflags |= WILLBEDIR;
@@ -3844,6 +3862,29 @@
error = EEXIST;
goto out;
}
+ if (exchange) {
+ if (tvp == NULL) {
+ error = ENOENT;
+ goto out;
+ }
+ if (tvp->v_type == VDIR && fndflags == 0) {
+ fndflags = WILLBEDIR;
+again2:
+ NDFREE_PNBUF(&fromnd);
+ vrele(fromnd.ni_dvp);
+ vrele(fvp);
+ NDFREE_PNBUF(&tond);
+ VOP_VPUT_PAIR(tdvp, &tvp, true);
+ error = sig_intr();
+ if (error != 0)
+ goto out1;
+ goto again;
+ }
+ if (tvp->v_type != VDIR && fndflags != 0) {
+ fndflags = 0;
+ goto again2;
+ }
+ }
error = vn_start_write(fvp, &mp, V_NOWAIT);
if (error != 0) {
again1:
@@ -3886,12 +3927,15 @@
goto out;
}
if (tvp != NULL) {
- if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
- error = ENOTDIR;
- goto out;
- } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
- error = EISDIR;
- goto out;
+ if (!exchange) {
+ if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
+ error = ENOTDIR;
+ goto out;
+ } else if (fvp->v_type != VDIR &&
+ tvp->v_type == VDIR) {
+ error = EISDIR;
+ goto out;
+ }
}
#ifdef CAPABILITIES
if (newfd != AT_FDCWD && (tond.ni_resflags & NIRES_ABS) == 0) {
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -260,7 +260,9 @@
#define AT_EMPTY_PATH 0x4000 /* Operate on dirfd if path is empty */
#define AT_RENAME_NOREPLACE 0x0001 /* Fail rename if target exists */
+#define AT_RENAME_EXCHANGE 0x0002 /* Atomically exchange 'from' and 'to' */
#define RENAME_NOREPLACE AT_RENAME_NOREPLACE
+#define RENAME_EXCHANGE AT_RENAME_EXCHANGE
#endif /* __BSD_VISIBLE */
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Aug 2, 4:12 AM (20 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35839686
Default Alt Text
D57658.diff (3 KB)
Attached To
Mode
D57658: Implement AT_RENAME_EXCHANGE flag for VFS and tmpfs
Attached
Detach File
Event Timeline
Log In to Comment