* bufspace_wait: * * Wait for bufspace, acting as the buf daemon if a locked vnode is * supplied. bd_wanted must be set prior to polling for space. The * operation must be re-tried on return. */
| 733 | * operation must be re-tried on return. |
| 734 | */ |
| 735 | static void |
| 736 | bufspace_wait(struct bufdomain *bd, struct vnode *vp, int gbflags, |
| 737 | int slpflag, int slptimeo) |
| 738 | { |
| 739 | struct thread *td; |
| 740 | int error, fl, norunbuf; |
| 741 | |
| 742 | if ((gbflags & GB_NOWAIT_BD) != 0) |
| 743 | return; |
| 744 | |
| 745 | td = curthread; |
| 746 | BD_LOCK(bd); |
| 747 | while (bd->bd_wanted) { |
| 748 | if (vp != NULL && vp->v_type != VCHR && |
| 749 | (td->td_pflags & TDP_BUFNEED) == 0) { |
| 750 | BD_UNLOCK(bd); |
| 751 | /* |
| 752 | * getblk() is called with a vnode locked, and |
| 753 | * some majority of the dirty buffers may as |
| 754 | * well belong to the vnode. Flushing the |
| 755 | * buffers there would make a progress that |
| 756 | * cannot be achieved by the buf_daemon, that |
| 757 | * cannot lock the vnode. |
| 758 | */ |
| 759 | norunbuf = ~(TDP_BUFNEED | TDP_NORUNNINGBUF) | |
| 760 | (td->td_pflags & TDP_NORUNNINGBUF); |
| 761 | |
| 762 | /* |
| 763 | * Play bufdaemon. The getnewbuf() function |
| 764 | * may be called while the thread owns lock |
| 765 | * for another dirty buffer for the same |
| 766 | * vnode, which makes it impossible to use |
| 767 | * VOP_FSYNC() there, due to the buffer lock |
| 768 | * recursion. |
| 769 | */ |
| 770 | td->td_pflags |= TDP_BUFNEED | TDP_NORUNNINGBUF; |
| 771 | fl = buf_flush(vp, bd, flushbufqtarget); |
| 772 | td->td_pflags &= norunbuf; |
| 773 | BD_LOCK(bd); |
| 774 | if (fl != 0) |
| 775 | continue; |
| 776 | if (bd->bd_wanted == 0) |
| 777 | break; |
| 778 | } |
| 779 | error = msleep(&bd->bd_wanted, BD_LOCKPTR(bd), |
| 780 | (PRIBIO + 4) | slpflag, "newbuf", slptimeo); |
| 781 | if (error != 0) |
| 782 | break; |
| 783 | } |
| 784 | BD_UNLOCK(bd); |
| 785 | } |
| 786 | |
| 787 | /* |
| 788 | * bufspace_daemon: |
no test coverage detected