* Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
* @(#)ufs_ihash.c 8.6 (Berkeley) %G%
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufs_extern.h>
* Structures associated with inode cacheing.
LIST_HEAD(ihashhead
, inode
) *ihashtbl
;
u_long ihash
; /* size of hash table - 1 */
#define INOHASH(device, inum) (&ihashtbl[((device) + (inum)) & ihash])
struct simplelock ufs_ihash_slock
;
* Initialize inode hash table.
ihashtbl
= hashinit(desiredvnodes
, M_UFSMNT
, &ihash
);
simple_lock_init(&ufs_ihash_slock
);
* Use the device/inum pair to find the incore inode, and return a pointer
* to it. If it is in core, return it, even if it is locked.
ufs_ihashlookup(dev
, inum
)
simple_lock(&ufs_ihash_slock
);
for (ip
= INOHASH(dev
, inum
)->lh_first
; ip
; ip
= ip
->i_hash
.le_next
)
if (inum
== ip
->i_number
&& dev
== ip
->i_dev
)
simple_unlock(&ufs_ihash_slock
);
* Use the device/inum pair to find the incore inode, and return a pointer
* to it. If it is in core, but locked, wait for it.
struct proc
*p
= curproc
; /* XXX */
simple_lock(&ufs_ihash_slock
);
for (ip
= INOHASH(dev
, inum
)->lh_first
; ip
; ip
= ip
->i_hash
.le_next
) {
if (inum
== ip
->i_number
&& dev
== ip
->i_dev
) {
simple_lock(&vp
->v_interlock
);
simple_unlock(&ufs_ihash_slock
);
if (vget(vp
, LK_EXCLUSIVE
| LK_INTERLOCK
, p
))
simple_unlock(&ufs_ihash_slock
);
* Insert the inode into the hash table, and return it locked.
struct proc
*p
= curproc
; /* XXX */
simple_lock(&ufs_ihash_slock
);
ipp
= INOHASH(ip
->i_dev
, ip
->i_number
);
LIST_INSERT_HEAD(ipp
, ip
, i_hash
);
simple_unlock(&ufs_ihash_slock
);
lockmgr(&ip
->i_lock
, LK_EXCLUSIVE
, (struct simplelock
*)0, p
);
* Remove the inode from the hash table.
simple_lock(&ufs_ihash_slock
);
ip
->i_hash
.le_next
= NULL
;
ip
->i_hash
.le_prev
= NULL
;
simple_unlock(&ufs_ihash_slock
);