|
@@ -654,15 +654,32 @@ EXPORT_SYMBOL_GPL(__lock_page_killable);
|
|
int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
|
|
int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
|
|
unsigned int flags)
|
|
unsigned int flags)
|
|
{
|
|
{
|
|
- if (!(flags & FAULT_FLAG_ALLOW_RETRY)) {
|
|
|
|
- __lock_page(page);
|
|
|
|
- return 1;
|
|
|
|
- } else {
|
|
|
|
- if (!(flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
|
|
|
- up_read(&mm->mmap_sem);
|
|
|
|
|
|
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
|
|
|
|
+ /*
|
|
|
|
+ * CAUTION! In this case, mmap_sem is not released
|
|
|
|
+ * even though return 0.
|
|
|
|
+ */
|
|
|
|
+ if (flags & FAULT_FLAG_RETRY_NOWAIT)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ up_read(&mm->mmap_sem);
|
|
|
|
+ if (flags & FAULT_FLAG_KILLABLE)
|
|
|
|
+ wait_on_page_locked_killable(page);
|
|
|
|
+ else
|
|
wait_on_page_locked(page);
|
|
wait_on_page_locked(page);
|
|
- }
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
+ } else {
|
|
|
|
+ if (flags & FAULT_FLAG_KILLABLE) {
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = __lock_page_killable(page);
|
|
|
|
+ if (ret) {
|
|
|
|
+ up_read(&mm->mmap_sem);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ } else
|
|
|
|
+ __lock_page(page);
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|