Module Name: src
Committed By: elad
Date: Fri Dec 25 20:05:43 UTC 2009
Modified Files:
src/sys/kern: kern_fileassoc.c
Log Message:
This subsystem had leftovers from the time it was part of Veriexec, and then
from when I first implemented it as "metahook."
Cleanup a lot of the mess by unifying variable names, add struct member
prefixes, adjust comments, etc.
No functional change intended.
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/kern/kern_fileassoc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_fileassoc.c
diff -u src/sys/kern/kern_fileassoc.c:1.32 src/sys/kern/kern_fileassoc.c:1.33
--- src/sys/kern/kern_fileassoc.c:1.32 Fri Dec 25 18:51:41 2009
+++ src/sys/kern/kern_fileassoc.c Fri Dec 25 20:05:43 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_fileassoc.c,v 1.32 2009/12/25 18:51:41 elad Exp $ */
+/* $NetBSD: kern_fileassoc.c,v 1.33 2009/12/25 20:05:43 elad Exp $ */
/*-
* Copyright (c) 2006 Elad Efrat <[email protected]>
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.32 2009/12/25 18:51:41 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.33 2009/12/25 20:05:43 elad Exp $");
#include "opt_fileassoc.h"
@@ -36,15 +36,10 @@
#include <sys/mount.h>
#include <sys/queue.h>
#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/exec.h>
-#include <sys/proc.h>
-#include <sys/inttypes.h>
#include <sys/errno.h>
#include <sys/fileassoc.h>
#include <sys/specificdata.h>
#include <sys/hash.h>
-#include <sys/fstypes.h>
#include <sys/kmem.h>
#include <sys/once.h>
@@ -55,34 +50,35 @@
static ONCE_DECL(control);
/*
- * Hook entry.
- * Includes the hook name for identification and private hook clear callback.
+ * Assoc entry.
+ * Includes the assoc name for identification and private clear callback.
*/
struct fileassoc {
- LIST_ENTRY(fileassoc) list;
- const char *name; /* name. */
- fileassoc_cleanup_cb_t cleanup_cb; /* clear callback. */
- specificdata_key_t key;
+ LIST_ENTRY(fileassoc) assoc_list;
+ const char *assoc_name; /* Name. */
+ fileassoc_cleanup_cb_t assoc_cleanup_cb; /* Clear callback. */
+ specificdata_key_t assoc_key;
};
static LIST_HEAD(, fileassoc) fileassoc_list;
+static kmutex_t fileassoc_list_lock;
/* An entry in the per-mount hash table. */
-struct fileassoc_hash_entry {
- fhandle_t *handle; /* File handle */
- specificdata_reference data; /* Hooks. */
- u_int nassocs; /* # of hooks. */
- LIST_ENTRY(fileassoc_hash_entry) entries; /* List pointer. */
+struct fileassoc_file {
+ fhandle_t *faf_handle; /* File handle */
+ specificdata_reference faf_data; /* Assoc data. */
+ u_int faf_nassocs; /* # of assocs. */
+ LIST_ENTRY(fileassoc_file) faf_list; /* List pointer. */
};
-LIST_HEAD(fileassoc_hashhead, fileassoc_hash_entry);
+LIST_HEAD(fileassoc_hash_entry, fileassoc_file);
struct fileassoc_table {
- struct fileassoc_hashhead *hash_tbl;
- size_t hash_size; /* Number of slots. */
- u_long hash_mask;
- size_t hash_used; /* # of used slots. */
- specificdata_reference data;
+ struct fileassoc_hash_entry *tbl_hash;
+ u_long tbl_mask; /* Hash table mask. */
+ size_t tbl_nslots; /* Number of slots. */
+ size_t tbl_nused; /* # of used slots. */
+ specificdata_reference tbl_data;
};
/*
@@ -91,74 +87,72 @@
*/
#define FILEASSOC_HASH(tbl, handle) \
(hash32_buf((handle), FHANDLE_SIZE(handle), HASH32_BUF_INIT) \
- & ((tbl)->hash_mask))
+ & ((tbl)->tbl_mask))
static void *
-file_getdata(struct fileassoc_hash_entry *e, const struct fileassoc *assoc)
+file_getdata(struct fileassoc_file *faf, const struct fileassoc *assoc)
{
- return specificdata_getspecific(fileassoc_domain, &e->data,
- assoc->key);
+ return specificdata_getspecific(fileassoc_domain, &faf->faf_data,
+ assoc->assoc_key);
}
static void
-file_setdata(struct fileassoc_hash_entry *e, const struct fileassoc *assoc,
+file_setdata(struct fileassoc_file *faf, const struct fileassoc *assoc,
void *data)
{
- specificdata_setspecific(fileassoc_domain, &e->data, assoc->key,
- data);
+ specificdata_setspecific(fileassoc_domain, &faf->faf_data,
+ assoc->assoc_key, data);
}
static void
-file_cleanup(struct fileassoc_hash_entry *e, const struct fileassoc *assoc)
+file_cleanup(struct fileassoc_file *faf, const struct fileassoc *assoc)
{
fileassoc_cleanup_cb_t cb;
void *data;
- cb = assoc->cleanup_cb;
+ cb = assoc->assoc_cleanup_cb;
if (cb == NULL) {
return;
}
- data = file_getdata(e, assoc);
+ data = file_getdata(faf, assoc);
(*cb)(data);
}
static void
-file_free(struct fileassoc_hash_entry *e)
+file_free(struct fileassoc_file *faf)
{
struct fileassoc *assoc;
- LIST_REMOVE(e, entries);
+ LIST_REMOVE(faf, faf_list);
- LIST_FOREACH(assoc, &fileassoc_list, list) {
- file_cleanup(e, assoc);
+ LIST_FOREACH(assoc, &fileassoc_list, assoc_list) {
+ file_cleanup(faf, assoc);
}
- vfs_composefh_free(e->handle);
- specificdata_fini(fileassoc_domain, &e->data);
- kmem_free(e, sizeof(*e));
+ vfs_composefh_free(faf->faf_handle);
+ specificdata_fini(fileassoc_domain, &faf->faf_data);
+ kmem_free(faf, sizeof(*faf));
}
static void
-table_dtor(void *vp)
+table_dtor(void *v)
{
- struct fileassoc_table *tbl = vp;
- struct fileassoc_hashhead *hh;
+ struct fileassoc_table *tbl = v;
u_long i;
/* Remove all entries from the table and lists */
- hh = tbl->hash_tbl;
- for (i = 0; i < tbl->hash_size; i++) {
- struct fileassoc_hash_entry *mhe;
+ for (i = 0; i < tbl->tbl_nslots; i++) {
+ struct fileassoc_file *faf;
- while ((mhe = LIST_FIRST(&hh[i])) != NULL) {
- file_free(mhe);
+ while ((faf = LIST_FIRST(&tbl->tbl_hash[i])) != NULL) {
+ file_free(faf);
}
}
/* Remove hash table and sysctl node */
- hashdone(tbl->hash_tbl, HASH_LIST, tbl->hash_mask);
- specificdata_fini(fileassoc_domain, &tbl->data);
+ hashdone(tbl->tbl_hash, HASH_LIST, tbl->tbl_mask);
+ specificdata_fini(fileassoc_domain, &tbl->tbl_data);
kmem_free(tbl, sizeof(*tbl));
}
@@ -177,11 +171,13 @@
}
fileassoc_domain = specificdata_domain_create();
+ mutex_init(&fileassoc_list_lock, MUTEX_DEFAULT, IPL_NONE);
+
return 0;
}
/*
- * Register a new hook.
+ * Register a new assoc.
*/
int
fileassoc_register(const char *name, fileassoc_cleanup_cb_t cleanup_cb,
@@ -200,24 +196,28 @@
return error;
}
assoc = kmem_alloc(sizeof(*assoc), KM_SLEEP);
- assoc->name = name;
- assoc->cleanup_cb = cleanup_cb;
- assoc->key = key;
- LIST_INSERT_HEAD(&fileassoc_list, assoc, list);
+ assoc->assoc_name = name;
+ assoc->assoc_cleanup_cb = cleanup_cb;
+ assoc->assoc_key = key;
+
+ mutex_enter(&fileassoc_list_lock);
+ LIST_INSERT_HEAD(&fileassoc_list, assoc, assoc_list);
+ mutex_exit(&fileassoc_list_lock);
+
*result = assoc;
return 0;
}
/*
- * Deregister a hook.
+ * Deregister an assoc.
*/
int
fileassoc_deregister(fileassoc_t assoc)
{
- LIST_REMOVE(assoc, list);
- specificdata_key_delete(fileassoc_domain, assoc->key);
+ LIST_REMOVE(assoc, assoc_list);
+ specificdata_key_delete(fileassoc_domain, assoc->assoc_key);
kmem_free(assoc, sizeof(*assoc));
return 0;
@@ -243,12 +243,12 @@
* of the hint as the identifier instead of performing a lookup for the
* fileid.
*/
-static struct fileassoc_hash_entry *
+static struct fileassoc_file *
fileassoc_file_lookup(struct vnode *vp, fhandle_t *hint)
{
struct fileassoc_table *tbl;
- struct fileassoc_hashhead *tble;
- struct fileassoc_hash_entry *e;
+ struct fileassoc_hash_entry *hash_entry;
+ struct fileassoc_file *faf;
size_t indx;
fhandle_t *th;
int error;
@@ -267,12 +267,12 @@
}
indx = FILEASSOC_HASH(tbl, th);
- tble = &(tbl->hash_tbl[indx]);
+ hash_entry = &(tbl->tbl_hash[indx]);
- LIST_FOREACH(e, tble, entries) {
- if (((FHANDLE_FILEID(e->handle)->fid_len ==
+ LIST_FOREACH(faf, hash_entry, faf_list) {
+ if (((FHANDLE_FILEID(faf->faf_handle)->fid_len ==
FHANDLE_FILEID(th)->fid_len)) &&
- (memcmp(FHANDLE_FILEID(e->handle), FHANDLE_FILEID(th),
+ (memcmp(FHANDLE_FILEID(faf->faf_handle), FHANDLE_FILEID(th),
(FHANDLE_FILEID(th))->fid_len) == 0)) {
break;
}
@@ -281,29 +281,28 @@
if (hint == NULL)
vfs_composefh_free(th);
- return e;
+ return faf;
}
/*
- * Return hook data associated with a vnode.
+ * Return assoc data associated with a vnode.
*/
void *
fileassoc_lookup(struct vnode *vp, fileassoc_t assoc)
{
- struct fileassoc_hash_entry *mhe;
+ struct fileassoc_file *faf;
- mhe = fileassoc_file_lookup(vp, NULL);
- if (mhe == NULL)
- return (NULL);
+ faf = fileassoc_file_lookup(vp, NULL);
+ if (faf == NULL)
+ return (NULL);
- return file_getdata(mhe, assoc);
+ return file_getdata(faf, assoc);
}
static struct fileassoc_table *
fileassoc_table_resize(struct fileassoc_table *tbl)
{
struct fileassoc_table *newtbl;
- struct fileassoc_hashhead *hh;
u_long i;
/*
@@ -311,42 +310,41 @@
* this is also temporary -- just double the number of slots.
*/
newtbl = kmem_zalloc(sizeof(*newtbl), KM_SLEEP);
- newtbl->hash_size = (tbl->hash_size * 2);
- if (newtbl->hash_size < tbl->hash_size)
- newtbl->hash_size = tbl->hash_size;
- newtbl->hash_tbl = hashinit(newtbl->hash_size, HASH_LIST,
- true, &newtbl->hash_mask);
- newtbl->hash_used = 0;
- specificdata_init(fileassoc_domain, &newtbl->data);
+ newtbl->tbl_nslots = (tbl->tbl_nslots * 2);
+ if (newtbl->tbl_nslots < tbl->tbl_nslots)
+ newtbl->tbl_nslots = tbl->tbl_nslots;
+ newtbl->tbl_hash = hashinit(newtbl->tbl_nslots, HASH_LIST,
+ true, &newtbl->tbl_mask);
+ newtbl->tbl_nused = 0;
+ specificdata_init(fileassoc_domain, &newtbl->tbl_data);
/* XXX we need to make sure nothing uses fileassoc here! */
- hh = tbl->hash_tbl;
- for (i = 0; i < tbl->hash_size; i++) {
- struct fileassoc_hash_entry *mhe;
+ for (i = 0; i < tbl->tbl_nslots; i++) {
+ struct fileassoc_file *faf;
- while ((mhe = LIST_FIRST(&hh[i])) != NULL) {
- struct fileassoc_hashhead *vhh;
+ while ((faf = LIST_FIRST(&tbl->tbl_hash[i])) != NULL) {
+ struct fileassoc_hash_entry *hash_entry;
size_t indx;
- LIST_REMOVE(mhe, entries);
+ LIST_REMOVE(faf, faf_list);
- indx = FILEASSOC_HASH(newtbl, mhe->handle);
- vhh = &(newtbl->hash_tbl[indx]);
+ indx = FILEASSOC_HASH(newtbl, faf->faf_handle);
+ hash_entry = &(newtbl->tbl_hash[indx]);
- LIST_INSERT_HEAD(vhh, mhe, entries);
+ LIST_INSERT_HEAD(hash_entry, faf, faf_list);
- newtbl->hash_used++;
+ newtbl->tbl_nused++;
}
}
- if (tbl->hash_used != newtbl->hash_used)
+ if (tbl->tbl_nused != newtbl->tbl_nused)
panic("fileassoc_table_resize: inconsistency detected! "
- "needed %zu entries, got %zu", tbl->hash_used,
- newtbl->hash_used);
+ "needed %zu entries, got %zu", tbl->tbl_nused,
+ newtbl->tbl_nused);
- hashdone(tbl->hash_tbl, HASH_LIST, tbl->hash_mask);
- specificdata_fini(fileassoc_domain, &tbl->data);
+ hashdone(tbl->tbl_hash, HASH_LIST, tbl->tbl_mask);
+ specificdata_fini(fileassoc_domain, &tbl->tbl_data);
kmem_free(tbl, sizeof(*tbl));
return (newtbl);
@@ -367,11 +365,11 @@
/* Allocate and initialize a table. */
tbl = kmem_zalloc(sizeof(*tbl), KM_SLEEP);
- tbl->hash_size = FILEASSOC_INITIAL_TABLESIZE;
- tbl->hash_tbl = hashinit(tbl->hash_size, HASH_LIST, true,
- &tbl->hash_mask);
- tbl->hash_used = 0;
- specificdata_init(fileassoc_domain, &tbl->data);
+ tbl->tbl_nslots = FILEASSOC_INITIAL_TABLESIZE;
+ tbl->tbl_hash = hashinit(tbl->tbl_nslots, HASH_LIST, true,
+ &tbl->tbl_mask);
+ tbl->tbl_nused = 0;
+ specificdata_init(fileassoc_domain, &tbl->tbl_data);
mount_setspecific(mp, fileassoc_mountspecific_key, tbl);
@@ -397,28 +395,26 @@
}
/*
- * Run a callback for each hook entry in a table.
+ * Run a callback for each assoc in a table.
*/
int
fileassoc_table_run(struct mount *mp, fileassoc_t assoc, fileassoc_cb_t cb,
void *cookie)
{
struct fileassoc_table *tbl;
- struct fileassoc_hashhead *hh;
u_long i;
tbl = fileassoc_table_lookup(mp);
if (tbl == NULL)
return (EEXIST);
- hh = tbl->hash_tbl;
- for (i = 0; i < tbl->hash_size; i++) {
- struct fileassoc_hash_entry *mhe;
+ for (i = 0; i < tbl->tbl_nslots; i++) {
+ struct fileassoc_file *faf;
- LIST_FOREACH(mhe, &hh[i], entries) {
+ LIST_FOREACH(faf, &tbl->tbl_hash[i], faf_list) {
void *data;
- data = file_getdata(mhe, assoc);
+ data = file_getdata(faf, assoc);
if (data != NULL)
cb(data, cookie);
}
@@ -428,26 +424,24 @@
}
/*
- * Clear a table for a given hook.
+ * Clear a table for a given assoc.
*/
int
fileassoc_table_clear(struct mount *mp, fileassoc_t assoc)
{
struct fileassoc_table *tbl;
- struct fileassoc_hashhead *hh;
u_long i;
tbl = fileassoc_table_lookup(mp);
if (tbl == NULL)
return (EEXIST);
- hh = tbl->hash_tbl;
- for (i = 0; i < tbl->hash_size; i++) {
- struct fileassoc_hash_entry *mhe;
-
- LIST_FOREACH(mhe, &hh[i], entries) {
- file_cleanup(mhe, assoc);
- file_setdata(mhe, assoc, NULL);
+ for (i = 0; i < tbl->tbl_nslots; i++) {
+ struct fileassoc_file *faf;
+
+ LIST_FOREACH(faf, &tbl->tbl_hash[i], faf_list) {
+ file_cleanup(faf, assoc);
+ file_setdata(faf, assoc, NULL);
}
}
@@ -457,12 +451,12 @@
/*
* Add a file entry to a table.
*/
-static struct fileassoc_hash_entry *
+static struct fileassoc_file *
fileassoc_file_add(struct vnode *vp, fhandle_t *hint)
{
struct fileassoc_table *tbl;
- struct fileassoc_hashhead *vhh;
- struct fileassoc_hash_entry *e;
+ struct fileassoc_hash_entry *hash_entry;
+ struct fileassoc_file *faf;
size_t indx;
fhandle_t *th;
int error;
@@ -474,12 +468,12 @@
} else
th = hint;
- e = fileassoc_file_lookup(vp, th);
- if (e != NULL) {
+ faf = fileassoc_file_lookup(vp, th);
+ if (faf != NULL) {
if (hint == NULL)
vfs_composefh_free(th);
- return (e);
+ return (faf);
}
tbl = fileassoc_table_lookup(vp->v_mount);
@@ -488,12 +482,12 @@
}
indx = FILEASSOC_HASH(tbl, th);
- vhh = &(tbl->hash_tbl[indx]);
+ hash_entry = &(tbl->tbl_hash[indx]);
- e = kmem_zalloc(sizeof(*e), KM_SLEEP);
- e->handle = th;
- specificdata_init(fileassoc_domain, &e->data);
- LIST_INSERT_HEAD(vhh, e, entries);
+ faf = kmem_zalloc(sizeof(*faf), KM_SLEEP);
+ faf->faf_handle = th;
+ specificdata_init(fileassoc_domain, &faf->faf_data);
+ LIST_INSERT_HEAD(hash_entry, faf, faf_list);
/*
* This decides when we need to resize the table. For now,
@@ -501,7 +495,7 @@
* has. That's not really true unless of course we had zero
* collisions. Think positive! :)
*/
- if (++(tbl->hash_used) == tbl->hash_size) {
+ if (++(tbl->tbl_nused) == tbl->tbl_nslots) {
struct fileassoc_table *newtbl;
newtbl = fileassoc_table_resize(tbl);
@@ -509,7 +503,7 @@
newtbl);
}
- return (e);
+ return (faf);
}
/*
@@ -519,20 +513,20 @@
fileassoc_file_delete(struct vnode *vp)
{
struct fileassoc_table *tbl;
- struct fileassoc_hash_entry *mhe;
+ struct fileassoc_file *faf;
KERNEL_LOCK(1, NULL);
- mhe = fileassoc_file_lookup(vp, NULL);
- if (mhe == NULL) {
+ faf = fileassoc_file_lookup(vp, NULL);
+ if (faf == NULL) {
KERNEL_UNLOCK_ONE(NULL);
return (ENOENT);
}
- file_free(mhe);
+ file_free(faf);
tbl = fileassoc_table_lookup(vp->v_mount);
- --(tbl->hash_used); /* XXX gc? */
+ --(tbl->tbl_nused); /* XXX gc? */
KERNEL_UNLOCK_ONE(NULL);
@@ -540,48 +534,48 @@
}
/*
- * Add a hook to a vnode.
+ * Add an assoc to a vnode.
*/
int
fileassoc_add(struct vnode *vp, fileassoc_t assoc, void *data)
{
- struct fileassoc_hash_entry *e;
+ struct fileassoc_file *faf;
void *olddata;
- e = fileassoc_file_lookup(vp, NULL);
- if (e == NULL) {
- e = fileassoc_file_add(vp, NULL);
- if (e == NULL)
+ faf = fileassoc_file_lookup(vp, NULL);
+ if (faf == NULL) {
+ faf = fileassoc_file_add(vp, NULL);
+ if (faf == NULL)
return (ENOTDIR);
}
- olddata = file_getdata(e, assoc);
+ olddata = file_getdata(faf, assoc);
if (olddata != NULL)
return (EEXIST);
- file_setdata(e, assoc, data);
+ file_setdata(faf, assoc, data);
- e->nassocs++;
+ faf->faf_nassocs++;
return (0);
}
/*
- * Clear a hook from a vnode.
+ * Clear an assoc from a vnode.
*/
int
fileassoc_clear(struct vnode *vp, fileassoc_t assoc)
{
- struct fileassoc_hash_entry *mhe;
+ struct fileassoc_file *faf;
- mhe = fileassoc_file_lookup(vp, NULL);
- if (mhe == NULL)
+ faf = fileassoc_file_lookup(vp, NULL);
+ if (faf == NULL)
return (ENOENT);
- file_cleanup(mhe, assoc);
- file_setdata(mhe, assoc, NULL);
+ file_cleanup(faf, assoc);
+ file_setdata(faf, assoc, NULL);
- --(mhe->nassocs); /* XXX gc? */
+ --(faf->faf_nassocs); /* XXX gc? */
return (0);
}