aboutsummaryrefslogtreecommitdiff
path: root/mm/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index fbf17c5c32f..d4e69bc9d38 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -182,6 +182,11 @@ static int sleep_on_page(void *word)
return 0;
}
+static int sleep_on_page_timeout(void *word)
+{
+ return io_schedule_timeout(2) ? 0 : -EAGAIN;
+}
+
static int sleep_on_page_killable(void *word)
{
sleep_on_page(word);
@@ -562,6 +567,16 @@ void wait_on_page_bit(struct page *page, int bit_nr)
}
EXPORT_SYMBOL(wait_on_page_bit);
+void wait_on_page_bit_timeout(struct page *page, int bit_nr)
+{
+ DEFINE_WAIT_BIT(wait, &page->flags, bit_nr);
+
+ if (test_bit(bit_nr, &page->flags))
+ __wait_on_bit(page_waitqueue(page), &wait,
+ sleep_on_page_timeout, TASK_UNINTERRUPTIBLE);
+}
+EXPORT_SYMBOL(wait_on_page_bit_timeout);
+
int wait_on_page_bit_killable(struct page *page, int bit_nr)
{
DEFINE_WAIT_BIT(wait, &page->flags, bit_nr);
@@ -2388,6 +2403,11 @@ again:
break;
}
+ if (fatal_signal_pending(current)) {
+ status = -EINTR;
+ break;
+ }
+
status = a_ops->write_begin(file, mapping, pos, bytes, flags,
&page, &fsdata);
if (unlikely(status))
@@ -2428,10 +2448,6 @@ again:
written += copied;
balance_dirty_pages_ratelimited(mapping);
- if (fatal_signal_pending(current)) {
- status = -EINTR;
- break;
- }
} while (iov_iter_count(i));
return written ? written : status;