| 426 | } |
| 427 | |
| 428 | struct buffer_head * |
| 429 | get_block_bh_mdl( |
| 430 | struct block_device * bdev, |
| 431 | sector_t block, |
| 432 | unsigned long size, |
| 433 | int zero |
| 434 | ) |
| 435 | { |
| 436 | PEXT2_VCB Vcb = bdev->bd_priv; |
| 437 | LARGE_INTEGER offset; |
| 438 | PVOID bcb = NULL; |
| 439 | PVOID ptr = NULL; |
| 440 | |
| 441 | struct list_head *entry; |
| 442 | |
| 443 | /* allocate buffer_head and initialize it */ |
| 444 | struct buffer_head *bh = NULL, *tbh = NULL; |
| 445 | |
| 446 | /* check the block is valid or not */ |
| 447 | if (block >= TOTAL_BLOCKS) { |
| 448 | DbgBreak(); |
| 449 | goto errorout; |
| 450 | } |
| 451 | |
| 452 | /* search the bdev bh list */ |
| 453 | ExAcquireSharedStarveExclusive(&bdev->bd_bh_lock, TRUE); |
| 454 | tbh = buffer_head_search(bdev, block); |
| 455 | if (tbh) { |
| 456 | bh = tbh; |
| 457 | get_bh(bh); |
| 458 | ExReleaseResourceLite(&bdev->bd_bh_lock); |
| 459 | goto errorout; |
| 460 | } |
| 461 | ExReleaseResourceLite(&bdev->bd_bh_lock); |
| 462 | |
| 463 | bh = new_buffer_head(); |
| 464 | if (!bh) { |
| 465 | goto errorout; |
| 466 | } |
| 467 | bh->b_bdev = bdev; |
| 468 | bh->b_blocknr = block; |
| 469 | bh->b_size = size; |
| 470 | bh->b_data = NULL; |
| 471 | |
| 472 | again: |
| 473 | |
| 474 | offset.QuadPart = (s64) bh->b_blocknr; |
| 475 | offset.QuadPart <<= BLOCK_BITS; |
| 476 | |
| 477 | if (zero) { |
| 478 | /* PIN_EXCLUSIVE disabled, likely to deadlock with volume operations */ |
| 479 | if (!CcPreparePinWrite(Vcb->Volume, |
| 480 | &offset, |
| 481 | bh->b_size, |
| 482 | FALSE, |
| 483 | PIN_WAIT /* | PIN_EXCLUSIVE */, |
| 484 | &bcb, |
| 485 | &ptr)) { |
no test coverage detected