version 1.1.1.1, 2008/06/03 10:38:51 |
version 1.1.1.1.2.1, 2008/08/13 17:12:45 |
|
|
/* |
/* |
* Copyright (c) 2005-2007, Kohsuke Ohtani |
* Copyright (c) 2005-2008, Kohsuke Ohtani |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
|
|
|
|
/* |
/* |
* Get the hash value from path name and mount point. |
* Get the hash value from the mount point and path name. |
*/ |
*/ |
static u_int |
static u_int |
vn_hash(mount_t mp, char *path) |
vn_hash(mount_t mp, char *path) |
|
|
while (*path) |
while (*path) |
val = ((val << 5) + val) + *path++; |
val = ((val << 5) + val) + *path++; |
} |
} |
return (val ^ (u_int) mp) & (VNODE_BUCKETS - 1); |
return (val ^ (u_int)mp) & (VNODE_BUCKETS - 1); |
} |
} |
|
|
/* |
/* |
* Returns locked vnode for specified mount point and path. |
* Returns locked vnode for specified mount point and path. |
|
* vn_lock() will increment the reference count of vnode. |
*/ |
*/ |
vnode_t |
vnode_t |
vn_lookup(mount_t mp, char *path) |
vn_lookup(mount_t mp, char *path) |
|
|
vp = list_entry(n, struct vnode, v_link); |
vp = list_entry(n, struct vnode, v_link); |
if (vp->v_mount == mp && |
if (vp->v_mount == mp && |
!strncmp(vp->v_path, path, PATH_MAX)) { |
!strncmp(vp->v_path, path, PATH_MAX)) { |
|
vp->v_refcnt++; |
|
VNODE_UNLOCK(); |
mutex_lock(&vp->v_lock); |
mutex_lock(&vp->v_lock); |
vp->v_nrlocks++; |
vp->v_nrlocks++; |
VNODE_UNLOCK(); |
|
return vp; |
return vp; |
} |
} |
} |
} |
|
|
vn_lock(vnode_t vp) |
vn_lock(vnode_t vp) |
{ |
{ |
ASSERT(vp); |
ASSERT(vp); |
|
ASSERT(vp->v_refcnt > 0); |
|
|
VNODE_LOCK(); |
|
vn_printf("vn_lock: %s\n", vp->v_path); |
|
mutex_lock(&vp->v_lock); |
mutex_lock(&vp->v_lock); |
vp->v_nrlocks++; |
vp->v_nrlocks++; |
VNODE_UNLOCK(); |
DPRINTF(VFSDB_VNODE, ("vn_lock: %s\n", vp->v_path)); |
} |
} |
|
|
/* |
/* |
|
|
vn_unlock(vnode_t vp) |
vn_unlock(vnode_t vp) |
{ |
{ |
ASSERT(vp); |
ASSERT(vp); |
|
ASSERT(vp->v_refcnt > 0); |
ASSERT(vp->v_nrlocks > 0); |
ASSERT(vp->v_nrlocks > 0); |
|
|
VNODE_LOCK(); |
DPRINTF(VFSDB_VNODE, ("vn_unlock: %s\n", vp->v_path)); |
vn_printf("vn_unlock: %s\n", vp->v_path); |
|
vp->v_nrlocks--; |
vp->v_nrlocks--; |
mutex_unlock(&vp->v_lock); |
mutex_unlock(&vp->v_lock); |
VNODE_UNLOCK(); |
|
} |
} |
|
|
/* |
/* |
|
|
vnode_t vp; |
vnode_t vp; |
int err; |
int err; |
|
|
vn_printf("vget: %s\n", path); |
DPRINTF(VFSDB_VNODE, ("vget: %s\n", path)); |
|
|
if (!(vp = malloc(sizeof(struct vnode)))) |
if (!(vp = malloc(sizeof(struct vnode)))) |
return NULL; |
return NULL; |
|
|
return NULL; |
return NULL; |
} |
} |
vp->v_mount = mp; |
vp->v_mount = mp; |
vp->v_refcount = 1; |
vp->v_refcnt = 1; |
vp->v_op = mp->m_op->vnops; |
vp->v_op = mp->m_op->vfs_vnops; |
strcpy(vp->v_path, path); |
strcpy(vp->v_path, path); |
mutex_init(&vp->v_lock); |
mutex_init(&vp->v_lock); |
vp->v_nrlocks = 0; |
vp->v_nrlocks = 0; |
|
|
{ |
{ |
ASSERT(vp); |
ASSERT(vp); |
ASSERT(vp->v_nrlocks > 0); |
ASSERT(vp->v_nrlocks > 0); |
ASSERT(vp->v_refcount > 0); |
ASSERT(vp->v_refcnt > 0); |
vn_printf("vput: ref=%d %s\n", vp->v_refcount, vp->v_path); |
DPRINTF(VFSDB_VNODE, ("vput: ref=%d %s\n", vp->v_refcnt, |
|
vp->v_path)); |
|
|
vp->v_refcount--; |
vp->v_refcnt--; |
if (vp->v_refcount > 0) { |
if (vp->v_refcnt > 0) { |
vn_unlock(vp); |
vn_unlock(vp); |
return; |
return; |
} |
} |
|
|
vref(vnode_t vp) |
vref(vnode_t vp) |
{ |
{ |
ASSERT(vp); |
ASSERT(vp); |
ASSERT(vp->v_refcount > 0); /* Need vget */ |
ASSERT(vp->v_refcnt > 0); /* Need vget */ |
|
|
VNODE_LOCK(); |
VNODE_LOCK(); |
vn_printf("vref: ref=%d %s\n", vp->v_refcount, vp->v_path); |
DPRINTF(VFSDB_VNODE, ("vref: ref=%d %s\n", vp->v_refcnt, |
vp->v_refcount++; |
vp->v_path)); |
|
vp->v_refcnt++; |
VNODE_UNLOCK(); |
VNODE_UNLOCK(); |
} |
} |
|
|
|
|
{ |
{ |
ASSERT(vp); |
ASSERT(vp); |
ASSERT(vp->v_nrlocks == 0); |
ASSERT(vp->v_nrlocks == 0); |
ASSERT(vp->v_refcount > 0); |
ASSERT(vp->v_refcnt > 0); |
|
|
VNODE_LOCK(); |
VNODE_LOCK(); |
vn_printf("vrele: ref=%d %s\n", vp->v_refcount, vp->v_path); |
DPRINTF(VFSDB_VNODE, ("vrele: ref=%d %s\n", vp->v_refcnt, |
vp->v_refcount--; |
vp->v_path)); |
if (vp->v_refcount > 0) { |
vp->v_refcnt--; |
|
if (vp->v_refcnt > 0) { |
VNODE_UNLOCK(); |
VNODE_UNLOCK(); |
return; |
return; |
} |
} |
|
|
ASSERT(vp->v_nrlocks == 0); |
ASSERT(vp->v_nrlocks == 0); |
|
|
VNODE_LOCK(); |
VNODE_LOCK(); |
vn_printf("vgone: %s\n", vp->v_path); |
DPRINTF(VFSDB_VNODE, ("vgone: %s\n", vp->v_path)); |
list_remove(&vp->v_link); |
list_remove(&vp->v_link); |
vfs_unbusy(vp->v_mount); |
vfs_unbusy(vp->v_mount); |
mutex_destroy(&vp->v_lock); |
mutex_destroy(&vp->v_lock); |
|
|
int count; |
int count; |
|
|
vn_lock(vp); |
vn_lock(vp); |
count = vp->v_refcount; |
count = vp->v_refcnt; |
vn_unlock(vp); |
vn_unlock(vp); |
return count; |
return count; |
} |
} |
|
|
VNODE_UNLOCK(); |
VNODE_UNLOCK(); |
} |
} |
|
|
|
int |
|
vn_stat(vnode_t vp, struct stat *st) |
|
{ |
|
mode_t mode; |
|
|
|
memset(st, 0, sizeof(struct stat)); |
|
|
|
st->st_ino = (ino_t)vp; |
|
st->st_size = vp->v_size; |
|
mode = vp->v_mode; |
|
switch (vp->v_type) { |
|
case VREG: |
|
mode |= S_IFREG; |
|
break; |
|
case VDIR: |
|
mode |= S_IFDIR; |
|
break; |
|
case VBLK: |
|
mode |= S_IFBLK; |
|
break; |
|
case VCHR: |
|
mode |= S_IFCHR; |
|
break; |
|
case VLNK: |
|
mode |= S_IFLNK; |
|
break; |
|
case VSOCK: |
|
mode |= S_IFSOCK; |
|
break; |
|
case VFIFO: |
|
mode |= S_IFIFO; |
|
break; |
|
default: |
|
return EBADF; |
|
}; |
|
st->st_mode = mode; |
|
st->st_blksize = BSIZE; |
|
st->st_blocks = vp->v_size / S_BLKSIZE; |
|
st->st_uid = 0; |
|
st->st_gid = 0; |
|
if (vp->v_type == VCHR || vp->v_type == VBLK) |
|
st->st_rdev = (dev_t)vp->v_data; |
|
|
|
return 0; |
|
} |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
/* |
/* |
* Dump all all vnode. |
* Dump all all vnode. |
|
|
"VLNK ", "VSOCK", "VFIFO" }; |
"VLNK ", "VSOCK", "VFIFO" }; |
|
|
VNODE_LOCK(); |
VNODE_LOCK(); |
printf("Dump vnode\n"); |
dprintf("Dump vnode\n"); |
printf(" vnode mount type refcnt blkno path\n"); |
dprintf(" vnode mount type refcnt blkno path\n"); |
printf(" -------- -------- ----- ------ -------- ------------------------------\n"); |
dprintf(" -------- -------- ----- ------ -------- ------------------------------\n"); |
|
|
for (i = 0; i < VNODE_BUCKETS; i++) { |
for (i = 0; i < VNODE_BUCKETS; i++) { |
head = &vnode_table[i]; |
head = &vnode_table[i]; |
for (n = list_first(head); n != head; n = list_next(n)) { |
for (n = list_first(head); n != head; n = list_next(n)) { |
vp = list_entry(n, struct vnode, v_link); |
vp = list_entry(n, struct vnode, v_link); |
mp = vp->v_mount; |
mp = vp->v_mount; |
printf(" %08x %08x %s %6d %8d %s%s\n", (u_int)vp, |
|
(u_int)mp, type[vp->v_type], vp->v_refcount, |
dprintf(" %08x %08x %s %6d %8d %s%s\n", (u_int)vp, |
(u_int)vp->v_blkno, |
(u_int)mp, type[vp->v_type], vp->v_refcnt, |
(strlen(mp->m_path) == 1) ? "\0" : mp->m_path, |
(u_int)vp->v_blkno, |
vp->v_path); |
(strlen(mp->m_path) == 1) ? "\0" : mp->m_path, |
|
vp->v_path); |
} |
} |
} |
} |
printf("\n"); |
dprintf("\n"); |
VNODE_UNLOCK(); |
VNODE_UNLOCK(); |
} |
} |
#endif |
#endif |
|
|
int |
int |
vop_nullop(void) |
vop_nullop(void) |
{ |
{ |
|
|
return 0; |
return 0; |
} |
} |
|
|
int |
int |
vop_einval(void) |
vop_einval(void) |
{ |
{ |
|
|
return EINVAL; |
return EINVAL; |
} |
} |
|
|