aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-31 19:45:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-31 19:45:47 -0500
commit75659ca0c10992dcb39258518368a0f6f56e935d (patch)
tree5d014ceb2f10158061a23d0d976f9a613d85e659 /mm/filemap.c
parentfbdde7bd274d74729954190f99afcb1e3d9bbfba (diff)
parent2dfe485a2c8afa54cb069fcf48476f6c90ea3fdf (diff)
Merge branch 'task_killable' of git://git.kernel.org/pub/scm/linux/kernel/git/willy/misc
* 'task_killable' of git://git.kernel.org/pub/scm/linux/kernel/git/willy/misc: (22 commits) Remove commented-out code copied from NFS NFS: Switch from intr mount option to TASK_KILLABLE Add wait_for_completion_killable Add wait_event_killable Add schedule_timeout_killable Use mutex_lock_killable in vfs_readdir Add mutex_lock_killable Use lock_page_killable Add lock_page_killable Add fatal_signal_pending Add TASK_WAKEKILL exit: Use task_is_* signal: Use task_is_* sched: Use task_contributes_to_load, TASK_ALL and TASK_NORMAL ptrace: Use task_is_* power: Use task_is_* wait: Use TASK_NORMAL proc/base.c: Use task_is_* proc/array.c: Use TASK_REPORT perfmon: Use task_is_* ... Fixed up conflicts in NFS/sunrpc manually..
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index f4d0cded0e10..89ce6fe5f8be 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -185,6 +185,12 @@ static int sync_page(void *word)
185 return 0; 185 return 0;
186} 186}
187 187
188static int sync_page_killable(void *word)
189{
190 sync_page(word);
191 return fatal_signal_pending(current) ? -EINTR : 0;
192}
193
188/** 194/**
189 * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range 195 * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range
190 * @mapping: address space structure to write 196 * @mapping: address space structure to write
@@ -589,6 +595,14 @@ void fastcall __lock_page(struct page *page)
589} 595}
590EXPORT_SYMBOL(__lock_page); 596EXPORT_SYMBOL(__lock_page);
591 597
598int fastcall __lock_page_killable(struct page *page)
599{
600 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
601
602 return __wait_on_bit_lock(page_waitqueue(page), &wait,
603 sync_page_killable, TASK_KILLABLE);
604}
605
592/* 606/*
593 * Variant of lock_page that does not require the caller to hold a reference 607 * Variant of lock_page that does not require the caller to hold a reference
594 * on the page's mapping. 608 * on the page's mapping.
@@ -980,7 +994,8 @@ page_ok:
980 994
981page_not_up_to_date: 995page_not_up_to_date:
982 /* Get exclusive access to the page ... */ 996 /* Get exclusive access to the page ... */
983 lock_page(page); 997 if (lock_page_killable(page))
998 goto readpage_eio;
984 999
985 /* Did it get truncated before we got the lock? */ 1000 /* Did it get truncated before we got the lock? */
986 if (!page->mapping) { 1001 if (!page->mapping) {
@@ -1008,7 +1023,8 @@ readpage:
1008 } 1023 }
1009 1024
1010 if (!PageUptodate(page)) { 1025 if (!PageUptodate(page)) {
1011 lock_page(page); 1026 if (lock_page_killable(page))
1027 goto readpage_eio;
1012 if (!PageUptodate(page)) { 1028 if (!PageUptodate(page)) {
1013 if (page->mapping == NULL) { 1029 if (page->mapping == NULL) {
1014 /* 1030 /*
@@ -1019,15 +1035,16 @@ readpage:
1019 goto find_page; 1035 goto find_page;
1020 } 1036 }
1021 unlock_page(page); 1037 unlock_page(page);
1022 error = -EIO;
1023 shrink_readahead_size_eio(filp, ra); 1038 shrink_readahead_size_eio(filp, ra);
1024 goto readpage_error; 1039 goto readpage_eio;
1025 } 1040 }
1026 unlock_page(page); 1041 unlock_page(page);
1027 } 1042 }
1028 1043
1029 goto page_ok; 1044 goto page_ok;
1030 1045
1046readpage_eio:
1047 error = -EIO;
1031readpage_error: 1048readpage_error:
1032 /* UHHUH! A synchronous read error occurred. Report it */ 1049 /* UHHUH! A synchronous read error occurred. Report it */
1033 desc->error = error; 1050 desc->error = error;