tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Vnode API change: mnt_vnodelist traversal
Current support for iterating over mnt_vnodelist (the list of vnodes
attached to a specific mount point) is rudimentary. All we have is
vmark() / vunmark() to set a marker on the list. Every caller has
to care about list and vnode mutexes, reference count being zero,
intermediate vnode states like VI_CLEAN, VI_XLOCK, VI_MARKER and so on.
Add an interface to iterate over a vnode list:
void vfs_vnode_iterator_init(struct mount *mp, void **marker)
void vfs_vnode_iterator_destroy(void *marker)
bool vfs_vnode_iterator_next(void *marker, struct vnode **vpp)
where vfs_vnode_iterator_next() returns either "false / *vpp == NULL"
when done or "true / *vpp != NULL" to return the next referenced vnode
from the list.
To make vrecycle() work in this environment change it to
bool vrecycle(struct vnode *vp)
where "vp" is a referenced vnode to be destroyed if this is the last
reference.
Typical usage is like
struct vnode *vp;
void *marker;
vfs_vnode_iterator_init(mp, &marker);
while (vfs_vnode_iterator_next(marker, &vp) {
if (vrecycle(vp))
continue;
if (destroy_all)
vgone(vp);
else
vrele(vp);
}
vfs_vnode_iterator_destroy(marker);
to clean or purge the list or
struct vnode *vp;
void *marker;
vfs_vnode_iterator_init(mp, &marker);
while (vfs_vnode_iterator_next(marker, &vp) {
error = vn_lock(vp, LK_EXCLUSIVE);
if (error == ENOENT) {
vrele(vp);
continue;
}
KASSERT(error == 0);
/* process this vnode */
vput(vp);
}
vfs_vnode_iterator_destroy(marker);
to do something on all vnodes attached to this mount point.
A diff implementing this and using it for those operations running
vrecycle() is at http://www.netbsd.org/~hannken/vnode-pass4-1.diff
Once all operations are converted, vmark() / vunmark() will go and
man pages will be updated.
Comments or objections anyone?
--
J. Hannken-Illjes - hannken%eis.cs.tu-bs.de@localhost - TU Braunschweig
(Germany)
Home |
Main Index |
Thread Index |
Old Index