|
@@ -513,8 +513,8 @@ static void free_more_memory(void)
|
|
*/
|
|
*/
|
|
static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
|
static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
|
{
|
|
{
|
|
- static DEFINE_SPINLOCK(page_uptodate_lock);
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
+ struct buffer_head *first;
|
|
struct buffer_head *tmp;
|
|
struct buffer_head *tmp;
|
|
struct page *page;
|
|
struct page *page;
|
|
int page_uptodate = 1;
|
|
int page_uptodate = 1;
|
|
@@ -536,7 +536,9 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
|
* two buffer heads end IO at almost the same time and both
|
|
* two buffer heads end IO at almost the same time and both
|
|
* decide that the page is now completely done.
|
|
* decide that the page is now completely done.
|
|
*/
|
|
*/
|
|
- spin_lock_irqsave(&page_uptodate_lock, flags);
|
|
|
|
|
|
+ first = page_buffers(page);
|
|
|
|
+ local_irq_save(flags);
|
|
|
|
+ bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
|
|
clear_buffer_async_read(bh);
|
|
clear_buffer_async_read(bh);
|
|
unlock_buffer(bh);
|
|
unlock_buffer(bh);
|
|
tmp = bh;
|
|
tmp = bh;
|
|
@@ -549,7 +551,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
|
|
}
|
|
}
|
|
tmp = tmp->b_this_page;
|
|
tmp = tmp->b_this_page;
|
|
} while (tmp != bh);
|
|
} while (tmp != bh);
|
|
- spin_unlock_irqrestore(&page_uptodate_lock, flags);
|
|
|
|
|
|
+ bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
|
|
|
+ local_irq_restore(flags);
|
|
|
|
|
|
/*
|
|
/*
|
|
* If none of the buffers had errors and they are all
|
|
* 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)
|
|
return;
|
|
return;
|
|
|
|
|
|
still_busy:
|
|
still_busy:
|
|
- spin_unlock_irqrestore(&page_uptodate_lock, flags);
|
|
|
|
|
|
+ bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
|
|
|
+ local_irq_restore(flags);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -572,8 +576,8 @@ still_busy:
|
|
void end_buffer_async_write(struct buffer_head *bh, int uptodate)
|
|
void end_buffer_async_write(struct buffer_head *bh, int uptodate)
|
|
{
|
|
{
|
|
char b[BDEVNAME_SIZE];
|
|
char b[BDEVNAME_SIZE];
|
|
- static DEFINE_SPINLOCK(page_uptodate_lock);
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
+ struct buffer_head *first;
|
|
struct buffer_head *tmp;
|
|
struct buffer_head *tmp;
|
|
struct page *page;
|
|
struct page *page;
|
|
|
|
|
|
@@ -594,7 +598,10 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
|
|
SetPageError(page);
|
|
SetPageError(page);
|
|
}
|
|
}
|
|
|
|
|
|
- spin_lock_irqsave(&page_uptodate_lock, flags);
|
|
|
|
|
|
+ first = page_buffers(page);
|
|
|
|
+ local_irq_save(flags);
|
|
|
|
+ bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
|
|
|
|
+
|
|
clear_buffer_async_write(bh);
|
|
clear_buffer_async_write(bh);
|
|
unlock_buffer(bh);
|
|
unlock_buffer(bh);
|
|
tmp = bh->b_this_page;
|
|
tmp = bh->b_this_page;
|
|
@@ -605,12 +612,14 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
|
|
}
|
|
}
|
|
tmp = tmp->b_this_page;
|
|
tmp = tmp->b_this_page;
|
|
}
|
|
}
|
|
- spin_unlock_irqrestore(&page_uptodate_lock, flags);
|
|
|
|
|
|
+ bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
|
|
|
+ local_irq_restore(flags);
|
|
end_page_writeback(page);
|
|
end_page_writeback(page);
|
|
return;
|
|
return;
|
|
|
|
|
|
still_busy:
|
|
still_busy:
|
|
- spin_unlock_irqrestore(&page_uptodate_lock, flags);
|
|
|
|
|
|
+ bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
|
|
|
|
+ local_irq_restore(flags);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|