f2fs: fix to avoid accessing invalid fio in f2fs_allocate_data_block()
[linux-2.6-microblaze.git] / mm / migrate.c
index c0efe92..62b81d5 100644 (file)
@@ -331,7 +331,7 @@ void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
        if (!get_page_unless_zero(page))
                goto out;
        pte_unmap_unlock(ptep, ptl);
-       put_and_wait_on_page_locked(page);
+       put_and_wait_on_page_locked(page, TASK_UNINTERRUPTIBLE);
        return;
 out:
        pte_unmap_unlock(ptep, ptl);
@@ -365,7 +365,7 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
        if (!get_page_unless_zero(page))
                goto unlock;
        spin_unlock(ptl);
-       put_and_wait_on_page_locked(page);
+       put_and_wait_on_page_locked(page, TASK_UNINTERRUPTIBLE);
        return;
 unlock:
        spin_unlock(ptl);
@@ -500,6 +500,12 @@ int migrate_page_move_mapping(struct address_space *mapping,
                        __mod_lruvec_state(old_lruvec, NR_SHMEM, -nr);
                        __mod_lruvec_state(new_lruvec, NR_SHMEM, nr);
                }
+#ifdef CONFIG_SWAP
+               if (PageSwapCache(page)) {
+                       __mod_lruvec_state(old_lruvec, NR_SWAPCACHE, -nr);
+                       __mod_lruvec_state(new_lruvec, NR_SWAPCACHE, nr);
+               }
+#endif
                if (dirty && mapping_can_writeback(mapping)) {
                        __mod_lruvec_state(old_lruvec, NR_FILE_DIRTY, -nr);
                        __mod_zone_page_state(oldzone, NR_ZONE_WRITE_PENDING, -nr);
@@ -1280,6 +1286,12 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
                return -ENOSYS;
        }
 
+       if (page_count(hpage) == 1) {
+               /* page was freed from under us. So we are done. */
+               putback_active_hugepage(hpage);
+               return MIGRATEPAGE_SUCCESS;
+       }
+
        new_hpage = get_new_page(hpage, private);
        if (!new_hpage)
                return -ENOMEM;