| 146 | } |
| 147 | |
| 148 | int |
| 149 | vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread *td, |
| 150 | struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg) |
| 151 | { |
| 152 | struct vnode *vp2; |
| 153 | enum vgetstate vs; |
| 154 | int error; |
| 155 | |
| 156 | *vpp = NULL; |
| 157 | while (1) { |
| 158 | rw_wlock(&vfs_hash_lock); |
| 159 | LIST_FOREACH(vp2, |
| 160 | vfs_hash_bucket(vp->v_mount, hash), v_hashlist) { |
| 161 | if (vp2->v_hash != hash) |
| 162 | continue; |
| 163 | if (vp2->v_mount != vp->v_mount) |
| 164 | continue; |
| 165 | if (fn != NULL && fn(vp2, arg)) |
| 166 | continue; |
| 167 | vs = vget_prep(vp2); |
| 168 | rw_wunlock(&vfs_hash_lock); |
| 169 | error = vget_finish(vp2, flags, vs); |
| 170 | if (error == ENOENT && (flags & LK_NOWAIT) == 0) |
| 171 | break; |
| 172 | rw_wlock(&vfs_hash_lock); |
| 173 | LIST_INSERT_HEAD(&vfs_hash_side, vp, v_hashlist); |
| 174 | rw_wunlock(&vfs_hash_lock); |
| 175 | vgone(vp); |
| 176 | vput(vp); |
| 177 | if (!error) |
| 178 | *vpp = vp2; |
| 179 | return (error); |
| 180 | } |
| 181 | if (vp2 == NULL) |
| 182 | break; |
| 183 | } |
| 184 | vp->v_hash = hash; |
| 185 | LIST_INSERT_HEAD(vfs_hash_bucket(vp->v_mount, hash), vp, v_hashlist); |
| 186 | rw_wunlock(&vfs_hash_lock); |
| 187 | return (0); |
| 188 | } |
| 189 | |
| 190 | void |
| 191 | vfs_hash_rehash(struct vnode *vp, u_int hash) |
no test coverage detected