diff --git a/share/man/man7/Makefile.xattr b/share/man/man7/Makefile --- a/share/man/man7/Makefile.xattr +++ b/share/man/man7/Makefile @@ -17,6 +17,7 @@ intro.7 \ maclabel.7 \ mitigations.7 \ + named_attribute.7 \ operator.7 \ orders.7 \ ports.7 \ diff --git a/share/man/man7/named_attribute.7.xattr b/share/man/man7/named_attribute.7 --- a/share/man/man7/named_attribute.7.xattr +++ b/share/man/man7/named_attribute.7 @@ -0,0 +1,236 @@ +.\" Copyright (c) 2025 Rick Macklem. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 15, 2025 +.Dt NAMED_ATTRIBUTE 7 +.Os +.Sh NAME +.Nm named_attribute +.Nd Solaris-like extended attribute system interface +.Sh DESCRIPTION +Description of the system interface for named attributes +(the NFS Version 4 terminology). +.Ss Introduction +This document describes an alternate system interface for extended +attributes as compared to +.Xr extattr 9 . +It is based on the interface provided by Solaris and NFS Version 4. +.Pp +This interface associates a directory, known as a named attribute directory, +to a file system object. +This directory is read in the same manner as a normal directory via the +.Fn getdents +or +.Fn getdirenties +system calls. +The +.Dq .\& +and +.Dq ..\& +entries refer to the directory itself and to the associated file object, +respectively. +The other entries in this directory +are the names of the extended attributes for the associated file object +and are referred to as named attributes. +They are analogous to regular files. +.Pp +A named attribute directory does not live in the file system's name space. +It is accessed via an +.Fn open +or +.Fn openat +system call done on the associated file object, with the +.Dv O_NAMEDATTR +flag specified and a +.Fa path +argument of +.Qq .\& . +If successful, this +.Fn open +or +.Fn openat +will return a file descriptor for the named attribute directory. +This file descriptor may be used by +.Fn getdents +or +.Fn getdirentries +as above. +Alternately, this file descriptor can be used as the +.Fa fd +argument for a variety of system calls, such as: +.Fn fchdir , +.Fn unlinkat +and +.Fn renameat . +.Pp +When a file descriptor for a file object in the file system's namespace +is used as the +.Fa fd +argument of an +.Fn openat +along with the +.Fa flag +.Dv O_NAMEDATTR +and a +.Fa path +argument that is the name of the named attribute and not +.Dq .\& +or +.Dq ..\& , +a file decsriptor for the named attribute is acquired. +The +.Fa path +argument must be a single component name, with no embedded +.Dq / +in it. +A named attribute is essentially a regular file, but not in the file +system's name space. +I/O on these named attribute file descriptors may be performed by +standard I/O system calls +such as: +.Fn read , +.Fn write , +.Fn lseek +and +.Fn ftruncate . +.Pp +This provides an alternate system call interface to extended attributes +that provides certain advantages over +.Xr extattr 9 . +Since the attribute's value is updated via +.Fn read +and +.Fn write +system calls, the attribute's data may be as large as any regular file +and may be partially updated. +(Note that this interface does not provide the atomicity guarantee that +.Xr extattr 9 +does.) +The permission to access a named attribute directory is determined from +the access control information for the associated file object. +However, access control information can be set on each individual attribute +in a manner similar to a regular file. +This provides +.Dq per attribute +ganular control over attribute permissions. +.Pp +The +.Xr runat 1 +command may be used to run shell commands on the named attribute directory. +(See +.Xr runat 1 +for more information.) +.Pp +At this time, the only local file system which supports this interface +is ZFS and only if the +.Dv xattr +property is set to +.Dq dir . +(Note that, although +.Dq zfs get xattr +shows +.Dq on +the +.Dq zfs set xattr=dir +must be done, followed by a reboot or remount to make it take effect.) +A NFSv4 mount will also support this interface, but only if the NFSv4 +server file system supports named attributes (the openattr operation). +.Sh EXAMPLES +.Bd -literal +#include +#include +#include +#include + +\&... + +/* For a file called "myfile". Failure checks removed for brevity. */ +int file_fd, nameddir_fd, namedattr_fd; +ssize_t siz; +char buf[DIRBLKSIZ], *cp; +struct dirent *dp; +long named_enabled; + +\&... +/* Check to see if named attributes are supported. */ +named_enabled = pathconf("myfile", _PC_NAMEDATTR_ENABLED); +if (named_enabled <= 0) + err(1, "Named attributes not enabled"); +/* Open a named attribute directory. */ +file_fd = open("myfile", O_RDONLY, 0); +nameddir_fd = openat(file_fd, ".", O_NAMEDATTR | O_CREAT, 0); +\&... +/* and read it, assuming it all fits in DIRBLKSIZ for simplicity. */ +siz = getdents(fd, buf, sizeof(buf)); +cp = buf; +while (cp < &buf[siz]) { + dp = (struct dirent *)cp; + printf("name=%s\\n", dp->d_name); + cp += dp->d_reclen; +} +\&... +/* Open/create a named attribute called "foo". */ +namedattr_fd = openat(file_fd, "foo", O_CREAT | O_RDWR | + O_TRUNC | O_NAMEDATTR, 0600); +\&... +/* Write foo's attribute value. */ +write(namedattr_fd, "xxxyyy", 6); +\&... +/* Read foo's attribute value. */ +lseek(namedattr_fd, 0, SEEK_SET); +siz = read(namedattr_fd, buf, sizeof(buf)); +\&... +/* And close "foo". */ +close(namedattr_fd); +\&... +/* Rename "foo" to "oldfoo". */ +renameat(nameddir_fd, "foo", nameddir_fd, "oldfoo"); +/* and delete "oldfoo". */ +unlinkat(nameddir_fd, "oldfoo", AT_RESOLVE_BENEATH); +.Ed +.Pp +The +.Xr runat 1 +command may be used to perform shell commands on named attributes. +For example: +.Bd -literal +$ runat -create myfile ls -l # creates the named attribute dir +$ runat myfile cp /etc/hosts attrhosts # creates attrhosts +$ runat myfile cat attrhosts # displays contents of attrhosts +$ runat myfile ls -l # lists the attributes for myfile +.Ed +.Sh SEE ALSO +.Xr runat 1 , +.Xr chdir 2 , +.Xr lseek 2 , +.Xr open 2 , +.Xr read 2 , +.Xr rename 2 , +.Xr truncate 2 , +.Xr unlinkat 2 , +.Xr write 2 , +.Xr zfsprops 7 , +.Xr extattr 9 +.Sh HISTORY +This interface first appeared in +.Fx 15.0 .