|
@@ -1668,6 +1668,15 @@ find_page:
|
|
|
index, last_index - index);
|
|
|
}
|
|
|
if (!PageUptodate(page)) {
|
|
|
+ /*
|
|
|
+ * See comment in do_read_cache_page on why
|
|
|
+ * wait_on_page_locked is used to avoid unnecessarily
|
|
|
+ * serialisations and why it's safe.
|
|
|
+ */
|
|
|
+ wait_on_page_locked_killable(page);
|
|
|
+ if (PageUptodate(page))
|
|
|
+ goto page_ok;
|
|
|
+
|
|
|
if (inode->i_blkbits == PAGE_CACHE_SHIFT ||
|
|
|
!mapping->a_ops->is_partially_uptodate)
|
|
|
goto page_not_up_to_date;
|
|
@@ -2341,12 +2350,52 @@ filler:
|
|
|
if (PageUptodate(page))
|
|
|
goto out;
|
|
|
|
|
|
+ /*
|
|
|
+ * Page is not up to date and may be locked due one of the following
|
|
|
+ * case a: Page is being filled and the page lock is held
|
|
|
+ * case b: Read/write error clearing the page uptodate status
|
|
|
+ * case c: Truncation in progress (page locked)
|
|
|
+ * case d: Reclaim in progress
|
|
|
+ *
|
|
|
+ * Case a, the page will be up to date when the page is unlocked.
|
|
|
+ * There is no need to serialise on the page lock here as the page
|
|
|
+ * is pinned so the lock gives no additional protection. Even if the
|
|
|
+ * the page is truncated, the data is still valid if PageUptodate as
|
|
|
+ * it's a race vs truncate race.
|
|
|
+ * Case b, the page will not be up to date
|
|
|
+ * Case c, the page may be truncated but in itself, the data may still
|
|
|
+ * be valid after IO completes as it's a read vs truncate race. The
|
|
|
+ * operation must restart if the page is not uptodate on unlock but
|
|
|
+ * otherwise serialising on page lock to stabilise the mapping gives
|
|
|
+ * no additional guarantees to the caller as the page lock is
|
|
|
+ * released before return.
|
|
|
+ * Case d, similar to truncation. If reclaim holds the page lock, it
|
|
|
+ * will be a race with remove_mapping that determines if the mapping
|
|
|
+ * is valid on unlock but otherwise the data is valid and there is
|
|
|
+ * no need to serialise with page lock.
|
|
|
+ *
|
|
|
+ * As the page lock gives no additional guarantee, we optimistically
|
|
|
+ * wait on the page to be unlocked and check if it's up to date and
|
|
|
+ * use the page if it is. Otherwise, the page lock is required to
|
|
|
+ * distinguish between the different cases. The motivation is that we
|
|
|
+ * avoid spurious serialisations and wakeups when multiple processes
|
|
|
+ * wait on the same page for IO to complete.
|
|
|
+ */
|
|
|
+ wait_on_page_locked(page);
|
|
|
+ if (PageUptodate(page))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /* Distinguish between all the cases under the safety of the lock */
|
|
|
lock_page(page);
|
|
|
+
|
|
|
+ /* Case c or d, restart the operation */
|
|
|
if (!page->mapping) {
|
|
|
unlock_page(page);
|
|
|
page_cache_release(page);
|
|
|
goto repeat;
|
|
|
}
|
|
|
+
|
|
|
+ /* Someone else locked and filled the page in a very small window */
|
|
|
if (PageUptodate(page)) {
|
|
|
unlock_page(page);
|
|
|
goto out;
|