[patch] UFS inode hash chain conversion to SLIST
Joe Talbott
josepht at cstone.net
Tue Jun 12 17:40:36 PDT 2007
The attached patch is my attempt to convert the i_next field in struct
inode to an SLIST. I'm not sure if I handled the initialization
correctly or if I handled the ilast part of ufs_ihashins() correctly.
It seems to me that a STAILQ may be a better choice since it seems
like all insertions are done on the tail of the list (queue).
Comments are welcome.
Thanks,
Joe
Index: sys/vfs/ufs/inode.h
===================================================================
RCS file: /home/dcvs/src/sys/vfs/ufs/inode.h,v
retrieving revision 1.12
diff -u -r1.12 inode.h
--- sys/vfs/ufs/inode.h 10 Sep 2006 01:26:41 -0000 1.12
+++ sys/vfs/ufs/inode.h 13 Jun 2007 00:29:28 -0000
@@ -81,7 +81,7 @@
* active, and is put back when the file is no longer being used.
*/
struct inode {
- struct inode *i_next;/* Hash chain */
+ SLIST_ENTRY(inode) i_next;/* Hash Chain */
struct vnode *i_vnode;/* Vnode associated with this inode. */
struct vnode *i_devvp;/* Vnode for block I/O. */
uint32_t i_flag; /* flags, see below */
Index: sys/vfs/ufs/ufs_ihash.c
===================================================================
RCS file: /home/dcvs/src/sys/vfs/ufs/ufs_ihash.c,v
retrieving revision 1.20
diff -u -r1.20 ufs_ihash.c
--- sys/vfs/ufs/ufs_ihash.c 14 Oct 2006 16:26:40 -0000 1.20
+++ sys/vfs/ufs/ufs_ihash.c 13 Jun 2007 00:30:01 -0000
@@ -51,7 +51,10 @@
/*
* Structures associated with inode cacheing.
*/
-static struct inode **ihashtbl;
+
+SLIST_HEAD(ihashhead, inode) head = SLIST_HEAD_INITIALIZER(head);
+
+static struct ihashhead **ihashtbl;
static u_long ihash; /* size of hash table - 1 */
static struct lwkt_token ufs_ihash_token;
@@ -63,10 +66,20 @@
void
ufs_ihashinit(void)
{
+ u_long i;
+ struct ihashhead *ihh;
+
ihash = 16;
while (ihash < desiredvnodes)
ihash <<= 1;
ihashtbl = kmalloc(sizeof(void *) * ihash, M_UFSIHASH, M_WAITOK|M_ZERO);
+ for (i = 0; i < ihash; i++)
+ {
+ ihh = kmalloc(sizeof(head),
+ M_UFSIHASH, M_WAITOK|M_ZERO);
+ *(ihashtbl + i) = ihh;
+ SLIST_INIT(*(ihashtbl + i));
+ }
--ihash;
lwkt_token_init(&ufs_ihash_token);
}
@@ -90,11 +103,13 @@
struct vnode *
ufs_ihashlookup(cdev_t dev, ino_t inum)
{
+ struct ihashhead **ipp;
struct inode *ip;
lwkt_tokref ilock;
lwkt_gettoken(&ilock, &ufs_ihash_token);
- for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+ ipp = INOHASH(dev, inum);
+ SLIST_FOREACH(ip, *ipp, i_next) {
if (inum == ip->i_number && dev == ip->i_dev)
break;
}
@@ -117,12 +132,14 @@
ufs_ihashget(cdev_t dev, ino_t inum)
{
lwkt_tokref ilock;
+ struct ihashhead **ipp;
struct inode *ip;
struct vnode *vp;
lwkt_gettoken(&ilock, &ufs_ihash_token);
loop:
- for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+ ipp = INOHASH(dev, inum);
+ SLIST_FOREACH(ip, *ipp, i_next) {
if (inum != ip->i_number || dev != ip->i_dev)
continue;
vp = ITOV(ip);
@@ -132,7 +149,8 @@
* We must check to see if the inode has been ripped
* out from under us after blocking.
*/
- for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+ ipp = INOHASH(dev, inum);
+ SLIST_FOREACH(ip, *ipp, i_next) {
if (inum == ip->i_number && dev == ip->i_dev)
break;
}
@@ -156,10 +174,12 @@
ufs_ihashcheck(cdev_t dev, ino_t inum)
{
lwkt_tokref ilock;
+ struct ihashhead **ipp;
struct inode *ip;
lwkt_gettoken(&ilock, &ufs_ihash_token);
- for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+ ipp = INOHASH(dev, inum);
+ SLIST_FOREACH(ip, *ipp, i_next) {
if (inum == ip->i_number && dev == ip->i_dev)
break;
}
@@ -173,22 +193,27 @@
int
ufs_ihashins(struct inode *ip)
{
- struct inode **ipp;
+ struct ihashhead **ipp;
struct inode *iq;
lwkt_tokref ilock;
+ struct inode *ilast;
KKASSERT((ip->i_flag & IN_HASHED) == 0);
lwkt_gettoken(&ilock, &ufs_ihash_token);
ipp = INOHASH(ip->i_dev, ip->i_number);
- while ((iq = *ipp) != NULL) {
+ SLIST_FOREACH(iq, *ipp, i_next) {
if (ip->i_dev == iq->i_dev && ip->i_number == iq->i_number) {
lwkt_reltoken(&ilock);
return(EBUSY);
}
- ipp = &iq->i_next;
+ if (SLIST_NEXT(iq, i_next) == NULL)
+ ilast = iq;
}
- ip->i_next = NULL;
- *ipp = ip;
+ if (SLIST_EMPTY(*ipp))
+ SLIST_INSERT_HEAD(*ipp, ip, i_next);
+ else
+ SLIST_INSERT_AFTER(ilast, ip, i_next);
+
ip->i_flag |= IN_HASHED;
lwkt_reltoken(&ilock);
return(0);
@@ -201,21 +226,20 @@
ufs_ihashrem(struct inode *ip)
{
lwkt_tokref ilock;
- struct inode **ipp;
+ struct ihashhead **ipp;
struct inode *iq;
lwkt_gettoken(&ilock, &ufs_ihash_token);
if (ip->i_flag & IN_HASHED) {
ipp = INOHASH(ip->i_dev, ip->i_number);
- while ((iq = *ipp) != NULL) {
+ SLIST_FOREACH(iq, *ipp, i_next)
+ {
if (ip == iq)
break;
- ipp = &iq->i_next;
- }
+ }
KKASSERT(ip == iq);
- *ipp = ip->i_next;
- ip->i_next = NULL;
- ip->i_flag &= ~IN_HASHED;
+ SLIST_REMOVE(*ipp, iq, inode, i_next);
+ iq->i_flag &= ~IN_HASHED;
}
lwkt_reltoken(&ilock);
}
More information about the Submit
mailing list