1.\" $NetBSD: fileassoc.9,v 1.22 2008/09/14 12:51:39 itohy 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. The name of the author may not be used to endorse or promote products 15.\" derived from this software without specific prior written permission. 16.\" 17.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27.\" 28.Dd May 15, 2007 29.Dt FILEASSOC 9 30.Os 31.Sh NAME 32.Nm fileassoc 33.Nd in-kernel, file-system independent, file-meta data association 34.Sh SYNOPSIS 35.In sys/fileassoc.h 36.Sh DESCRIPTION 37The 38.Nm 39KPI allows association of meta-data with files independent of file-system 40support for such elaborate meta-data. 41.Pp 42When plugging a new fileassoc to the system, a developer can specify private 43data to be associated with every file, as well as (potentially different) 44private data to be associated with every file-system mount. 45.Pp 46For example, a developer might choose to associate a custom ACL with every 47file, and a count of total files with ACLs with the mount. 48.Ss Kernel Programming Interface 49Designed with simplicity in mind, the 50.Nm 51KPI usually accepts four different types of parameters to the most commonly 52used routines: 53.Bl -tag -width "123456" 54.It Ft struct mount * Ar mp 55Describing a mount on which to take action. 56.It Ft struct vnode * Ar vp 57Describing a file on which to take action. 58.It Ft fileassoc_t Ar id 59Describing an id, as returned from a successful call to 60.Fn fileassoc_register . 61.It Ft void * Ar data 62Describing a custom private data block, attached to either a file or a mount. 63.El 64.Pp 65Before using the 66.Nm 67KPI it is important to keep in mind that the interface provides memory 68management only for 69.Nm 70internal memory. 71Any additional memory stored in the tables (such as private data-structures 72used by custom fileassocs) should be allocated and freed by the developer. 73.Pp 74.Nm 75provides the ability to specify a 76.Dq cleanup 77routine to 78.Fn fileassoc_register 79(see below) 80to be called whenever an entry for a file or a mount is deleted. 81.Ss Fileassoc Registration and Deregistration Routines 82These routines allow a developer to allocate a 83.Nm 84slot to be used for private data. 85.Bl -tag -width "123456" 86.It Ft int Fn fileassoc_register "const char *name" \ 87"fileassoc_cleanup_cb_t cleanup_cb" "fileassoc_t *result" 88Registers a new fileassoc as 89.Ar name , 90and returns a 91.Ft fileassoc_t 92via 93.Fa result 94to be used as identifier in subsequent calls to the 95.Nm 96subsystem. 97.Pp 98.Fn fileassoc_register 99returns zero on success. 100Otherwise, an error number will be returned. 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 returning 113.Ft void . 114See the 115.Sx EXAMPLES 116section for illustration. 117.Pp 118.It Ft int Fn fileassoc_deregister "fileassoc_t id" 119Deregisters a 120.Nm fileassoc 121whose id is 122.Ar id . 123.Pp 124Note that calling 125.Fn fileassoc_deregister 126only frees the associated slot in the 127.Nm 128subsystem. 129It is up to the developer to take care of garbage collection. 130.El 131.Ss Lookup Routines 132These routines allow lookup of 133.Nm 134mounts, files, and private data attached to them. 135.Bl -tag -width "123456" 136.It Ft void * Fn fileassoc_lookup "struct vnode *vp" "fileassoc_t id" 137Returns the private data for the file/id combination 138or 139.Dv NULL 140if not found. 141.El 142.Ss Mount-wide Routines 143.Bl -tag -width "123456" 144.It Ft int Fn fileassoc_table_delete "struct mount *mp" 145Deletes a fileassoc table for 146.Ar mp . 147.Pp 148.It Ft int Fn fileassoc_table_clear "struct mount *mp" "fileassoc_t id" 149Clear all table entries for 150.Ar fileassoc 151from 152.Ar mp . 153.Pp 154If specified, the fileassoc's 155.Dq cleanup routine 156will be called with a pointer to the private data-structure. 157.Pp 158.It Ft int Fn fileassoc_table_run "struct mount *mp" "fileassoc_t id" \ 159"fileassoc_cb_t cb" "void *cookie" 160For each entry for 161.Ar id , 162call 163.Ar cb 164with the entry being the first argument, and 165.Ar cookie 166being the second argument. 167.Pp 168.Ar cb 169is a function returning 170.Ft void 171and receiving one 172.Ft "void *" 173parameter. 174.El 175.Ss File-specific Routines 176.Bl -tag -width "123456" 177.It Ft int Fn fileassoc_file_delete "struct vnode *vp" 178Delete the fileassoc entries for 179.Ar vp . 180.Pp 181If specified, the 182.Dq cleanup routines 183of all fileassoc types added will be called with a pointer to the corresponding 184private data structure and indication of 185.Dv FILEASSOC_CLEANUP_FILE . 186.El 187.Ss Fileassoc-specific Routines 188.Bl -tag -width "123456" 189.It Ft int Fn fileassoc_add "struct vnode *vp" "fileassoc_t id" "void *data" 190Add private data in 191.Ar data 192for 193.Ar vp , 194for the fileassoc specified by 195.Ar id . 196.Pp 197If a table for the mount-point 198.Ar vp 199is on doesn't exist, one will be created automatically. 200.Nm 201manages internally the optimal table sizes as tables are modified. 202.It Ft int Fn fileassoc_clear "struct vnode *vp" "fileassoc_t id" 203Clear the private data for 204.Ar vp , 205for the fileassoc specified by 206.Ar id . 207.Pp 208If specified, the fileassoc's 209.Dq cleanup routine 210will be called with a pointer to the private data-structure and indication of 211.Dv FILEASSOC_CLEANUP_FILE . 212.El 213.Sh EXAMPLES 214The following code examples should give you a clue on using 215.Nm 216for your purposes. 217.Pp 218First, we'll begin with registering a new id. 219We need to do that to save a slot for private data storage with each mount 220and/or file: 221.Bd -literal -offset indent 222fileassoc_t myhook_id; 223int error; 224 225error = fileassoc_register("my_hook", myhook_cleanup, \*[Am]myhook_id); 226if (error != 0) 227 ...handle error... 228.Ed 229.Pp 230In the above example we pass a 231.Fn myhook_cleanup 232routine. 233It could look something like this: 234.Bd -literal -offset indent 235void 236myhook_cleanup(void *data) 237{ 238 239 printf("Myhook: Removing entry for file.\en"); 240 ...handle file entry removal... 241 free(data, M_TEMP); 242} 243.Ed 244.Pp 245Another useful thing would be to add our private data to a file. 246For example, let's assume we keep a custom ACL with each file: 247.Bd -literal -offset indent 248int 249myhook_acl_add(struct vnode *vp, struct myhook_acl *acl) 250{ 251 int error; 252 253 error = fileassoc_add(vp, myhook_id, acl); 254 if (error) { 255 printf("Myhook: Could not add ACL.\en"); 256 ...handle error... 257 } 258 259 printf("Myhook: Added ACL.\en"); 260 261 return (0); 262} 263.Ed 264.Pp 265Adding an entry will override any entry that previously exists. 266.Pp 267Whatever your plug is, eventually you'll want to access the private data you 268store with each file. 269To do that you can use the following: 270.Bd -literal -offset indent 271int 272myhook_acl_access(struct vnode *vp, int access_flags) 273{ 274 struct myhook_acl *acl; 275 276 acl = fileassoc_lookup(vp, myhook_id); 277 if (acl == NULL) 278 return (0); 279 280 error = myhook_acl_eval(acl, access_flags); 281 if (error) { 282 printf("Myhook: Denying access based on ACL decision.\en"); 283 return (error); 284 } 285 286 return (0); 287} 288.Ed 289.Pp 290And, in some cases, it may be desired to remove private data associated with 291an file: 292.Bd -literal -offset indent 293int error; 294 295error = fileassoc_clear(vp, myhook_id); 296if (error) { 297 printf("Myhook: Error occurred during fileassoc removal.\en"); 298 ...handle error... 299} 300.Ed 301.Pp 302As mentioned previously, the call to 303.Fn fileassoc_clear 304will result in a call to the 305.Dq cleanup routine 306specified in the initial call to 307.Fn fileassoc_register . 308.Pp 309The above should be enough to get you started. 310.Pp 311For example usage of 312.Nm , 313see the Veriexec code. 314.Sh CODE REFERENCES 315.Pa src/sys/kern/kern_fileassoc.c 316.Sh HISTORY 317The 318.Nm 319KPI first appeared in 320.Nx 4.0 . 321.Sh AUTHORS 322.An Elad Efrat Aq elad@NetBSD.org 323.An Brett Lymn Aq blymn@NetBSD.org 324