diff options
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index f43b3dca12b5..3992bd5120e7 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -116,7 +116,9 @@ static void update_and_free_page(struct page *page) | |||
116 | static void free_huge_page(struct page *page) | 116 | static void free_huge_page(struct page *page) |
117 | { | 117 | { |
118 | int nid = page_to_nid(page); | 118 | int nid = page_to_nid(page); |
119 | struct address_space *mapping; | ||
119 | 120 | ||
121 | mapping = (struct address_space *) page_private(page); | ||
120 | BUG_ON(page_count(page)); | 122 | BUG_ON(page_count(page)); |
121 | INIT_LIST_HEAD(&page->lru); | 123 | INIT_LIST_HEAD(&page->lru); |
122 | 124 | ||
@@ -129,6 +131,9 @@ static void free_huge_page(struct page *page) | |||
129 | enqueue_huge_page(page); | 131 | enqueue_huge_page(page); |
130 | } | 132 | } |
131 | spin_unlock(&hugetlb_lock); | 133 | spin_unlock(&hugetlb_lock); |
134 | if (mapping) | ||
135 | hugetlb_put_quota(mapping); | ||
136 | set_page_private(page, 0); | ||
132 | } | 137 | } |
133 | 138 | ||
134 | /* | 139 | /* |
@@ -388,8 +393,10 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, | |||
388 | page = alloc_huge_page_shared(vma, addr); | 393 | page = alloc_huge_page_shared(vma, addr); |
389 | else | 394 | else |
390 | page = alloc_huge_page_private(vma, addr); | 395 | page = alloc_huge_page_private(vma, addr); |
391 | if (page) | 396 | if (page) { |
392 | set_page_refcounted(page); | 397 | set_page_refcounted(page); |
398 | set_page_private(page, (unsigned long) vma->vm_file->f_mapping); | ||
399 | } | ||
393 | return page; | 400 | return page; |
394 | } | 401 | } |
395 | 402 | ||
@@ -730,6 +737,8 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, | |||
730 | set_huge_ptep_writable(vma, address, ptep); | 737 | set_huge_ptep_writable(vma, address, ptep); |
731 | return 0; | 738 | return 0; |
732 | } | 739 | } |
740 | if (hugetlb_get_quota(vma->vm_file->f_mapping)) | ||
741 | return VM_FAULT_SIGBUS; | ||
733 | 742 | ||
734 | page_cache_get(old_page); | 743 | page_cache_get(old_page); |
735 | new_page = alloc_huge_page(vma, address); | 744 | new_page = alloc_huge_page(vma, address); |
@@ -796,7 +805,6 @@ retry: | |||
796 | err = add_to_page_cache(page, mapping, idx, GFP_KERNEL); | 805 | err = add_to_page_cache(page, mapping, idx, GFP_KERNEL); |
797 | if (err) { | 806 | if (err) { |
798 | put_page(page); | 807 | put_page(page); |
799 | hugetlb_put_quota(mapping); | ||
800 | if (err == -EEXIST) | 808 | if (err == -EEXIST) |
801 | goto retry; | 809 | goto retry; |
802 | goto out; | 810 | goto out; |
@@ -830,7 +838,6 @@ out: | |||
830 | 838 | ||
831 | backout: | 839 | backout: |
832 | spin_unlock(&mm->page_table_lock); | 840 | spin_unlock(&mm->page_table_lock); |
833 | hugetlb_put_quota(mapping); | ||
834 | unlock_page(page); | 841 | unlock_page(page); |
835 | put_page(page); | 842 | put_page(page); |
836 | goto out; | 843 | goto out; |