Linux: Implement FS_IOC_GETVERSION
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
This commit is contained in:
parent
82e414f1b2
commit
3fa5266d72
|
@ -213,6 +213,7 @@ AC_CONFIG_FILES([
|
||||||
tests/zfs-tests/cmd/file_trunc/Makefile
|
tests/zfs-tests/cmd/file_trunc/Makefile
|
||||||
tests/zfs-tests/cmd/file_write/Makefile
|
tests/zfs-tests/cmd/file_write/Makefile
|
||||||
tests/zfs-tests/cmd/get_diff/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/largest_file/Makefile
|
||||||
tests/zfs-tests/cmd/libzfs_input_check/Makefile
|
tests/zfs-tests/cmd/libzfs_input_check/Makefile
|
||||||
tests/zfs-tests/cmd/mkbusy/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/snapshot/Makefile
|
||||||
tests/zfs-tests/tests/functional/snapused/Makefile
|
tests/zfs-tests/tests/functional/snapused/Makefile
|
||||||
tests/zfs-tests/tests/functional/sparse/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/suid/Makefile
|
||||||
tests/zfs-tests/tests/functional/threadsappend/Makefile
|
tests/zfs-tests/tests/functional/threadsappend/Makefile
|
||||||
tests/zfs-tests/tests/functional/tmpfile/Makefile
|
tests/zfs-tests/tests/functional/tmpfile/Makefile
|
||||||
|
|
|
@ -817,6 +817,14 @@ zpl_fallocate(struct file *filp, int mode, loff_t offset, loff_t len)
|
||||||
mode, offset, 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_VISIBLE (FS_FL_USER_VISIBLE | ZFS_PROJINHERIT_FL)
|
||||||
#define ZFS_FL_USER_MODIFIABLE (FS_FL_USER_MODIFIABLE | 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)
|
zpl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case FS_IOC_GETVERSION:
|
||||||
|
return (zpl_ioctl_getversion(filp, (void *)arg));
|
||||||
case FS_IOC_GETFLAGS:
|
case FS_IOC_GETFLAGS:
|
||||||
return (zpl_ioctl_getflags(filp, (void *)arg));
|
return (zpl_ioctl_getflags(filp, (void *)arg));
|
||||||
case FS_IOC_SETFLAGS:
|
case FS_IOC_SETFLAGS:
|
||||||
|
@ -1007,6 +1017,9 @@ static long
|
||||||
zpl_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
zpl_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case FS_IOC32_GETVERSION:
|
||||||
|
cmd = FS_IOC_GETVERSION;
|
||||||
|
break;
|
||||||
case FS_IOC32_GETFLAGS:
|
case FS_IOC32_GETFLAGS:
|
||||||
cmd = FS_IOC_GETFLAGS;
|
cmd = FS_IOC_GETFLAGS;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -874,6 +874,10 @@ tags = ['functional', 'snapused']
|
||||||
tests = ['sparse_001_pos']
|
tests = ['sparse_001_pos']
|
||||||
tags = ['functional', 'sparse']
|
tags = ['functional', 'sparse']
|
||||||
|
|
||||||
|
[tests/functional/stat]
|
||||||
|
tests = ['stat_001_pos']
|
||||||
|
tags = ['functional', 'stat']
|
||||||
|
|
||||||
[tests/functional/suid]
|
[tests/functional/suid]
|
||||||
tests = ['suid_write_to_suid', 'suid_write_to_sgid', 'suid_write_to_suid_sgid',
|
tests = ['suid_write_to_suid', 'suid_write_to_sgid', 'suid_write_to_suid_sgid',
|
||||||
'suid_write_to_none']
|
'suid_write_to_none']
|
||||||
|
|
|
@ -32,6 +32,7 @@ SUBDIRS = \
|
||||||
|
|
||||||
if BUILD_LINUX
|
if BUILD_LINUX
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
|
getversion \
|
||||||
randfree_file \
|
randfree_file \
|
||||||
user_ns_exec \
|
user_ns_exec \
|
||||||
xattrtest
|
xattrtest
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/getversion
|
|
@ -0,0 +1,6 @@
|
||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
|
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
|
||||||
|
|
||||||
|
pkgexec_PROGRAMS = getversion
|
||||||
|
getversion_SOURCES = getversion.c
|
|
@ -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);
|
||||||
|
}
|
|
@ -201,6 +201,7 @@ export ZFSTEST_FILES='badsend
|
||||||
file_trunc
|
file_trunc
|
||||||
file_write
|
file_write
|
||||||
get_diff
|
get_diff
|
||||||
|
getversion
|
||||||
largest_file
|
largest_file
|
||||||
libzfs_input_check
|
libzfs_input_check
|
||||||
mkbusy
|
mkbusy
|
||||||
|
|
|
@ -4051,6 +4051,20 @@ function stat_crtime #<path>
|
||||||
esac
|
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.
|
# Run a command as if it was being run in a TTY.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
|
|
|
@ -73,6 +73,7 @@ SUBDIRS = \
|
||||||
snapshot \
|
snapshot \
|
||||||
snapused \
|
snapused \
|
||||||
sparse \
|
sparse \
|
||||||
|
stat \
|
||||||
suid \
|
suid \
|
||||||
threadsappend \
|
threadsappend \
|
||||||
trim \
|
trim \
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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}
|
|
@ -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."
|
Loading…
Reference in New Issue