]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Linux: Implement FS_IOC_GETVERSION
authorRyan Moeller <freqlabs@FreeBSD.org>
Sat, 18 Dec 2021 00:18:37 +0000 (19:18 -0500)
committerGitHub <noreply@github.com>
Sat, 18 Dec 2021 00:18:37 +0000 (16:18 -0800)
Provide access to file generation number on Linux.

Add test coverage.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ahelenia ZiemiaƄska <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Ryan Moeller <freqlabs@FreeBSD.org>
Closes #12856

14 files changed:
configure.ac
module/os/linux/zfs/zpl_file.c
tests/runfiles/common.run
tests/zfs-tests/cmd/Makefile.am
tests/zfs-tests/cmd/getversion/.gitignore [new file with mode: 0644]
tests/zfs-tests/cmd/getversion/Makefile.am [new file with mode: 0644]
tests/zfs-tests/cmd/getversion/getversion.c [new file with mode: 0644]
tests/zfs-tests/include/commands.cfg
tests/zfs-tests/include/libtest.shlib
tests/zfs-tests/tests/functional/Makefile.am
tests/zfs-tests/tests/functional/stat/Makefile.am [new file with mode: 0644]
tests/zfs-tests/tests/functional/stat/cleanup.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/stat/setup.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/stat/stat_001_pos.ksh [new file with mode: 0755]

index 4ff902cdc289131d8e890673b8b5c7690a09fbba..1ba037a36aa4c0cb255d57bf8998622625fb37e2 100644 (file)
@@ -213,6 +213,7 @@ AC_CONFIG_FILES([
        tests/zfs-tests/cmd/file_trunc/Makefile
        tests/zfs-tests/cmd/file_write/Makefile
        tests/zfs-tests/cmd/get_diff/Makefile
+       tests/zfs-tests/cmd/getversion/Makefile
        tests/zfs-tests/cmd/largest_file/Makefile
        tests/zfs-tests/cmd/libzfs_input_check/Makefile
        tests/zfs-tests/cmd/mkbusy/Makefile
@@ -388,6 +389,7 @@ AC_CONFIG_FILES([
        tests/zfs-tests/tests/functional/snapshot/Makefile
        tests/zfs-tests/tests/functional/snapused/Makefile
        tests/zfs-tests/tests/functional/sparse/Makefile
+       tests/zfs-tests/tests/functional/stat/Makefile
        tests/zfs-tests/tests/functional/suid/Makefile
        tests/zfs-tests/tests/functional/threadsappend/Makefile
        tests/zfs-tests/tests/functional/tmpfile/Makefile
index 7e88eae3371157293da0e485b9b3dc47045ab713..ff324222d15d3ccd39b53172447fd3be85c6526d 100644 (file)
@@ -817,6 +817,14 @@ zpl_fallocate(struct file *filp, int mode, loff_t offset, loff_t len)
            mode, offset, len);
 }
 
+static int
+zpl_ioctl_getversion(struct file *filp, void __user *arg)
+{
+       uint32_t generation = file_inode(filp)->i_generation;
+
+       return (copy_to_user(arg, &generation, sizeof (generation)));
+}
+
 #define        ZFS_FL_USER_VISIBLE     (FS_FL_USER_VISIBLE | ZFS_PROJINHERIT_FL)
 #define        ZFS_FL_USER_MODIFIABLE  (FS_FL_USER_MODIFIABLE | ZFS_PROJINHERIT_FL)
 
@@ -989,6 +997,8 @@ static long
 zpl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        switch (cmd) {
+       case FS_IOC_GETVERSION:
+               return (zpl_ioctl_getversion(filp, (void *)arg));
        case FS_IOC_GETFLAGS:
                return (zpl_ioctl_getflags(filp, (void *)arg));
        case FS_IOC_SETFLAGS:
@@ -1007,6 +1017,9 @@ static long
 zpl_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        switch (cmd) {
+       case FS_IOC32_GETVERSION:
+               cmd = FS_IOC_GETVERSION;
+               break;
        case FS_IOC32_GETFLAGS:
                cmd = FS_IOC_GETFLAGS;
                break;
index d5052172d269cfd05e03319c1f09672fcb3c6f62..0f0eab050fa39f117467c5bda0fd9106f93d0277 100644 (file)
@@ -874,6 +874,10 @@ tags = ['functional', 'snapused']
 tests = ['sparse_001_pos']
 tags = ['functional', 'sparse']
 
+[tests/functional/stat]
+tests = ['stat_001_pos']
+tags = ['functional', 'stat']
+
 [tests/functional/suid]
 tests = ['suid_write_to_suid', 'suid_write_to_sgid', 'suid_write_to_suid_sgid',
     'suid_write_to_none']
index d1c29fcd1c62fe843e05f1ab67aa126ed02194bc..2470397a90a3a193562bc0f01ebe26faa9e041de 100644 (file)
@@ -32,6 +32,7 @@ SUBDIRS = \
 
 if BUILD_LINUX
 SUBDIRS += \
+       getversion \
        randfree_file \
        user_ns_exec \
        xattrtest
diff --git a/tests/zfs-tests/cmd/getversion/.gitignore b/tests/zfs-tests/cmd/getversion/.gitignore
new file mode 100644 (file)
index 0000000..b347c41
--- /dev/null
@@ -0,0 +1 @@
+/getversion
diff --git a/tests/zfs-tests/cmd/getversion/Makefile.am b/tests/zfs-tests/cmd/getversion/Makefile.am
new file mode 100644 (file)
index 0000000..d6b5e84
--- /dev/null
@@ -0,0 +1,6 @@
+include $(top_srcdir)/config/Rules.am
+
+pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
+
+pkgexec_PROGRAMS = getversion
+getversion_SOURCES = getversion.c
diff --git a/tests/zfs-tests/cmd/getversion/getversion.c b/tests/zfs-tests/cmd/getversion/getversion.c
new file mode 100644 (file)
index 0000000..62c1c5b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 iXsystems, Inc.
+ */
+
+/*
+ * FreeBSD and macOS expose file generation number through stat(2) and stat(1).
+ * Linux exposes it instead through an ioctl.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <linux/fs.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(int argc, const char * const argv[])
+{
+       if (argc != 2)
+               errx(EXIT_FAILURE, "usage: %s filename", argv[0]);
+
+       int fd = open(argv[1], O_RDONLY);
+       if (fd == -1)
+               err(EXIT_FAILURE, "failed to open %s", argv[1]);
+
+       int gen = 0;
+       if (ioctl(fd, FS_IOC_GETVERSION, &gen) == -1)
+               err(EXIT_FAILURE, "FS_IOC_GETVERSION failed");
+
+       (void) close(fd);
+
+       (void) printf("%d\n", gen);
+
+       return (EXIT_SUCCESS);
+}
index 4497a6248b4b92d54bdcaefe3acdf7a9686d2695..e479f2c01f15305bb1300131498e44f699d2ba37 100644 (file)
@@ -201,6 +201,7 @@ export ZFSTEST_FILES='badsend
     file_trunc
     file_write
     get_diff
+    getversion
     largest_file
     libzfs_input_check
     mkbusy
index 2e6ec7601db3cba1f571e2c448df8fcc5ee8739d..66aec104c27dd5ef48e7f739ad7e8041b932a5b1 100644 (file)
@@ -4051,6 +4051,20 @@ function stat_crtime #<path>
        esac
 }
 
+function stat_generation #<path>
+{
+       typeset path=$1
+
+       case $(uname) in
+       Linux)
+               getversion "${path}"
+               ;;
+       *)
+               stat -f %v "${path}"
+               ;;
+       esac
+}
+
 # Run a command as if it was being run in a TTY.
 #
 # Usage:
index 137cddd5f7842687e1e707ec36813db6927b0343..1412e3d8132e69c97b09423822bd6cdbace97cb8 100644 (file)
@@ -73,6 +73,7 @@ SUBDIRS = \
        snapshot \
        snapused \
        sparse \
+       stat \
        suid \
        threadsappend \
        trim \
diff --git a/tests/zfs-tests/tests/functional/stat/Makefile.am b/tests/zfs-tests/tests/functional/stat/Makefile.am
new file mode 100644 (file)
index 0000000..1a861a6
--- /dev/null
@@ -0,0 +1,8 @@
+include $(top_srcdir)/config/Rules.am
+
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/stat
+
+dist_pkgdata_SCRIPTS = \
+       cleanup.ksh \
+       setup.ksh \
+       stat_001_pos.ksh
diff --git a/tests/zfs-tests/tests/functional/stat/cleanup.ksh b/tests/zfs-tests/tests/functional/stat/cleanup.ksh
new file mode 100755 (executable)
index 0000000..3166bd6
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2013 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/tests/zfs-tests/tests/functional/stat/setup.ksh b/tests/zfs-tests/tests/functional/stat/setup.ksh
new file mode 100755 (executable)
index 0000000..4fc55cd
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2013 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup ${DISK}
diff --git a/tests/zfs-tests/tests/functional/stat/stat_001_pos.ksh b/tests/zfs-tests/tests/functional/stat/stat_001_pos.ksh
new file mode 100755 (executable)
index 0000000..e6f9775
--- /dev/null
@@ -0,0 +1,57 @@
+#! /bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2021 iXsystems, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+#
+# Ensure znode generation number is accessible.
+#
+# STRATEGY:
+#      1) Create a file
+#      2) Verify that the znode generation number can be obtained
+#      3) Verify that the znode generation number is not empty
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+       rm -f ${TESTFILE}
+}
+
+log_onexit cleanup
+
+log_assert "Ensure znode generation number is accessible."
+
+TESTFILE=${TESTDIR}/${TESTFILE0}
+
+log_must touch ${TESTFILE}
+log_must stat_generation ${TESTFILE}
+log_must test $(stat_generation ${TESTFILE}) -ne 0
+
+log_pass "Successfully obtained file znode generation number."