xref: /netbsd-src/share/man/man9/fileassoc.9 (revision ce2c90c7c172d95d2402a5b3d96d8f8e6d138a21)
1.\" $NetBSD: fileassoc.9,v 1.9 2006/09/06 13:37:49 blymn Exp $
2.\"
3.\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\"    must display the following acknowledgement:
16.\"      This product includes software developed by Elad Efrat.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\"    derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd September 4, 2006
32.Dt FILEASSOC 9
33.Os
34.Sh NAME
35.Nm fileassoc
36.Nd in-kernel, file-system independent, file-meta data association
37.Sh SYNOPSIS
38.In sys/fileassoc.h
39.Sh DESCRIPTION
40The
41.Nm
42KPI allows association of meta-data with files independent of file-system
43support for such elaborate meta-data.
44.Pp
45A system can have a maximum number of
46.Dv FILEASSOC_NHOOKS
47fileassocs associated with each file.
48.Pp
49When plugging a new fileassoc to the system, a developer can specify private
50data to be associated with every file, as well as (potentially different)
51private data to be associated with every file-system mount.
52.Pp
53For example, a developer might choose to associate a custom ACL with every
54file, and a count of total files with ACLs with the mount.
55.Ss Kernel Programming Interface
56Designed with simplicity in mind, the
57.Nm
58KPI usually accepts four different types of parameters to the most commonly
59used routines:
60.Bl -tag -width "123456"
61.It Ft struct mount * Ar mp
62Describing a mount on which to take action.
63.It Ft struct vnode * Ar vp
64Describing a file on which to take action.
65.It Ft fileassoc_t Ar id
66Describing an id, as returned from a successful call to
67.Fn fileassoc_register .
68.It Ft void * Ar data
69Describing a custom private data block, attached to either a file or a mount.
70.El
71.Pp
72Before using the
73.Nm
74KPI it is important to keep in mind that the interface provides memory
75management only for
76.Nm
77internal memory.
78Any additional memory stored in the tables (such as private data-structures
79used by custom fileassocs) should be allocated and freed by the developer.
80.Pp
81.Nm
82provides the ability to specify a
83.Dq cleanup
84routine to
85.Fn fileassoc_register
86(see below)
87to be called whenever an entry for a file or a mount is deleted.
88.Ss Fileassoc Registration and Deregistration Routines
89These routines allow a developer to allocate a
90.Nm
91slot to be used for private data.
92.Bl -tag -width "123456"
93.It Ft int Fn fileassoc_register "const char *name"  "fileassoc_cleanup_cb cleanup_cb"
94Registers a new fileassoc as
95.Ar name ,
96and returns an
97.Ft int
98to be used as a metahhook-id in subsequent calls to the
99.Nm
100subsystem to identify the fileassoc, or \-1 on failure.
101.Pp
102If
103.Ar cleanup_cb
104is not
105.Dv NULL ,
106it will be called during delete/clear operations (see routines below) with
107indication whether the passed data is file- or mount-specific.
108.Pp
109.Ar cleanup_cb
110should be a function receiving a
111.Ft void *
112and an
113.Ft int ,
114returning
115.Ft void .
116See the
117.Sx EXAMPLES
118section for illustration.
119.Pp
120.It Ft int Fn fileassoc_deregister "fileassoc_t id"
121Deregisters a
122.Nm fileassoc
123whose id is
124.Ar id .
125.Pp
126Note that calling
127.Fn fileassoc_deregister
128only frees the associated slot in the
129.Nm
130subsystem.
131It is up to the developer to take care of garbage collection.
132.El
133.Ss Lookup Routines
134These routines allow lookup of
135.Nm
136mounts, files, and private data attached to them.
137.Bl -tag -width "123456"
138.It Ft void * Fn fileassoc_tabledata_lookup "struct mount *mp" "fileassoc_t id"
139Return table-wide private data in
140.Ar mp
141for
142.Ar id .
143.Pp
144.It Ft void * Fn fileassoc_lookup "struct vnode *vp" "fileassoc_t id"
145Returns the private data for the file/id combination
146or
147.Dv NULL
148if not found.
149.El
150.Ss Mount-wide Routines
151.Bl -tag -width "123456"
152.It Ft int Fn fileassoc_table_add "struct mount *mp" "size_t size"
153Creates a new fileassoc table for
154.Ar mp
155with at least
156.Ar size
157slots.
158.Pp
159.It Ft int Fn fileassoc_table_delete "struct mount *mp"
160Deletes a fileassoc table for
161.Ar mp .
162.Pp
163If specified, the fileassoc's
164.Dq cleanup routine
165will be called with a pointer to the private data-structure and indication of
166.Dv FILEASSOC_CLEANUP_TABLE .
167.Pp
168.It Ft int Fn fileassoc_table_clear "struct mount *mp" "fileassoc_t id"
169Clear all table entries for
170.Ar fileassoc
171from
172.Ar mp .
173.Pp
174If specified, the fileassoc's
175.Dq cleanup routine
176will be called with a pointer to the private data-structure and indication of
177either
178.Dv FILEASSOC_CLEANUP_FILE
179or
180.Dv FILEASSOC_CLEANUP_TABLE
181as appropriate.
182.Pp
183.It Ft int Fn fileassoc_tabledata_add "struct mount *mp" "fileassoc_t id" "void *data"
184Add table-wide fileassoc-specific data in
185.Ar data
186to
187.Ar mp
188for
189.Ar id .
190.Pp
191.It Ft int Fn fileassoc_tabledata_clear "struct mount *mp" "fileassoc_t id"
192Clear table-wide fileassoc-specific data in
193.Ar mp
194for
195.Ar id .
196.It Ft int Fn fileassoc_table_run "struct mount *mp" "fileassoc_t id" \
197"fileassoc_cb_t cb"
198For each entry for
199.Ar id ,
200call
201.Ar cb
202with the entry being the argument.
203.Pp
204.Ar cb
205is a function returning
206.Ft void
207and receiving one
208.Ft "void *"
209parameter.
210.El
211.Ss File-specific Routines
212.Bl -tag -width "123456"
213.It Ft int Fn fileassoc_file_delete "struct vnode *vp"
214Delete the fileassoc entry for
215.Ar vp .
216.Pp
217If specified, the fileassoc's
218.Dq cleanup routine
219will be called with a pointer to the private data-structure and indication of
220.Dv FILEASSOC_CLEANUP_FILE .
221.El
222.Ss Fileassoc-specific Routines
223.Bl -tag -width "123456"
224.It Ft int Fn fileassoc_add "struct vnode *vp" "fileassoc_t id" "void *data"
225Add private data in
226.Ar data
227for
228.Ar vp ,
229for the fileassoc specified by
230.Ar id .
231.Pp
232.It Ft int Fn fileassoc_clear "struct vnode *vp" "fileassoc_t id"
233Clear the private data for
234.Ar vp ,
235for the fileassoc specified by
236.Ar id .
237.Pp
238If specified, the fileassoc's
239.Dq cleanup routine
240will be called with a pointer to the private data-structure and indication of
241.Dv FILEASSOC_CLEANUP_FILE .
242.El
243.Ss Misc. Routines
244.Bl -tag -width "123456"
245.It Ft void Fn fileassoc_init "void"
246Initializes the
247.Nm
248subsystem.
249.Fn fileassoc_init
250is called once during system boot.
251.El
252.Sh EXAMPLES
253The following code examples should give you a clue on using
254.Nm
255for your purposes.
256.Pp
257First, we'll begin with registering a new id.
258We need to do that to save a slot for private data storage with each mount
259and/or file:
260.Bd -literal -offset indent
261fileassoc_t myhook_id;
262
263myhook_id = fileassoc_register("my_hook", myhook_cleanup);
264if (myhook_id == -1)
265	...handle error...
266.Ed
267.Pp
268In the above example we pass a
269.Fn myhook_cleanup
270routine.
271It could look something like this:
272.Bd -literal -offset indent
273void
274myhook_cleanup(void *data, int what)
275{
276	if (what == FILEASSOC_CLEANUP_FILE) {
277		printf("Myhook: Removing entry for file.\n");
278		...handle file entry removal...
279		free(data, M_TEMP);
280	} else if (what == FILEASSOC_CLEANUP_TABLE) {
281		printf("Myhook: Removing entry for mount.\n");
282		...handle mount entry removal...
283		free(data, M_TEMP);
284	}
285}
286.Ed
287.Pp
288Another useful thing would be to add our private data to a file.
289For example, let's assume we keep a custom ACL with each file:
290.Bd -literal -offset indent
291int
292myhook_acl_add(struct vnode *vp, struct myhook_acl *acl)
293{
294	int error;
295
296	error = fileassoc_add(vp, myhook_id, acl);
297	if (error) {
298		printf("Myhook: Could not add ACL.\n");
299		...handle error...
300	}
301
302	printf("Myhook: Added ACL.\n");
303
304	return (0);
305}
306.Ed
307.Pp
308Adding an entry will override any entry that previously exists.
309.Pp
310The above can fail, usually when there is no table for the mount.
311Creating a new table is simple:
312.Bd -literal -offset indent
313int error;
314
315error = fileassoc_table_add(vp-\*[Gt]v_mount, nentries);
316if (error)
317	...handle error...
318.Ed
319.Pp
320The second argument to
321.Fn fileassoc_table_add ,
322.Ar nentries ,
323should be approximately the number of files it is predicted that will
324have entries in the table, although you can provide a pseudo-safe constant
325value (like 128, for example).
326.Pp
327Whatever your plug is, eventually you'll want to access the private data you
328store with each file.
329To do that you can use the following:
330.Bd -literal -offset indent
331int
332myhook_acl_access(struct vnode *vp, int access_flags)
333{
334	struct myhook_acl *acl;
335
336	acl = fileassoc_lookup(vp, myhook_id);
337	if (acl == NULL)
338		return (0);
339
340	error = myhook_acl_eval(acl, access_flags);
341	if (error) {
342		printf("Myhook: Denying access based on ACL decision.\n");
343		return (error);
344	}
345
346	return (0);
347}
348.Ed
349.Pp
350And, in some cases, it may be desired to remove private data associated with
351an file:
352.Bd -literal -offset indent
353int error;
354
355error = fileassoc_clear(vp, myhook_id);
356if (error) {
357	printf("Myhook: Error occured during fileassoc removal.\n");
358	...handle error...
359}
360.Ed
361.Pp
362As mentioned previously, the call to
363.Fn fileassoc_clear
364will result in a call to the
365.Dq cleanup routine
366specified in the initial call to
367.Fn fileassoc_register .
368.Pp
369The above should be enough to get you started.
370.Pp
371For example usage of
372.Nm ,
373see the Veriexec code.
374.Sh CODE REFERENCES
375.Pa src/sys/kern/kern_verifiedexec.c
376.Sh HISTORY
377The
378.Nm
379KPI first appeared in
380.Nx 4.0 .
381.Sh AUTHORS
382.An Elad Efrat Aq elad@NetBSD.org
383.An Brett Lymn Aq blymn@NetBSD.org
384