aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/pagemap.h15
-rw-r--r--mm/filemap.c17
-rw-r--r--mm/page-writeback.c2
3 files changed, 33 insertions, 1 deletions
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 0a2f5d27f60e..64f950925151 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -130,14 +130,29 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
130} 130}
131 131
132extern void FASTCALL(__lock_page(struct page *page)); 132extern void FASTCALL(__lock_page(struct page *page));
133extern void FASTCALL(__lock_page_nosync(struct page *page));
133extern void FASTCALL(unlock_page(struct page *page)); 134extern void FASTCALL(unlock_page(struct page *page));
134 135
136/*
137 * lock_page may only be called if we have the page's inode pinned.
138 */
135static inline void lock_page(struct page *page) 139static inline void lock_page(struct page *page)
136{ 140{
137 might_sleep(); 141 might_sleep();
138 if (TestSetPageLocked(page)) 142 if (TestSetPageLocked(page))
139 __lock_page(page); 143 __lock_page(page);
140} 144}
145
146/*
147 * lock_page_nosync should only be used if we can't pin the page's inode.
148 * Doesn't play quite so well with block device plugging.
149 */
150static inline void lock_page_nosync(struct page *page)
151{
152 might_sleep();
153 if (TestSetPageLocked(page))
154 __lock_page_nosync(page);
155}
141 156
142/* 157/*
143 * This is exported only for wait_on_page_locked/wait_on_page_writeback. 158 * This is exported only for wait_on_page_locked/wait_on_page_writeback.
diff --git a/mm/filemap.c b/mm/filemap.c
index b9a60c43b61a..d5af1cab4268 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -488,6 +488,12 @@ struct page *page_cache_alloc_cold(struct address_space *x)
488EXPORT_SYMBOL(page_cache_alloc_cold); 488EXPORT_SYMBOL(page_cache_alloc_cold);
489#endif 489#endif
490 490
491static int __sleep_on_page_lock(void *word)
492{
493 io_schedule();
494 return 0;
495}
496
491/* 497/*
492 * In order to wait for pages to become available there must be 498 * In order to wait for pages to become available there must be
493 * waitqueues associated with pages. By using a hash table of 499 * waitqueues associated with pages. By using a hash table of
@@ -577,6 +583,17 @@ void fastcall __lock_page(struct page *page)
577} 583}
578EXPORT_SYMBOL(__lock_page); 584EXPORT_SYMBOL(__lock_page);
579 585
586/*
587 * Variant of lock_page that does not require the caller to hold a reference
588 * on the page's mapping.
589 */
590void fastcall __lock_page_nosync(struct page *page)
591{
592 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
593 __wait_on_bit_lock(page_waitqueue(page), &wait, __sleep_on_page_lock,
594 TASK_UNINTERRUPTIBLE);
595}
596
580/** 597/**
581 * find_get_page - find and get a page reference 598 * find_get_page - find and get a page reference
582 * @mapping: the address_space to search 599 * @mapping: the address_space to search
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index b9f4c6f1be86..555752907dc3 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -701,7 +701,7 @@ int set_page_dirty_lock(struct page *page)
701{ 701{
702 int ret; 702 int ret;
703 703
704 lock_page(page); 704 lock_page_nosync(page);
705 ret = set_page_dirty(page); 705 ret = set_page_dirty(page);
706 unlock_page(page); 706 unlock_page(page);
707 return ret; 707 return ret;