Add functions to the fileassoc interface to allow a "hint" to be provided

instead of performing an implicit VOP_GETATTR() when adding/looking up
fileassoc entries.
This commit is contained in:
blymn 2006-08-20 10:38:23 +00:00
parent 0406a06106
commit 50abf3c730
3 changed files with 100 additions and 31 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fileassoc.9,v 1.7 2006/08/11 19:17:47 christos Exp $
.\" $NetBSD: fileassoc.9,v 1.8 2006/08/20 10:38:23 blymn Exp $
.\"
.\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
.\" All rights reserved.
@ -28,7 +28,7 @@
.\" (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 August 10, 2006
.Dd August 19, 2006
.Dt FILEASSOC 9
.Os
.Sh NAME
@ -146,6 +146,20 @@ Returns the private data for the file/id combination
or
.Dv NULL
if not found.
.It Ft void * Fn fileassoc_lookup_hint "struct vnode *vp" "fileassoc_t id" \
"uint64_t hint"
Returns the private data for the file/id combination or
.Dv NULL
if not found.
.Pp
.Ar hint
is used to save calculation.
.Pp
While this routine can be used to bypass internal calculation for critical
code paths, it exposes implementation internals and will require special
care if the
.Nm
implementation changes.
.El
.Ss Mount-wide Routines
.Bl -tag -width "123456"
@ -229,6 +243,24 @@ for
for the fileassoc specified by
.Ar id .
.Pp
.It Ft int Fn fileassoc_add_hint "struct vnode *vp" "fileassoc_t id" \
"void *data" "uint64_t hint"
Add private data in
.Ar data
for
.Ar vp
for the fileassoc specified by
.Ar id
using
.Ar hint
to save calculation.
.Pp
While this routine can be used to bypass internal calculation for critical
code paths, it exposes implementation internals and will require special
care if the
.Nm
implementation changes.
.Pp
.It Ft int Fn fileassoc_clear "struct vnode *vp" "fileassoc_t id"
Clear the private data for
.Ar vp ,
@ -399,4 +431,7 @@ and
.Fn fileassoc_clear .
This should be taken into consideration when using the interface.
.Pp
For critical code paths, a hinted version of the routines is supplied as a
mean to bypass internal calculation.
.Pp
This limitation is planned on being removed.

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_fileassoc.c,v 1.7 2006/08/13 06:21:10 xtraeme Exp $ */
/* $NetBSD: kern_fileassoc.c,v 1.8 2006/08/20 10:38:23 blymn Exp $ */
/*-
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.7 2006/08/13 06:21:10 xtraeme Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.8 2006/08/20 10:38:23 blymn Exp $");
#include <sys/param.h>
#include <sys/mount.h>
@ -72,13 +72,13 @@ struct fileassoc_table {
void *tables[FILEASSOC_NHOOKS];
LIST_ENTRY(fileassoc_table) hash_list; /* List pointer. */
};
struct fileassoc_hook fileassoc_hooks[FILEASSOC_NHOOKS];
int fileassoc_nhooks;
/* Global list of hash tables, one per device. */
LIST_HEAD(, fileassoc_table) fileassoc_tables;
/*
* Hashing function: Takes a number modulus the mask to give back
* an index into the hash table.
@ -154,21 +154,28 @@ fileassoc_table_lookup(struct mount *mp)
}
/*
* Perform a lookup on a hash table.
* Perform a lookup on a hash table. If hint is non-zero then use the value
* of the hint as the identifier instead of performing a lookup for the
* fileid.
*/
static struct fileassoc_hash_entry *
fileassoc_file_lookup(struct vnode *vp)
fileassoc_file_lookup(struct vnode *vp, uint64_t hint)
{
struct fileassoc_table *tbl;
struct fileassoc_hashhead *tble;
struct fileassoc_hash_entry *e;
struct vattr va;
size_t indx;
uint64_t th;
int error;
error = VOP_GETATTR(vp, &va, curlwp->l_cred, curlwp);
if (error)
return (NULL);
if (hint == 0) {
error = VOP_GETATTR(vp, &va, curlwp->l_cred, curlwp);
if (error)
return (NULL);
th = va.va_fileid;
} else
th = hint;
tbl = fileassoc_table_lookup(vp->v_mount);
if (tbl == NULL)
@ -177,11 +184,11 @@ fileassoc_file_lookup(struct vnode *vp)
/*
* XXX: We should NOT rely on fileid here!
*/
indx = FILEASSOC_HASH(tbl, va.va_fileid);
indx = FILEASSOC_HASH(tbl, th);
tble = &(tbl->hash_tbl[indx & ((tbl)->hash_mask)]);
LIST_FOREACH(e, tble, entries) {
if ((e != NULL) && (e->fileid == va.va_fileid))
if ((e != NULL) && (e->fileid == th))
return (e);
}
@ -193,10 +200,21 @@ fileassoc_file_lookup(struct vnode *vp)
*/
void *
fileassoc_lookup(struct vnode *vp, fileassoc_t id)
{
return fileassoc_lookup_hint(vp, id, 0);
}
/*
* Return hook data associated with a vnode, use hint to look for file
* instead of performing an implicit VOP_GETATTR() on the vnode.
*/
void *
fileassoc_lookup_hint(struct vnode *vp, fileassoc_t id, uint64_t hint)
{
struct fileassoc_hash_entry *mhe;
mhe = fileassoc_file_lookup(vp);
mhe = fileassoc_file_lookup(vp, hint);
if (mhe == NULL)
return (NULL);
@ -391,20 +409,28 @@ fileassoc_tabledata_lookup(struct mount *mp, fileassoc_t id)
* Add a file entry to a table.
*/
static struct fileassoc_hash_entry *
fileassoc_file_add(struct vnode *vp)
fileassoc_file_add(struct vnode *vp, uint64_t hint)
{
struct fileassoc_table *tbl;
struct fileassoc_hashhead *vhh;
struct fileassoc_hash_entry *e;
struct vattr va;
size_t indx;
uint64_t id;
int error;
error = VOP_GETATTR(vp, &va, curlwp->l_cred, curlwp);
if (error)
return (NULL);
if (hint == 0) {
error = VOP_GETATTR(vp, &va, curlwp->l_cred, curlwp);
if (error)
return (NULL);
/*
* XXX: We should NOT rely on fileid here!
*/
id = va.va_fileid;
} else
id = hint;
e = fileassoc_file_lookup(vp);
e = fileassoc_file_lookup(vp, id);
if (e != NULL)
return (e);
@ -412,14 +438,11 @@ fileassoc_file_add(struct vnode *vp)
if (tbl == NULL)
return (NULL);
/*
* XXX: We should NOT rely on fileid here!
*/
indx = FILEASSOC_HASH(tbl, va.va_fileid);
indx = FILEASSOC_HASH(tbl, id);
vhh = &(tbl->hash_tbl[indx & ((tbl)->hash_mask)]);
e = malloc(sizeof(*e), M_TEMP, M_WAITOK | M_ZERO);
e->fileid = va.va_fileid;
e->fileid = id;
LIST_INSERT_HEAD(vhh, e, entries);
return (e);
@ -434,7 +457,7 @@ fileassoc_file_delete(struct vnode *vp)
struct fileassoc_hash_entry *mhe;
int i;
mhe = fileassoc_file_lookup(vp);
mhe = fileassoc_file_lookup(vp, 0);
if (mhe == NULL)
return (ENOENT);
@ -451,16 +474,16 @@ fileassoc_file_delete(struct vnode *vp)
}
/*
* Add a hook to a vnode.
* Add a hook to a vnode using the given hint.
*/
int
fileassoc_add(struct vnode *vp, fileassoc_t id, void *data)
fileassoc_add_hint(struct vnode *vp, fileassoc_t id, void *data, uint64_t hint)
{
struct fileassoc_hash_entry *e;
e = fileassoc_file_lookup(vp);
e = fileassoc_file_lookup(vp, hint);
if (e == NULL) {
e = fileassoc_file_add(vp);
e = fileassoc_file_add(vp, hint);
if (e == NULL)
return (ENOTDIR);
}
@ -473,6 +496,15 @@ fileassoc_add(struct vnode *vp, fileassoc_t id, void *data)
return (0);
}
/*
* Add a hook to a vnode.
*/
int
fileassoc_add(struct vnode *vp, fileassoc_t id, void *data)
{
return fileassoc_add_hint(vp, id, data, 0);
}
/*
* Clear a hook from a vnode.
*/
@ -482,7 +514,7 @@ fileassoc_clear(struct vnode *vp, fileassoc_t id)
struct fileassoc_hash_entry *mhe;
fileassoc_cleanup_cb_t cleanup_cb;
mhe = fileassoc_file_lookup(vp);
mhe = fileassoc_file_lookup(vp, 0);
if (mhe == NULL)
return (ENOENT);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fileassoc.h,v 1.3 2006/08/11 19:17:47 christos Exp $ */
/* $NetBSD: fileassoc.h,v 1.4 2006/08/20 10:38:23 blymn Exp $ */
/*-
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
@ -57,6 +57,7 @@ fileassoc_t fileassoc_register(const char *, fileassoc_cleanup_cb_t);
int fileassoc_deregister(fileassoc_t);
void *fileassoc_tabledata_lookup(struct mount *, fileassoc_t);
void *fileassoc_lookup(struct vnode *, fileassoc_t);
void *fileassoc_lookup_hint(struct vnode *, fileassoc_t, uint64_t);
int fileassoc_table_add(struct mount *, size_t);
int fileassoc_table_delete(struct mount *);
int fileassoc_table_clear(struct mount *, fileassoc_t);
@ -64,6 +65,7 @@ int fileassoc_tabledata_add(struct mount *, fileassoc_t, void *);
int fileassoc_tabledata_clear(struct mount *, fileassoc_t);
int fileassoc_file_delete(struct vnode *);
int fileassoc_add(struct vnode *, fileassoc_t, void *);
int fileassoc_add_hint(struct vnode *, fileassoc_t, void *, uint64_t);
int fileassoc_clear(struct vnode *, fileassoc_t);
int fileassoc_table_run(struct mount *, fileassoc_t, fileassoc_cb_t);