Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linux: zpl: inode: pass through RENAME_NOREPLACE #14084

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1708,6 +1715,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/removal/remove_raidz.ksh \
functional/rename_dirs/cleanup.ksh \
functional/rename_dirs/rename_dirs_001_pos.ksh \
functional/rename_dirs/rename_no_replace_001_pos.ksh \
functional/rename_dirs/setup.ksh \
functional/replacement/attach_import.ksh \
functional/replacement/attach_multiple.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