xref: /freebsd/share/man/man7/named_attribute.7 (revision 328110da2661a8841f12000b99fea27ceacdd5b2)
1.\"
2.\" Copyright (c) 2025 Rick Macklem
3.\"
4.\" SPDX-License-Identifier: BSD-2-Clause
5.\"
6.Dd July 20, 2025
7.Dt NAMED_ATTRIBUTE 7
8.Os
9.Sh NAME
10.Nm named_attribute
11.Nd Solaris-like extended attribute system interface
12.Sh DESCRIPTION
13Description of the system interface for named attributes
14(the NFS Version 4 terminology).
15.Ss Introduction
16This document describes an alternate system interface for extended
17attributes as compared to
18.Xr extattr 2 .
19It is based on the interface provided by Solaris and NFS Version 4.
20.Pp
21This interface associates a directory, known as a named attribute directory,
22to a file system object.
23This directory is read in the same manner as a normal directory via the
24.Xr getdents 2
25or
26.Xr getdirentries 2
27system calls.
28The
29.Pa .\&
30and
31.Pa ..\&
32entries refer to the directory itself and to the associated file object,
33respectively.
34The other entries in this directory
35are the names of the extended attributes for the associated file object
36and are referred to as named attributes.
37These named attributes are regular files used to store the attribute's
38value.
39.Pp
40A named attribute directory does not live in the file system's name space.
41It is accessed via an
42.Xr open 2
43or
44.Xr openat 2
45system call done on a file to query the named attributes for the file,
46with the
47.Dv O_NAMEDATTR
48flag specified and a
49.Fa path
50argument of
51.Pa .\& .
52This file descriptor can be used as the
53.Fa fd
54argument for a variety of system calls, such as:
55.Xr fchdir 2 ,
56.Xr unlinkat 2
57and
58.Xr renameat 2 .
59.Xr renameat 2
60is only permitted to rename a named attribute within the same named
61attribute directory.
62.Pp
63When a file descriptor for a file object in the file system's namespace
64is used as the
65.Fa fd
66argument of an
67.Xr openat 2
68along with the
69.Fa flag
70.Dv O_NAMEDATTR
71and a
72.Fa path
73argument that is the name of a named attribute (not
74.Pa .\&
75or
76.Pa ..\&
77), a file descriptor for the named attribute is returned.
78If the
79.Fa flag
80.Dv O_CREAT
81is specified, the named attribute will be created if it does not exist.
82The
83.Fa path
84argument must be a single component name, with no embedded
85.Dq /
86in it.
87I/O on these named attribute file descriptors may be performed by
88standard I/O system calls
89such as:
90.Xr read 2 ,
91.Xr write 2 ,
92.Xr lseek 2
93and
94.Xr ftruncate 2 .
95.Pp
96The
97.Dv _PC_NAMEDATTR_ENABLED
98.Fa name
99argument to
100.Xr pathconf 2
101will return 1 if the file system supports named attributes.
102The
103.Dv _PC_HAS_NAMEDATTR
104.Fa name
105argument to
106.Xr pathconf 2
107will return 1 if there are one or more named attributes for the file.
108If an application does a
109.Xr openat 2
110of
111.Dq .\&
112to open a named attribute directory when no named attribute directory exists,
113an empty named attribute directory will be created.
114Testing
115.Dv _PC_HAS_NAMEDATTR
116can be done to avoid creating these named attribute directories unnecessarily.
117.Pp
118The named attribute interface is a different mechanism/system call interface for
119manipulating extended attributes compared with
120.Xr extattr 2 .
121Although the named attribute machanism might require different internal
122implementation
123of extended attributes within a file system, both ZFS and NFSv4 provide
124both mechanisms, which can be used interchangeably to manipulate
125extended attributes, but with a few limitations.
126.Bl -bullet
127.It
128The
129.Xr extattr 2
130interface requires that an extended attribute's value be set or acquired
131via a single system call using a single buffer.
132This limits the size of the attribute's value.
133.It
134The named attribute interface does not support system namespace
135extended attributes and,
136as such, system namespace extended attributes must be manipulated via
137.Xr extattr 2 .
138.It
139For ZFS, if an extended attribute with a value
140that is a small length in bytes is created when the ZFS
141.Dv xattr
142property is set to
143.Dq sa ,
144that extended attribute is only visible via
145.Xr extattr 2
146and not as a named attribute.
147Archiving/de-archiving the file via
148.Xr tar 1
149after setting the
150.Dv xattr
151property to
152.Dq dir
153will make the attribute(s) visible as both named attributes
154and via
155.Xr extattr 2 .
156.El
157.Pp
158The named attribute mechanism/system call interface provides certain
159advantages over
160.Xr extattr 2 .
161Since the attribute's value is updated via
162.Xr read 2
163and
164.Xr write 2
165system calls, the attribute's data may be as large as any regular file
166and may be partially updated.
167(Note that this interface does not provide the atomicity guarantee that
168.Xr extattr 2
169does.)
170The permission to access a named attribute directory is determined from
171the access control information for the associated file object.
172However, access control information can be set on each individual attribute
173in a manner similar to a regular file.
174This provides
175.Dq per attribute
176granular control over attribute permissions via
177.Xr fchown 2 .
178.Pp
179At this time, the only local file system which supports this interface
180is ZFS and only if the
181.Dv xattr
182property is set to
183.Dq dir .
184(Note that, even when
185.Dq zfs get xattr <file-system>
186shows
187.Dq on
188the command
189.Dq zfs set xattr=dir <file-system>
190must be done, followed by a remount to make the setting take effect.)
191A NFSv4 mount will also support this interface, but only if the NFSv4
192server file system supports named attributes (the openattr operation).
193The
194.Fx
195NFSv4 server supports named attributes only
196for ZFS exported file systems where the
197.Dq xattr
198property is set to
199.Dq dir
200for the file system.
201.Sh EXAMPLES
202.Bd -literal
203#include <stdio.h>
204#include <dirent.h>
205#include <fcntl.h>
206#include <unistd.h>
207
208\&...
209
210/* For a file called "myfile". Failure checks removed for brevity. */
211int file_fd, nameddir_fd, namedattr_fd;
212ssize_t siz;
213char buf[DIRBLKSIZ], *cp;
214struct dirent *dp;
215long named_enabled, has_named_attrs;
216
217\&...
218/* Check to see if named attributes are supported. */
219named_enabled = pathconf("myfile", _PC_NAMEDATTR_ENABLED);
220if (named_enabled <= 0)
221	err(1, "Named attributes not enabled");
222/* Test to see if named attribute(s) exist for the file. */
223has_named_attrs = pathconf("myfile", _PC_HAS_NAMEDATTR);
224if (has_named_attrs == 1)
225	printf("myfile has named attribute(s)\\n");
226else
227	printf("myfile does not have any named attributes\\n");
228/* Open a named attribute directory. */
229file_fd = open("myfile", O_RDONLY, 0);
230nameddir_fd = openat(file_fd, ".", O_NAMEDATTR, 0);
231\&...
232/* and read it, assuming it all fits in DIRBLKSIZ for simplicity. */
233siz = getdents(fd, buf, sizeof(buf));
234cp = buf;
235while (cp < &buf[siz]) {
236	dp = (struct dirent *)cp;
237	printf("name=%s\\n", dp->d_name);
238	cp += dp->d_reclen;
239}
240\&...
241/* Open/create a named attribute called "foo". */
242namedattr_fd = openat(file_fd, "foo", O_CREAT | O_RDWR |
243    O_TRUNC | O_NAMEDATTR, 0600);
244\&...
245/* Write foo's attribute value. */
246write(namedattr_fd, "xxxyyy", 6);
247\&...
248/* Read foo's attribute value. */
249lseek(namedattr_fd, 0, SEEK_SET);
250siz = read(namedattr_fd, buf, sizeof(buf));
251\&...
252/* And close "foo". */
253close(namedattr_fd);
254\&...
255/* Rename "foo" to "oldfoo". */
256renameat(nameddir_fd, "foo", nameddir_fd, "oldfoo");
257/* and delete "oldfoo". */
258unlinkat(nameddir_fd, "oldfoo", AT_RESOLVE_BENEATH);
259.Ed
260.Pp
261The
262.Xr runat 1
263command may be used to perform shell commands on named attributes.
264For example:
265.Bd -literal
266$ runat myfile cp /etc/hosts attrhosts	# creates attrhosts
267$ runat myfile cat attrhosts		# displays contents of attrhosts
268$ runat myfile ls -l			# lists the attributes for myfile
269.Ed
270.Pp
271If using the
272.Xr bash 1
273shell, the command
274.Dq cd -@ foo
275enters the named attribute directory for the file object
276.Dq foo .
277.Sh SEE ALSO
278.Xr bash 1 ,
279.Xr runat 1 ,
280.Xr tar 1 ,
281.Xr chdir 2 ,
282.Xr extattr 2 ,
283.Xr lseek 2 ,
284.Xr open 2 ,
285.Xr pathconf 2 ,
286.Xr read 2 ,
287.Xr rename 2 ,
288.Xr truncate 2 ,
289.Xr unlinkat 2 ,
290.Xr write 2 ,
291.Xr zfsprops 7
292.Sh HISTORY
293This interface first appeared in
294.Fx 15.0 .
295