diff options
Diffstat (limited to 'mm/filemap.c')
| -rw-r--r-- | mm/filemap.c | 24 |
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; |
