Bug #694 ยป ufs_ihash.patch
sys/vfs/ufs/inode.h 13 Jun 2007 00:29:28 -0000 | ||
---|---|---|
* 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 */
|
sys/vfs/ufs/ufs_ihash.c 13 Jun 2007 00:30:01 -0000 | ||
---|---|---|
/*
|
||
* 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;
|
||
... | ... | |
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);
|
||
}
|
||
... | ... | |
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;
|
||
}
|
||
... | ... | |
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);
|
||
... | ... | |
* 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;
|
||
}
|
||
... | ... | |
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;
|
||
}
|
||
... | ... | |
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);
|
||
... | ... | |
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);
|
||
}
|