Skip to content

Commit

Permalink
Linux: Implement FS_IOC_GETVERSION
Browse files Browse the repository at this point in the history
Provide access to file generation number on Linux.

Add test coverage.

Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Ahelenia Ziemiańska <[email protected]>
Signed-off-by: Ryan Moeller <[email protected]>
Closes #12856
  • Loading branch information
Ryan Moeller authored Dec 18, 2021
1 parent 82e414f commit 3fa5266
Show file tree
Hide file tree
Showing 14 changed files with 226 additions and 0 deletions.
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions module/os/linux/zfs/zpl_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions tests/runfiles/common.run
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/cmd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SUBDIRS = \

if BUILD_LINUX
SUBDIRS += \
getversion \
randfree_file \
user_ns_exec \
xattrtest
Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/cmd/getversion/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/getversion
6 changes: 6 additions & 0 deletions tests/zfs-tests/cmd/getversion/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am

pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin

pkgexec_PROGRAMS = getversion
getversion_SOURCES = getversion.c
48 changes: 48 additions & 0 deletions tests/zfs-tests/cmd/getversion/getversion.c
Original file line number Diff line number Diff line change
@@ -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);
}
1 change: 1 addition & 0 deletions tests/zfs-tests/include/commands.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ export ZFSTEST_FILES='badsend
file_trunc
file_write
get_diff
getversion
largest_file
libzfs_input_check
mkbusy
Expand Down
14 changes: 14 additions & 0 deletions tests/zfs-tests/include/libtest.shlib
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/tests/functional/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ SUBDIRS = \
snapshot \
snapused \
sparse \
stat \
suid \
threadsappend \
trim \
Expand Down
8 changes: 8 additions & 0 deletions tests/zfs-tests/tests/functional/stat/Makefile.am
Original file line number Diff line number Diff line change
@@ -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
34 changes: 34 additions & 0 deletions tests/zfs-tests/tests/functional/stat/cleanup.ksh
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions tests/zfs-tests/tests/functional/stat/setup.ksh
Original file line number Diff line number Diff line change
@@ -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}
57 changes: 57 additions & 0 deletions tests/zfs-tests/tests/functional/stat/stat_001_pos.ksh
Original file line number Diff line number Diff line change
@@ -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."

0 comments on commit 3fa5266

Please sign in to comment.