| 690 | } |
| 691 | |
| 692 | static int |
| 693 | vm_fault_lock_vnode(struct faultstate *fs, bool objlocked) |
| 694 | { |
| 695 | struct vnode *vp; |
| 696 | int error, locked; |
| 697 | |
| 698 | if (fs->object->type != OBJT_VNODE) |
| 699 | return (KERN_SUCCESS); |
| 700 | vp = fs->object->handle; |
| 701 | if (vp == fs->vp) { |
| 702 | ASSERT_VOP_LOCKED(vp, "saved vnode is not locked"); |
| 703 | return (KERN_SUCCESS); |
| 704 | } |
| 705 | |
| 706 | /* |
| 707 | * Perform an unlock in case the desired vnode changed while |
| 708 | * the map was unlocked during a retry. |
| 709 | */ |
| 710 | unlock_vp(fs); |
| 711 | |
| 712 | locked = VOP_ISLOCKED(vp); |
| 713 | if (locked != LK_EXCLUSIVE) |
| 714 | locked = LK_SHARED; |
| 715 | |
| 716 | /* |
| 717 | * We must not sleep acquiring the vnode lock while we have |
| 718 | * the page exclusive busied or the object's |
| 719 | * paging-in-progress count incremented. Otherwise, we could |
| 720 | * deadlock. |
| 721 | */ |
| 722 | error = vget(vp, locked | LK_CANRECURSE | LK_NOWAIT); |
| 723 | if (error == 0) { |
| 724 | fs->vp = vp; |
| 725 | return (KERN_SUCCESS); |
| 726 | } |
| 727 | |
| 728 | vhold(vp); |
| 729 | if (objlocked) |
| 730 | unlock_and_deallocate(fs); |
| 731 | else |
| 732 | fault_deallocate(fs); |
| 733 | error = vget(vp, locked | LK_RETRY | LK_CANRECURSE); |
| 734 | vdrop(vp); |
| 735 | fs->vp = vp; |
| 736 | KASSERT(error == 0, ("vm_fault: vget failed %d", error)); |
| 737 | return (KERN_RESOURCE_SHORTAGE); |
| 738 | } |
| 739 | |
| 740 | /* |
| 741 | * Calculate the desired readahead. Handle drop-behind. |
no test coverage detected