* Allocate (or lookup) pager for a vnode. * Handle is a vnode pointer. */
| 233 | * Handle is a vnode pointer. |
| 234 | */ |
| 235 | vm_object_t |
| 236 | vnode_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, |
| 237 | vm_ooffset_t offset, struct ucred *cred) |
| 238 | { |
| 239 | vm_object_t object; |
| 240 | struct vnode *vp; |
| 241 | |
| 242 | /* |
| 243 | * Pageout to vnode, no can do yet. |
| 244 | */ |
| 245 | if (handle == NULL) |
| 246 | return (NULL); |
| 247 | |
| 248 | vp = (struct vnode *)handle; |
| 249 | ASSERT_VOP_LOCKED(vp, "vnode_pager_alloc"); |
| 250 | VNPASS(vp->v_usecount > 0, vp); |
| 251 | retry: |
| 252 | object = vp->v_object; |
| 253 | |
| 254 | if (object == NULL) { |
| 255 | /* |
| 256 | * Add an object of the appropriate size |
| 257 | */ |
| 258 | object = vm_object_allocate(OBJT_VNODE, |
| 259 | OFF_TO_IDX(round_page(size))); |
| 260 | |
| 261 | object->un_pager.vnp.vnp_size = size; |
| 262 | object->un_pager.vnp.writemappings = 0; |
| 263 | object->domain.dr_policy = vnode_domainset; |
| 264 | object->handle = handle; |
| 265 | if ((vp->v_vflag & VV_VMSIZEVNLOCK) != 0) { |
| 266 | VM_OBJECT_WLOCK(object); |
| 267 | vm_object_set_flag(object, OBJ_SIZEVNLOCK); |
| 268 | VM_OBJECT_WUNLOCK(object); |
| 269 | } |
| 270 | VI_LOCK(vp); |
| 271 | if (vp->v_object != NULL) { |
| 272 | /* |
| 273 | * Object has been created while we were allocating. |
| 274 | */ |
| 275 | VI_UNLOCK(vp); |
| 276 | VM_OBJECT_WLOCK(object); |
| 277 | KASSERT(object->ref_count == 1, |
| 278 | ("leaked ref %p %d", object, object->ref_count)); |
| 279 | object->type = OBJT_DEAD; |
| 280 | refcount_init(&object->ref_count, 0); |
| 281 | VM_OBJECT_WUNLOCK(object); |
| 282 | vm_object_destroy(object); |
| 283 | goto retry; |
| 284 | } |
| 285 | vp->v_object = object; |
| 286 | VI_UNLOCK(vp); |
| 287 | vrefact(vp); |
| 288 | } else { |
| 289 | vm_object_reference(object); |
| 290 | #if VM_NRESERVLEVEL > 0 |
| 291 | if ((object->flags & OBJ_COLORED) == 0) { |
| 292 | VM_OBJECT_WLOCK(object); |
no test coverage detected