diff options
Diffstat (limited to 'fs/buffer.c')
| -rw-r--r-- | fs/buffer.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 561e63a14966..6a25d7df89b1 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -513,8 +513,8 @@ static void free_more_memory(void) | |||
| 513 | */ | 513 | */ |
| 514 | static void end_buffer_async_read(struct buffer_head *bh, int uptodate) | 514 | static void end_buffer_async_read(struct buffer_head *bh, int uptodate) |
| 515 | { | 515 | { |
| 516 | static DEFINE_SPINLOCK(page_uptodate_lock); | ||
| 517 | unsigned long flags; | 516 | unsigned long flags; |
| 517 | struct buffer_head *first; | ||
| 518 | struct buffer_head *tmp; | 518 | struct buffer_head *tmp; |
| 519 | struct page *page; | 519 | struct page *page; |
| 520 | int page_uptodate = 1; | 520 | int page_uptodate = 1; |
| @@ -536,7 +536,9 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 536 | * two buffer heads end IO at almost the same time and both | 536 | * two buffer heads end IO at almost the same time and both |
| 537 | * decide that the page is now completely done. | 537 | * decide that the page is now completely done. |
| 538 | */ | 538 | */ |
| 539 | spin_lock_irqsave(&page_uptodate_lock, flags); | 539 | first = page_buffers(page); |
| 540 | local_irq_save(flags); | ||
| 541 | bit_spin_lock(BH_Uptodate_Lock, &first->b_state); | ||
| 540 | clear_buffer_async_read(bh); | 542 | clear_buffer_async_read(bh); |
| 541 | unlock_buffer(bh); | 543 | unlock_buffer(bh); |
| 542 | tmp = bh; | 544 | tmp = bh; |
| @@ -549,7 +551,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 549 | } | 551 | } |
| 550 | tmp = tmp->b_this_page; | 552 | tmp = tmp->b_this_page; |
| 551 | } while (tmp != bh); | 553 | } while (tmp != bh); |
| 552 | spin_unlock_irqrestore(&page_uptodate_lock, flags); | 554 | bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); |
| 555 | local_irq_restore(flags); | ||
| 553 | 556 | ||
| 554 | /* | 557 | /* |
| 555 | * If none of the buffers had errors and they are all | 558 | * If none of the buffers had errors and they are all |
| @@ -561,7 +564,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 561 | return; | 564 | return; |
| 562 | 565 | ||
| 563 | still_busy: | 566 | still_busy: |
| 564 | spin_unlock_irqrestore(&page_uptodate_lock, flags); | 567 | bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); |
| 568 | local_irq_restore(flags); | ||
| 565 | return; | 569 | return; |
| 566 | } | 570 | } |
| 567 | 571 | ||
| @@ -572,8 +576,8 @@ still_busy: | |||
| 572 | void end_buffer_async_write(struct buffer_head *bh, int uptodate) | 576 | void end_buffer_async_write(struct buffer_head *bh, int uptodate) |
| 573 | { | 577 | { |
| 574 | char b[BDEVNAME_SIZE]; | 578 | char b[BDEVNAME_SIZE]; |
| 575 | static DEFINE_SPINLOCK(page_uptodate_lock); | ||
| 576 | unsigned long flags; | 579 | unsigned long flags; |
| 580 | struct buffer_head *first; | ||
| 577 | struct buffer_head *tmp; | 581 | struct buffer_head *tmp; |
| 578 | struct page *page; | 582 | struct page *page; |
| 579 | 583 | ||
| @@ -594,7 +598,10 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) | |||
| 594 | SetPageError(page); | 598 | SetPageError(page); |
| 595 | } | 599 | } |
| 596 | 600 | ||
| 597 | spin_lock_irqsave(&page_uptodate_lock, flags); | 601 | first = page_buffers(page); |
| 602 | local_irq_save(flags); | ||
| 603 | bit_spin_lock(BH_Uptodate_Lock, &first->b_state); | ||
| 604 | |||
| 598 | clear_buffer_async_write(bh); | 605 | clear_buffer_async_write(bh); |
| 599 | unlock_buffer(bh); | 606 | unlock_buffer(bh); |
| 600 | tmp = bh->b_this_page; | 607 | tmp = bh->b_this_page; |
| @@ -605,12 +612,14 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) | |||
| 605 | } | 612 | } |
| 606 | tmp = tmp->b_this_page; | 613 | tmp = tmp->b_this_page; |
| 607 | } | 614 | } |
| 608 | spin_unlock_irqrestore(&page_uptodate_lock, flags); | 615 | bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); |
| 616 | local_irq_restore(flags); | ||
| 609 | end_page_writeback(page); | 617 | end_page_writeback(page); |
| 610 | return; | 618 | return; |
| 611 | 619 | ||
| 612 | still_busy: | 620 | still_busy: |
| 613 | spin_unlock_irqrestore(&page_uptodate_lock, flags); | 621 | bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); |
| 622 | local_irq_restore(flags); | ||
| 614 | return; | 623 | return; |
| 615 | } | 624 | } |
| 616 | 625 | ||
