Skip to content

Commit

Permalink
linux: zpl: inode: pass through RENAME_NOREPLACE
Browse files Browse the repository at this point in the history
Fragment cited from Documentation/filesystems/vfs.rst,
the description is unchanged since the original in kernel commit
520c8b16505236fc82daa352e6c5e73cd9870cff ("vfs: add renameat2 syscall")

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
  • Loading branch information
nabijaczleweli committed Oct 25, 2022
1 parent 0b2428d commit 42bea64
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 20 deletions.
12 changes: 11 additions & 1 deletion module/os/linux/zfs/zpl_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,18 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
zuserns_t *user_ns = NULL;
#endif

/* We don't have renameat2(2) support */
/*
* (1) RENAME_NOREPLACE: this flag indicates that if the target of
* the rename exists the rename should fail with -EEXIST instead of
* replacing the target. The VFS already checks for existence, so
* for local filesystems the RENAME_NOREPLACE implementation is
* equivalent to plain rename.
*/
#ifdef RENAME_NOREPLACE /* Appeared in 3.15 */
if (flags != 0 && flags != RENAME_NOREPLACE)
#else
if (flags)
#endif
return (-EINVAL);

crhold(cr);
Expand Down
4 changes: 2 additions & 2 deletions tests/runfiles/common.run
Original file line number Diff line number Diff line change
Expand Up @@ -802,8 +802,8 @@ tests = ['removal_all_vdev', 'removal_cancel', 'removal_check_space',
tags = ['functional', 'removal']

[tests/functional/rename_dirs]
tests = ['rename_dirs_001_pos']
tags = ['functional', 'rename_dirs']
tests = ['rename_dirs_001_pos', 'rename_no_replace_002_pos']
tags = ['functional', 'rename_dirs', 'rename_no_replace']

[tests/functional/replacement]
tests = ['attach_import', 'attach_multiple', 'attach_rebuild',
Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/cmd/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
/write_dos_attributes
/xattrtest
/zed_fd_spill-zedlet
/rename_no_replace
/suid_write_to_file
/cp_files
/ctime
Expand Down
5 changes: 3 additions & 2 deletions tests/zfs-tests/cmd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/edonr_test %D%/skein_test \
libicp.la \
libspl.la \
libspl_assert.la
%C%_sha2_test_LDADD = $(%C%_skein_test_LDADD)
%C%_edonr_test_LDADD = $(%C%_skein_test_LDADD)
%C%_sha2_test_LDADD = $(%C%_skein_test_LDADD)
%C%_edonr_test_LDADD = $(%C%_skein_test_LDADD)
%C%_blake3_test_LDADD = $(%C%_skein_test_LDADD)


Expand All @@ -119,6 +119,7 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/user_ns_exec
scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest
scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet
scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util
scripts_zfs_tests_bin_PROGRAMS += %D%/rename_no_replace

%C%_idmap_util_LDADD = libspl.la

Expand Down
51 changes: 51 additions & 0 deletions tests/zfs-tests/cmd/rename_no_replace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: 0BSD

#undef NDEBUG
#include <assert.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifdef RENAME_NOREPLACE
static void makeff(int in, size_t sz, struct stat *madeff) {
int ff = openat(in, "from",
O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_CLOEXEC, 0644);
assert(write(ff, "from", sz) == sz);
fstat(ff, madeff);
close(ff);
}

int main(int argc, const char **argv) {
int from = argc > 1 ?
open(argv[1], O_PATH | O_DIRECTORY | O_CLOEXEC) : AT_FDCWD;
int to = argc > 2 ?
open(argv[2], O_PATH | O_DIRECTORY | O_CLOEXEC) : AT_FDCWD;
assert(from != -1 && to != -1);

struct stat ffbuf, frombuf, tobuf;
makeff(from, 3, &ffbuf);
fstatat(from, "from", &frombuf, 0);
assert(!memcmp(&ffbuf, &frombuf, sizeof (struct stat)));
assert(!renameat2(from, "from", to, "to", RENAME_NOREPLACE));
assert(!fstatat(to, "to", &tobuf, 0));
assert(!memcmp(&ffbuf, &tobuf, sizeof (struct stat)));

struct stat ffbuf2, frombuf2, from2buf2, tobuf2;
makeff(from, 4, &ffbuf2);
fstatat(from, "from", &frombuf2, 0);
assert(!memcmp(&ffbuf2, &frombuf2, sizeof (struct stat)));
assert(memcmp(&ffbuf, &ffbuf2, sizeof (struct stat)));
assert(renameat2(from, "from", to, "to", RENAME_NOREPLACE) == -1 &&
errno == EEXIST);
assert(!fstatat(from, "from", &from2buf2, 0));
assert(!memcmp(&frombuf2, &from2buf2, sizeof (struct stat)));
assert(!fstatat(to, "to", &tobuf2, 0));
assert(!memcmp(&tobuf, &tobuf2, sizeof (struct stat)));
}
#else
int main(void) {
abort();
}
#endif
1 change: 1 addition & 0 deletions tests/zfs-tests/include/commands.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export ZFSTEST_FILES='badsend
write_dos_attributes
xattrtest
stride_dd
rename_no_replace
zed_fd_spill-zedlet
suid_write_to_file
cp_files
Expand Down
32 changes: 17 additions & 15 deletions tests/zfs-tests/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/history/sparc.migratedpool.DAT.Z \
functional/history/sparc.orig_history.txt \
functional/history/zfs-pool-v4.dat.Z \
functional/idmap_mount/idmap_mount.cfg \
functional/idmap_mount/idmap_mount_common.kshlib \
functional/inheritance/config001.cfg \
functional/inheritance/config002.cfg \
functional/inheritance/config003.cfg \
Expand Down Expand Up @@ -378,9 +380,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/zvol/zvol_common.shlib \
functional/zvol/zvol_ENOSPC/zvol_ENOSPC.cfg \
functional/zvol/zvol_misc/zvol_misc_common.kshlib \
functional/zvol/zvol_swap/zvol_swap.cfg \
functional/idmap_mount/idmap_mount.cfg \
functional/idmap_mount/idmap_mount_common.kshlib
functional/zvol/zvol_swap/zvol_swap.cfg

nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/acl/off/cleanup.ksh \
Expand Down Expand Up @@ -414,10 +414,10 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/alloc_class/alloc_class_013_pos.ksh \
functional/alloc_class/cleanup.ksh \
functional/alloc_class/setup.ksh \
functional/append/file_append.ksh \
functional/append/threadsappend_001_pos.ksh \
functional/append/cleanup.ksh \
functional/append/file_append.ksh \
functional/append/setup.ksh \
functional/append/threadsappend_001_pos.ksh \
functional/arc/arcstats_runtime_tuning.ksh \
functional/arc/cleanup.ksh \
functional/arc/dbufstats_001_pos.ksh \
Expand Down Expand Up @@ -761,6 +761,8 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/cli_root/zfs_receive/zfs_receive_014_pos.ksh \
functional/cli_root/zfs_receive/zfs_receive_015_pos.ksh \
functional/cli_root/zfs_receive/zfs_receive_016_pos.ksh \
functional/cli_root/zfs_receive/zfs_receive_compressed_corrective.ksh \
functional/cli_root/zfs_receive/zfs_receive_corrective.ksh \
functional/cli_root/zfs_receive/zfs_receive_-e.ksh \
functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh \
functional/cli_root/zfs_receive/zfs_receive_from_zstd.ksh \
Expand All @@ -770,8 +772,6 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/cli_root/zfs_receive/zfs_receive_raw.ksh \
functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh \
functional/cli_root/zfs_receive/zfs_receive_-wR-encrypted-mix.ksh \
functional/cli_root/zfs_receive/zfs_receive_corrective.ksh \
functional/cli_root/zfs_receive/zfs_receive_compressed_corrective.ksh \
functional/cli_root/zfs_rename/cleanup.ksh \
functional/cli_root/zfs_rename/setup.ksh \
functional/cli_root/zfs_rename/zfs_rename_001_pos.ksh \
Expand Down Expand Up @@ -1234,7 +1234,6 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/cli_user/misc/arcstat_001_pos.ksh \
functional/cli_user/misc/arc_summary_001_pos.ksh \
functional/cli_user/misc/arc_summary_002_neg.ksh \
functional/cli_user/misc/zilstat_001_pos.ksh \
functional/cli_user/misc/cleanup.ksh \
functional/cli_user/misc/setup.ksh \
functional/cli_user/misc/zdb_001_neg.ksh \
Expand All @@ -1258,6 +1257,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/cli_user/misc/zfs_unmount_001_neg.ksh \
functional/cli_user/misc/zfs_unshare_001_neg.ksh \
functional/cli_user/misc/zfs_upgrade_001_neg.ksh \
functional/cli_user/misc/zilstat_001_pos.ksh \
functional/cli_user/misc/zpool_001_neg.ksh \
functional/cli_user/misc/zpool_add_001_neg.ksh \
functional/cli_user/misc/zpool_attach_001_neg.ksh \
Expand Down Expand Up @@ -1423,6 +1423,12 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/history/history_009_pos.ksh \
functional/history/history_010_pos.ksh \
functional/history/setup.ksh \
functional/idmap_mount/cleanup.ksh \
functional/idmap_mount/idmap_mount_001.ksh \
functional/idmap_mount/idmap_mount_002.ksh \
functional/idmap_mount/idmap_mount_003.ksh \
functional/idmap_mount/idmap_mount_004.ksh \
functional/idmap_mount/setup.ksh \
functional/inheritance/cleanup.ksh \
functional/inheritance/inherit_001_pos.ksh \
functional/inuse/inuse_001_pos.ksh \
Expand Down Expand Up @@ -1693,6 +1699,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/removal/removal_with_export.ksh \
functional/removal/removal_with_faulted.ksh \
functional/removal/removal_with_ganging.ksh \
functional/removal/removal_with_indirect.ksh \
functional/removal/removal_with_remove.ksh \
functional/removal/removal_with_scrub.ksh \
functional/removal/removal_with_send.ksh \
Expand All @@ -1707,6 +1714,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/removal/remove_mirror_sanity.ksh \
functional/removal/remove_raidz.ksh \
functional/rename_dirs/cleanup.ksh \
functional/rename_dirs/rename_001_pos.ksh \
functional/rename_dirs/rename_dirs_001_pos.ksh \
functional/rename_dirs/setup.ksh \
functional/replacement/attach_import.ksh \
Expand Down Expand Up @@ -2000,10 +2008,4 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/zvol/zvol_swap/zvol_swap_003_pos.ksh \
functional/zvol/zvol_swap/zvol_swap_004_pos.ksh \
functional/zvol/zvol_swap/zvol_swap_005_pos.ksh \
functional/zvol/zvol_swap/zvol_swap_006_pos.ksh \
functional/idmap_mount/cleanup.ksh \
functional/idmap_mount/setup.ksh \
functional/idmap_mount/idmap_mount_001.ksh \
functional/idmap_mount/idmap_mount_002.ksh \
functional/idmap_mount/idmap_mount_003.ksh \
functional/idmap_mount/idmap_mount_004.ksh
functional/zvol/zvol_swap/zvol_swap_006_pos.ksh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/ksh -p
# SPDX-License-Identifier: 0BSD

. $STF_SUITE/include/libtest.shlib

is_linux || [ $(linux_version) -ge $(linux_version "3.15.0") ] || log_unsupported "renameat2(2) is Linux-only"

verify_runnable "both"

log_assert "renameat2(RENAME_NOREPLACE) works"
log_onexit log_must rm -r "$TESTDIR"/*

mkdir "$TESTDIR"/{a,b,c}

log_must rename_no_replace "$TESTDIR" "$TESTDIR" ; rm "$TESTDIR"/from
log_must rename_no_replace "$TESTDIR" "$TESTDIR"/a

cd "$TESTDIR"/b
log_must rename_no_replace ../c; rm to
log_must rename_no_replace

log_pass

0 comments on commit 42bea64

Please sign in to comment.