* Flush out buffers on the specified list. * */
| 2084 | * |
| 2085 | */ |
| 2086 | static int |
| 2087 | flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, int slpflag, |
| 2088 | int slptimeo) |
| 2089 | { |
| 2090 | struct buf *bp, *nbp; |
| 2091 | int retval, error; |
| 2092 | daddr_t lblkno; |
| 2093 | b_xflags_t xflags; |
| 2094 | |
| 2095 | ASSERT_BO_WLOCKED(bo); |
| 2096 | |
| 2097 | retval = 0; |
| 2098 | TAILQ_FOREACH_SAFE(bp, &bufv->bv_hd, b_bobufs, nbp) { |
| 2099 | /* |
| 2100 | * If we are flushing both V_NORMAL and V_ALT buffers then |
| 2101 | * do not skip any buffers. If we are flushing only V_NORMAL |
| 2102 | * buffers then skip buffers marked as BX_ALTDATA. If we are |
| 2103 | * flushing only V_ALT buffers then skip buffers not marked |
| 2104 | * as BX_ALTDATA. |
| 2105 | */ |
| 2106 | if (((flags & (V_NORMAL | V_ALT)) != (V_NORMAL | V_ALT)) && |
| 2107 | (((flags & V_NORMAL) && (bp->b_xflags & BX_ALTDATA) != 0) || |
| 2108 | ((flags & V_ALT) && (bp->b_xflags & BX_ALTDATA) == 0))) { |
| 2109 | continue; |
| 2110 | } |
| 2111 | if (nbp != NULL) { |
| 2112 | lblkno = nbp->b_lblkno; |
| 2113 | xflags = nbp->b_xflags & (BX_VNDIRTY | BX_VNCLEAN); |
| 2114 | } |
| 2115 | retval = EAGAIN; |
| 2116 | error = BUF_TIMELOCK(bp, |
| 2117 | LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, BO_LOCKPTR(bo), |
| 2118 | "flushbuf", slpflag, slptimeo); |
| 2119 | if (error) { |
| 2120 | BO_LOCK(bo); |
| 2121 | return (error != ENOLCK ? error : EAGAIN); |
| 2122 | } |
| 2123 | KASSERT(bp->b_bufobj == bo, |
| 2124 | ("bp %p wrong b_bufobj %p should be %p", |
| 2125 | bp, bp->b_bufobj, bo)); |
| 2126 | /* |
| 2127 | * XXX Since there are no node locks for NFS, I |
| 2128 | * believe there is a slight chance that a delayed |
| 2129 | * write will occur while sleeping just above, so |
| 2130 | * check for it. |
| 2131 | */ |
| 2132 | if (((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI) && |
| 2133 | (flags & V_SAVE)) { |
| 2134 | bremfree(bp); |
| 2135 | bp->b_flags |= B_ASYNC; |
| 2136 | bwrite(bp); |
| 2137 | BO_LOCK(bo); |
| 2138 | return (EAGAIN); /* XXX: why not loop ? */ |
| 2139 | } |
| 2140 | bremfree(bp); |
| 2141 | bp->b_flags |= (B_INVAL | B_RELBUF); |
| 2142 | bp->b_flags &= ~B_ASYNC; |
| 2143 | brelse(bp); |
no test coverage detected