mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 03:37:45 +03:00
Expose additional file level attributes
ZFS allows to update and retrieve additional file level attributes for FreeBSD. This commit allows additional file level attributes to be updated and retrieved for Linux. These include the flags stored in the upper half of z_pflags only. Two new IOCTLs have been added for this purpose. ZFS_IOC_GETDOSFLAGS can be used to retrieve the attributes, while ZFS_IOC_SETDOSFLAGS can be used to update the attributes. Attributes that are allowed to be updated include ZFS_IMMUTABLE, ZFS_APPENDONLY, ZFS_NOUNLINK, ZFS_ARCHIVE, ZFS_NODUMP, ZFS_SYSTEM, ZFS_HIDDEN, ZFS_READONLY, ZFS_REPARSE, ZFS_OFFLINE and ZFS_SPARSE. Flags can be or'd together while calling ZFS_IOC_SETDOSFLAGS. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Umer Saleem <usaleem@ixsystems.com> Closes #13118
This commit is contained in:
@@ -10,7 +10,5 @@ dist_pkgdata_SCRIPTS = \
|
||||
|
||||
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/acl/off
|
||||
|
||||
if BUILD_FREEBSD
|
||||
pkgexec_PROGRAMS = dosmode_readonly_write
|
||||
dosmode_readonly_write_SOURCES = dosmode_readonly_write.c
|
||||
endif
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
# DESCRIPTION:
|
||||
# Verify that DOS mode flags function correctly.
|
||||
#
|
||||
# These flags are not currently exposed on Linux, so the test is
|
||||
# only useful on FreeBSD.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. ARCHIVE
|
||||
@@ -56,7 +54,13 @@ function hasflag
|
||||
typeset flag=$1
|
||||
typeset path=$2
|
||||
|
||||
ls -lo $path | awk '{ gsub(",", "\n", $5); print $5 }' | grep -qxF $flag
|
||||
if is_linux; then
|
||||
read_dos_attributes $path | awk \
|
||||
'{ gsub(",", "\n", $1); print $1 }' | grep -qxF $flag
|
||||
else
|
||||
ls -lo $path | awk '{ gsub(",", "\n", $5); print $5 }' | \
|
||||
grep -qxF $flag
|
||||
fi
|
||||
}
|
||||
|
||||
log_assert "Verify DOS mode flags function correctly"
|
||||
@@ -67,6 +71,12 @@ testfile=$TESTDIR/testfile
|
||||
owner=$ZFS_ACL_STAFF1
|
||||
other=$ZFS_ACL_STAFF2
|
||||
|
||||
if is_linux; then
|
||||
changeflags=write_dos_attributes
|
||||
else
|
||||
changeflags=chflags
|
||||
fi
|
||||
|
||||
#
|
||||
# ARCHIVE
|
||||
#
|
||||
@@ -75,36 +85,40 @@ other=$ZFS_ACL_STAFF2
|
||||
#
|
||||
log_must touch $testfile
|
||||
log_must hasflag uarch $testfile
|
||||
log_must chflags nouarch $testfile
|
||||
log_must $changeflags nouarch $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must touch $testfile
|
||||
log_must hasflag uarch $testfile
|
||||
if ! is_linux; then
|
||||
log_must hasflag uarch $testfile
|
||||
fi
|
||||
log_must rm $testfile
|
||||
log_must user_run $owner touch $testfile
|
||||
log_must hasflag uarch $testfile
|
||||
log_must user_run $owner chflags nouarch $testfile
|
||||
log_mustnot user_run $other chflags uarch $testfile
|
||||
log_must user_run $owner $changeflags nouarch $testfile
|
||||
log_mustnot user_run $other $changeflags uarch $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must user_run $owner touch $testfile
|
||||
log_mustnot user_run $other chflags nouarch $testfile
|
||||
log_must hasflag uarch $testfile
|
||||
log_mustnot user_run $other $changeflags nouarch $testfile
|
||||
if ! is_linux; then
|
||||
log_must hasflag uarch $testfile
|
||||
fi
|
||||
log_must user_run $owner rm $testfile
|
||||
|
||||
#
|
||||
# HIDDEN
|
||||
#
|
||||
log_must touch $testfile
|
||||
log_must chflags hidden $testfile
|
||||
log_must $changeflags hidden $testfile
|
||||
log_must hasflag hidden $testfile
|
||||
log_must chflags 0 $testfile
|
||||
log_must $changeflags 0 $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must rm $testfile
|
||||
log_must user_run $owner touch $testfile
|
||||
log_must user_run $owner chflags hidden $testfile
|
||||
log_mustnot user_run $other chflags nohidden $testfile
|
||||
log_must user_run $owner $changeflags hidden $testfile
|
||||
log_mustnot user_run $other $changeflags nohidden $testfile
|
||||
log_must hasflag hidden $testfile
|
||||
log_must user_run $owner chflags 0 $testfile
|
||||
log_mustnot user_run $other chflags hidden $testfile
|
||||
log_must user_run $owner $changeflags 0 $testfile
|
||||
log_mustnot user_run $other $changeflags hidden $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must user_run $owner rm $testfile
|
||||
|
||||
@@ -113,17 +127,17 @@ log_must user_run $owner rm $testfile
|
||||
# OFFLINE
|
||||
#
|
||||
log_must touch $testfile
|
||||
log_must chflags offline $testfile
|
||||
log_must $changeflags offline $testfile
|
||||
log_must hasflag offline $testfile
|
||||
log_must chflags 0 $testfile
|
||||
log_must $changeflags 0 $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must rm $testfile
|
||||
log_must user_run $owner touch $testfile
|
||||
log_must user_run $owner chflags offline $testfile
|
||||
log_mustnot user_run $other chflags nooffline $testfile
|
||||
log_must user_run $owner $changeflags offline $testfile
|
||||
log_mustnot user_run $other $changeflags nooffline $testfile
|
||||
log_must hasflag offline $testfile
|
||||
log_must user_run $owner chflags 0 $testfile
|
||||
log_mustnot user_run $other chflags offline $testfile
|
||||
log_must user_run $owner $changeflags 0 $testfile
|
||||
log_mustnot user_run $other $changeflags offline $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must user_run $owner rm $testfile
|
||||
|
||||
@@ -134,21 +148,23 @@ log_must user_run $owner rm $testfile
|
||||
# but root is always allowed the operation.
|
||||
#
|
||||
log_must touch $testfile
|
||||
log_must chflags rdonly $testfile
|
||||
log_must $changeflags rdonly $testfile
|
||||
log_must hasflag rdonly $testfile
|
||||
log_must eval "echo 'root write allowed' >> $testfile"
|
||||
log_must cat $testfile
|
||||
log_must chflags 0 $testfile
|
||||
log_must hasflag - $tesfile
|
||||
log_must $changeflags 0 $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must rm $testfile
|
||||
# It is required to still be able to write to an fd that was opened RW before
|
||||
# READONLY is set. We have a special test program for that.
|
||||
log_must user_run $owner touch $testfile
|
||||
log_mustnot user_run $other chflags rdonly $testfile
|
||||
log_mustnot user_run $other $changeflags rdonly $testfile
|
||||
log_must user_run $owner $tests_base/dosmode_readonly_write $testfile
|
||||
log_mustnot user_run $other chflags nordonly $testfile
|
||||
log_mustnot user_run $other $changeflags nordonly $testfile
|
||||
log_must hasflag rdonly $testfile
|
||||
log_mustnot user_run $owner "echo 'user write forbidden' >> $testfile"
|
||||
if ! is_linux; then
|
||||
log_mustnot user_run $owner "echo 'user write forbidden' >> $testfile"
|
||||
fi
|
||||
log_must eval "echo 'root write allowed' >> $testfile"
|
||||
# We are still allowed to read and remove the file when READONLY is set.
|
||||
log_must user_run $owner cat $testfile
|
||||
@@ -157,24 +173,23 @@ log_must user_run $owner rm $testfile
|
||||
#
|
||||
# REPARSE
|
||||
#
|
||||
# FIXME: does not work, not sure if broken or testing wrong
|
||||
#
|
||||
# not allowed to be changed
|
||||
|
||||
#
|
||||
# SPARSE
|
||||
#
|
||||
log_must truncate -s 1m $testfile
|
||||
log_must chflags sparse $testfile
|
||||
log_must $changeflags sparse $testfile
|
||||
log_must hasflag sparse $testfile
|
||||
log_must chflags 0 $testfile
|
||||
log_must $changeflags 0 $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must rm $testfile
|
||||
log_must user_run $owner truncate -s 1m $testfile
|
||||
log_must user_run $owner chflags sparse $testfile
|
||||
log_mustnot user_run $other chflags nosparse $testfile
|
||||
log_must user_run $owner $changeflags sparse $testfile
|
||||
log_mustnot user_run $other $changeflags nosparse $testfile
|
||||
log_must hasflag sparse $testfile
|
||||
log_must user_run $owner chflags 0 $testfile
|
||||
log_mustnot user_run $other chflags sparse $testfile
|
||||
log_must user_run $owner $changeflags 0 $testfile
|
||||
log_mustnot user_run $other $changeflags sparse $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must user_run $owner rm $testfile
|
||||
|
||||
@@ -182,17 +197,17 @@ log_must user_run $owner rm $testfile
|
||||
# SYSTEM
|
||||
#
|
||||
log_must touch $testfile
|
||||
log_must chflags system $testfile
|
||||
log_must $changeflags system $testfile
|
||||
log_must hasflag system $testfile
|
||||
log_must chflags 0 $testfile
|
||||
log_must $changeflags 0 $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must rm $testfile
|
||||
log_must user_run $owner touch $testfile
|
||||
log_must user_run $owner chflags system $testfile
|
||||
log_mustnot user_run $other chflags nosystem $testfile
|
||||
log_must user_run $owner $changeflags system $testfile
|
||||
log_mustnot user_run $other $changeflags nosystem $testfile
|
||||
log_must hasflag system $testfile
|
||||
log_must user_run $owner chflags 0 $testfile
|
||||
log_mustnot user_run $other chflags system $testfile
|
||||
log_must user_run $owner $changeflags 0 $testfile
|
||||
log_mustnot user_run $other $changeflags system $testfile
|
||||
log_must hasflag - $testfile
|
||||
log_must user_run $owner rm $testfile
|
||||
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <stdint.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
@@ -51,8 +56,14 @@ main(int argc, const char *argv[])
|
||||
fd = open(path, O_CREAT|O_RDWR, 0777);
|
||||
if (fd == -1)
|
||||
err(EXIT_FAILURE, "%s: open failed", path);
|
||||
#ifdef __linux__
|
||||
uint64_t dosflags = ZFS_READONLY;
|
||||
if (ioctl(fd, ZFS_IOC_SETDOSFLAGS, &dosflags) == -1)
|
||||
err(EXIT_FAILURE, "%s: ZFS_IOC_SETDOSFLAGS failed", path);
|
||||
#else
|
||||
if (chflags(path, UF_READONLY) == -1)
|
||||
err(EXIT_FAILURE, "%s: chflags failed", path);
|
||||
#endif
|
||||
if (write(fd, buf, strlen(buf)) == -1)
|
||||
err(EXIT_FAILURE, "%s: write failed", path);
|
||||
if (close(fd) == -1)
|
||||
|
||||
Reference in New Issue
Block a user