diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2019-04-28 20:44:34 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2019-04-28 20:44:34 +0200 |
commit | 31ff1ee3d4b344a5c17fb04f5cf100db6222ecf0 (patch) | |
tree | 66e57840601adeece1c37bb559c15a8074812d15 /libdiskfs/dir-renamed.c | |
parent | da27fb577d5f0b3e86c5ea0408383eef7a7bef2e (diff) | |
download | hurd-31ff1ee3d4b344a5c17fb04f5cf100db6222ecf0.tar.gz hurd-31ff1ee3d4b344a5c17fb04f5cf100db6222ecf0.tar.bz2 hurd-31ff1ee3d4b344a5c17fb04f5cf100db6222ecf0.zip |
diskfs: Fix rename_dir(excl=1) for source directories
Starting from coreutils 8.30 which uses
renameat2(flag=RENAME_NOREPLACE), we need to have excl=1 to behave
correctly, notably in this case:
$ mkdir a
$ mkdir b
$ touch b/t
$ mv b a
diskfs_rename("b", "a", excl=1) called by mv shall return EEXIST.
* libdiskfs/diskfs.h (diskfs_rename_dir): Add `excl' parameter.
* doc/hurd.texi (diskfs_rename_dir): Document `excl' parameter.
* libdiskfs/dir-renamed.c (diskfs_rename_dir): Add `excl' parameter.
Return EEXIST when target exists and `excl' is not 0.
* libdiskfs/dir-rename.c (diskfs_S_dir_rename): Pass `excl' to
diskfs_rename_dir.
Diffstat (limited to 'libdiskfs/dir-renamed.c')
-rw-r--r-- | libdiskfs/dir-renamed.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/libdiskfs/dir-renamed.c b/libdiskfs/dir-renamed.c index 772258d2..69fd7fe3 100644 --- a/libdiskfs/dir-renamed.c +++ b/libdiskfs/dir-renamed.c @@ -64,11 +64,12 @@ checkpath(struct node *source, upon return. This routine is serialized, so it doesn't have to be reentrant. Directories will never be renamed except by this routine. FROMCRED and TOCRED are the users responsible for - FDP/FNP and TDP respectively. */ + FDP/FNP and TDP respectively. If EXCL is set, then fail if TONAME + already exists inside directory TDP. */ error_t diskfs_rename_dir (struct node *fdp, struct node *fnp, const char *fromname, struct node *tdp, const char *toname, - struct protid *fromcred, struct protid *tocred) + struct protid *fromcred, struct protid *tocred, int excl) { error_t err; struct node *tnp, *tmpnp; @@ -96,6 +97,11 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, const char *fromname, assert_backtrace (err != EAGAIN); /* <-> assert_backtrace (TONAME != "..") */ if (err && err != ENOENT) goto out; + if (tnp && excl) + { + err = EEXIST; + goto out; + } if (tnp == fnp) { |