| 3160 | /* get buffer heads from global Vcb BH list */ |
| 3161 | |
| 3162 | BOOLEAN |
| 3163 | Ext2QueryUnusedBH(PEXT2_VCB Vcb, PLIST_ENTRY head) |
| 3164 | { |
| 3165 | struct buffer_head *bh = NULL; |
| 3166 | PLIST_ENTRY next = NULL; |
| 3167 | LARGE_INTEGER start, now; |
| 3168 | BOOLEAN wake = FALSE; |
| 3169 | |
| 3170 | KeQuerySystemTime(&start); |
| 3171 | |
| 3172 | ExAcquireResourceExclusiveLite(&Vcb->bd.bd_bh_lock, TRUE); |
| 3173 | |
| 3174 | while (!IsListEmpty(&Vcb->bd.bd_bh_free)) { |
| 3175 | |
| 3176 | KeQuerySystemTime(&now); |
| 3177 | if (now.QuadPart > start.QuadPart + (LONGLONG)10*1000*1000) { |
| 3178 | break; |
| 3179 | } |
| 3180 | |
| 3181 | next = RemoveHeadList(&Vcb->bd.bd_bh_free); |
| 3182 | bh = CONTAINING_RECORD(next, struct buffer_head, b_link); |
| 3183 | if (atomic_read(&bh->b_count)) { |
| 3184 | InitializeListHead(&bh->b_link); |
| 3185 | /* to be inserted by brelse */ |
| 3186 | continue; |
| 3187 | } |
| 3188 | |
| 3189 | if ( IsFlagOn(Vcb->Flags, VCB_BEING_DROPPED) || |
| 3190 | (bh->b_ts_drop.QuadPart + (LONGLONG)10*1000*1000*15) > now.QuadPart || |
| 3191 | (bh->b_ts_creat.QuadPart + (LONGLONG)10*1000*1000*180) > now.QuadPart) { |
| 3192 | InsertTailList(head, &bh->b_link); |
| 3193 | buffer_head_remove(&Vcb->bd, bh); |
| 3194 | } else { |
| 3195 | InsertHeadList(&Vcb->bd.bd_bh_free, &bh->b_link); |
| 3196 | break; |
| 3197 | } |
| 3198 | } |
| 3199 | |
| 3200 | wake = IsListEmpty(&Vcb->bd.bd_bh_free); |
| 3201 | ExReleaseResourceLite(&Vcb->bd.bd_bh_lock); |
| 3202 | |
| 3203 | if (wake) |
| 3204 | KeSetEvent(&Vcb->bd.bd_bh_notify, 0, FALSE); |
| 3205 | |
| 3206 | return IsFlagOn(Vcb->Flags, VCB_BEING_DROPPED); |
| 3207 | } |
| 3208 | |
| 3209 | |
| 3210 | /* Reaper thread to release unused buffer heads */ |
no test coverage detected