libceph: move r_reply_op_{len,result} into struct ceph_osd_req_op
[linux-2.6-block.git] / mm / mlock.c
index 9cb87cbc40715c72261189822aa43b3b30ecd284..96f00104192861aec6358d9fae5f9b39fecb43a4 100644 (file)
 
 #include "internal.h"
 
-int can_do_mlock(void)
+bool can_do_mlock(void)
 {
        if (rlimit(RLIMIT_MEMLOCK) != 0)
-               return 1;
+               return true;
        if (capable(CAP_IPC_LOCK))
-               return 1;
-       return 0;
+               return true;
+       return false;
 }
 EXPORT_SYMBOL(can_do_mlock);
 
@@ -82,6 +82,9 @@ void mlock_vma_page(struct page *page)
        /* Serialize with page migration */
        BUG_ON(!PageLocked(page));
 
+       VM_BUG_ON_PAGE(PageTail(page), page);
+       VM_BUG_ON_PAGE(PageCompound(page) && PageDoubleMap(page), page);
+
        if (!TestSetPageMlocked(page)) {
                mod_zone_page_state(page_zone(page), NR_MLOCK,
                                    hpage_nr_pages(page));
@@ -172,12 +175,14 @@ static void __munlock_isolation_failed(struct page *page)
  */
 unsigned int munlock_vma_page(struct page *page)
 {
-       unsigned int nr_pages;
+       int nr_pages;
        struct zone *zone = page_zone(page);
 
        /* For try_to_munlock() and to serialize with page migration */
        BUG_ON(!PageLocked(page));
 
+       VM_BUG_ON_PAGE(PageTail(page), page);
+
        /*
         * Serialize with any parallel __split_huge_page_refcount() which
         * might otherwise copy PageMlocked to part of the tail pages before
@@ -388,6 +393,13 @@ static unsigned long __munlock_pagevec_fill(struct pagevec *pvec,
                if (!page || page_zone_id(page) != zoneid)
                        break;
 
+               /*
+                * Do not use pagevec for PTE-mapped THP,
+                * munlock_vma_pages_range() will handle them.
+                */
+               if (PageTransCompound(page))
+                       break;
+
                get_page(page);
                /*
                 * Increase the address that will be returned *before* the
@@ -444,7 +456,10 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
                                &page_mask);
 
                if (page && !IS_ERR(page)) {
-                       if (PageTransHuge(page)) {
+                       if (PageTransTail(page)) {
+                               VM_BUG_ON_PAGE(PageMlocked(page), page);
+                               put_page(page); /* follow_page_mask() */
+                       } else if (PageTransHuge(page)) {
                                lock_page(page);
                                /*
                                 * Any THP page found by follow_page_mask() may
@@ -477,8 +492,6 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
                                goto next;
                        }
                }
-               /* It's a bug to munlock in the middle of a THP page */
-               VM_BUG_ON((start >> PAGE_SHIFT) & page_mask);
                page_increm = 1 + page_mask;
                start += page_increm * PAGE_SIZE;
 next: