| 791 | } |
| 792 | |
| 793 | void __brelse(struct buffer_head *bh) |
| 794 | { |
| 795 | struct block_device *bdev = bh->b_bdev; |
| 796 | PEXT2_VCB Vcb = (PEXT2_VCB)bdev->bd_priv; |
| 797 | |
| 798 | ASSERT(Vcb->Identifier.Type == EXT2VCB); |
| 799 | |
| 800 | /* write data in case it's dirty */ |
| 801 | while (buffer_dirty(bh)) { |
| 802 | ll_rw_block(WRITE, 1, &bh); |
| 803 | } |
| 804 | |
| 805 | ExAcquireResourceExclusiveLite(&bdev->bd_bh_lock, TRUE); |
| 806 | if (atomic_dec_and_test(&bh->b_count)) { |
| 807 | ASSERT(0 == atomic_read(&bh->b_count)); |
| 808 | } else { |
| 809 | ExReleaseResourceLite(&bdev->bd_bh_lock); |
| 810 | return; |
| 811 | } |
| 812 | KeQuerySystemTime(&bh->b_ts_drop); |
| 813 | RemoveEntryList(&bh->b_link); |
| 814 | InsertTailList(&Vcb->bd.bd_bh_free, &bh->b_link); |
| 815 | KeClearEvent(&Vcb->bd.bd_bh_notify); |
| 816 | ExReleaseResourceLite(&bdev->bd_bh_lock); |
| 817 | KeSetEvent(&Ext2Global->bhReaper.Wait, 0, FALSE); |
| 818 | |
| 819 | DEBUG(DL_BH, ("brelse: cnt=%u size=%u blk=%10.10xh bh=%p ptr=%p\n", |
| 820 | atomic_read(&g_jbh.bh_count) - 1, bh->b_size, |
| 821 | bh->b_blocknr, bh, bh->b_data )); |
| 822 | } |
| 823 | |
| 824 | |
| 825 | void __bforget(struct buffer_head *bh) |
no test coverage detected