diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-23 18:11:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-23 18:11:11 -0400 |
commit | ed4a1084bc8dc47328392aa31e0bc04eb2dbffbb (patch) | |
tree | adf2543a5c7149c6287d7f03ecca1bffcb6395b2 | |
parent | 15ba2236f3556fc01b9ca91394465152b5ea74b6 (diff) | |
parent | 0253d634e0803a8376a0d88efee0bf523d8673f9 (diff) |
Merge branch 'akpm' (patches from Andrew Morton)
Merge fixes from Andrew Morton:
"10 fixes"
* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
mm: hugetlb: fix copy_hugetlb_page_range()
simple_xattr: permit 0-size extended attributes
mm/fs: fix pessimization in hole-punching pagecache
shmem: fix splicing from a hole while it's punched
shmem: fix faulting into a hole, not taking i_mutex
mm: do not call do_fault_around for non-linear fault
sh: also try passing -m4-nofpu for SH2A builds
zram: avoid lockdep splat by revalidate_disk
mm/rmap.c: fix pgoff calculation to handle hugepage correctly
coredump: fix the setting of PF_DUMPCORE
-rw-r--r-- | arch/sh/Makefile | 3 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.c | 22 | ||||
-rw-r--r-- | fs/coredump.c | 2 | ||||
-rw-r--r-- | fs/xattr.c | 2 | ||||
-rw-r--r-- | include/linux/pagemap.h | 12 | ||||
-rw-r--r-- | mm/hugetlb.c | 1 | ||||
-rw-r--r-- | mm/memory-failure.c | 4 | ||||
-rw-r--r-- | mm/memory.c | 3 | ||||
-rw-r--r-- | mm/rmap.c | 10 | ||||
-rw-r--r-- | mm/shmem.c | 102 | ||||
-rw-r--r-- | mm/truncate.c | 11 |
11 files changed, 117 insertions, 55 deletions
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index d4d16e4be07c..bf5b3f5f4962 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -32,7 +32,8 @@ endif | |||
32 | 32 | ||
33 | cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) | 33 | cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) |
34 | cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ | 34 | cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ |
35 | $(call cc-option,-m2a-nofpu,) | 35 | $(call cc-option,-m2a-nofpu,) \ |
36 | $(call cc-option,-m4-nofpu,) | ||
36 | cflags-$(CONFIG_CPU_SH3) := $(call cc-option,-m3,) | 37 | cflags-$(CONFIG_CPU_SH3) := $(call cc-option,-m3,) |
37 | cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \ | 38 | cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \ |
38 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) | 39 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 089e72cd37be..36e54be402df 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
@@ -622,11 +622,18 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity) | |||
622 | memset(&zram->stats, 0, sizeof(zram->stats)); | 622 | memset(&zram->stats, 0, sizeof(zram->stats)); |
623 | 623 | ||
624 | zram->disksize = 0; | 624 | zram->disksize = 0; |
625 | if (reset_capacity) { | 625 | if (reset_capacity) |
626 | set_capacity(zram->disk, 0); | 626 | set_capacity(zram->disk, 0); |
627 | revalidate_disk(zram->disk); | 627 | |
628 | } | ||
629 | up_write(&zram->init_lock); | 628 | up_write(&zram->init_lock); |
629 | |||
630 | /* | ||
631 | * Revalidate disk out of the init_lock to avoid lockdep splat. | ||
632 | * It's okay because disk's capacity is protected by init_lock | ||
633 | * so that revalidate_disk always sees up-to-date capacity. | ||
634 | */ | ||
635 | if (reset_capacity) | ||
636 | revalidate_disk(zram->disk); | ||
630 | } | 637 | } |
631 | 638 | ||
632 | static ssize_t disksize_store(struct device *dev, | 639 | static ssize_t disksize_store(struct device *dev, |
@@ -666,8 +673,15 @@ static ssize_t disksize_store(struct device *dev, | |||
666 | zram->comp = comp; | 673 | zram->comp = comp; |
667 | zram->disksize = disksize; | 674 | zram->disksize = disksize; |
668 | set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); | 675 | set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); |
669 | revalidate_disk(zram->disk); | ||
670 | up_write(&zram->init_lock); | 676 | up_write(&zram->init_lock); |
677 | |||
678 | /* | ||
679 | * Revalidate disk out of the init_lock to avoid lockdep splat. | ||
680 | * It's okay because disk's capacity is protected by init_lock | ||
681 | * so that revalidate_disk always sees up-to-date capacity. | ||
682 | */ | ||
683 | revalidate_disk(zram->disk); | ||
684 | |||
671 | return len; | 685 | return len; |
672 | 686 | ||
673 | out_destroy_comp: | 687 | out_destroy_comp: |
diff --git a/fs/coredump.c b/fs/coredump.c index 0b2528fb640e..a93f7e6ea4cf 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -306,7 +306,7 @@ static int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
306 | if (unlikely(nr < 0)) | 306 | if (unlikely(nr < 0)) |
307 | return nr; | 307 | return nr; |
308 | 308 | ||
309 | tsk->flags = PF_DUMPCORE; | 309 | tsk->flags |= PF_DUMPCORE; |
310 | if (atomic_read(&mm->mm_users) == nr + 1) | 310 | if (atomic_read(&mm->mm_users) == nr + 1) |
311 | goto done; | 311 | goto done; |
312 | /* | 312 | /* |
diff --git a/fs/xattr.c b/fs/xattr.c index 3377dff18404..c69e6d43a0d2 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -843,7 +843,7 @@ struct simple_xattr *simple_xattr_alloc(const void *value, size_t size) | |||
843 | 843 | ||
844 | /* wrap around? */ | 844 | /* wrap around? */ |
845 | len = sizeof(*new_xattr) + size; | 845 | len = sizeof(*new_xattr) + size; |
846 | if (len <= sizeof(*new_xattr)) | 846 | if (len < sizeof(*new_xattr)) |
847 | return NULL; | 847 | return NULL; |
848 | 848 | ||
849 | new_xattr = kmalloc(len, GFP_KERNEL); | 849 | new_xattr = kmalloc(len, GFP_KERNEL); |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 0a97b583ee8d..e1474ae18c88 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -399,6 +399,18 @@ static inline struct page *read_mapping_page(struct address_space *mapping, | |||
399 | } | 399 | } |
400 | 400 | ||
401 | /* | 401 | /* |
402 | * Get the offset in PAGE_SIZE. | ||
403 | * (TODO: hugepage should have ->index in PAGE_SIZE) | ||
404 | */ | ||
405 | static inline pgoff_t page_to_pgoff(struct page *page) | ||
406 | { | ||
407 | if (unlikely(PageHeadHuge(page))) | ||
408 | return page->index << compound_order(page); | ||
409 | else | ||
410 | return page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | ||
411 | } | ||
412 | |||
413 | /* | ||
402 | * Return byte-offset into filesystem object for page. | 414 | * Return byte-offset into filesystem object for page. |
403 | */ | 415 | */ |
404 | static inline loff_t page_offset(struct page *page) | 416 | static inline loff_t page_offset(struct page *page) |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 2024bbd573d2..9221c02ed9e2 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2604,6 +2604,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, | |||
2604 | } else { | 2604 | } else { |
2605 | if (cow) | 2605 | if (cow) |
2606 | huge_ptep_set_wrprotect(src, addr, src_pte); | 2606 | huge_ptep_set_wrprotect(src, addr, src_pte); |
2607 | entry = huge_ptep_get(src_pte); | ||
2607 | ptepage = pte_page(entry); | 2608 | ptepage = pte_page(entry); |
2608 | get_page(ptepage); | 2609 | get_page(ptepage); |
2609 | page_dup_rmap(ptepage); | 2610 | page_dup_rmap(ptepage); |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index c6399e328931..7211a73ba14d 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -435,7 +435,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, | |||
435 | if (av == NULL) /* Not actually mapped anymore */ | 435 | if (av == NULL) /* Not actually mapped anymore */ |
436 | return; | 436 | return; |
437 | 437 | ||
438 | pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 438 | pgoff = page_to_pgoff(page); |
439 | read_lock(&tasklist_lock); | 439 | read_lock(&tasklist_lock); |
440 | for_each_process (tsk) { | 440 | for_each_process (tsk) { |
441 | struct anon_vma_chain *vmac; | 441 | struct anon_vma_chain *vmac; |
@@ -469,7 +469,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill, | |||
469 | mutex_lock(&mapping->i_mmap_mutex); | 469 | mutex_lock(&mapping->i_mmap_mutex); |
470 | read_lock(&tasklist_lock); | 470 | read_lock(&tasklist_lock); |
471 | for_each_process(tsk) { | 471 | for_each_process(tsk) { |
472 | pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 472 | pgoff_t pgoff = page_to_pgoff(page); |
473 | struct task_struct *t = task_early_kill(tsk, force_early); | 473 | struct task_struct *t = task_early_kill(tsk, force_early); |
474 | 474 | ||
475 | if (!t) | 475 | if (!t) |
diff --git a/mm/memory.c b/mm/memory.c index d67fd9fcf1f2..7e8d8205b610 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2882,7 +2882,8 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2882 | * if page by the offset is not ready to be mapped (cold cache or | 2882 | * if page by the offset is not ready to be mapped (cold cache or |
2883 | * something). | 2883 | * something). |
2884 | */ | 2884 | */ |
2885 | if (vma->vm_ops->map_pages && fault_around_pages() > 1) { | 2885 | if (vma->vm_ops->map_pages && !(flags & FAULT_FLAG_NONLINEAR) && |
2886 | fault_around_pages() > 1) { | ||
2886 | pte = pte_offset_map_lock(mm, pmd, address, &ptl); | 2887 | pte = pte_offset_map_lock(mm, pmd, address, &ptl); |
2887 | do_fault_around(vma, address, pte, pgoff, flags); | 2888 | do_fault_around(vma, address, pte, pgoff, flags); |
2888 | if (!pte_same(*pte, orig_pte)) | 2889 | if (!pte_same(*pte, orig_pte)) |
@@ -517,11 +517,7 @@ void page_unlock_anon_vma_read(struct anon_vma *anon_vma) | |||
517 | static inline unsigned long | 517 | static inline unsigned long |
518 | __vma_address(struct page *page, struct vm_area_struct *vma) | 518 | __vma_address(struct page *page, struct vm_area_struct *vma) |
519 | { | 519 | { |
520 | pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 520 | pgoff_t pgoff = page_to_pgoff(page); |
521 | |||
522 | if (unlikely(is_vm_hugetlb_page(vma))) | ||
523 | pgoff = page->index << huge_page_order(page_hstate(page)); | ||
524 | |||
525 | return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); | 521 | return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); |
526 | } | 522 | } |
527 | 523 | ||
@@ -1639,7 +1635,7 @@ static struct anon_vma *rmap_walk_anon_lock(struct page *page, | |||
1639 | static int rmap_walk_anon(struct page *page, struct rmap_walk_control *rwc) | 1635 | static int rmap_walk_anon(struct page *page, struct rmap_walk_control *rwc) |
1640 | { | 1636 | { |
1641 | struct anon_vma *anon_vma; | 1637 | struct anon_vma *anon_vma; |
1642 | pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 1638 | pgoff_t pgoff = page_to_pgoff(page); |
1643 | struct anon_vma_chain *avc; | 1639 | struct anon_vma_chain *avc; |
1644 | int ret = SWAP_AGAIN; | 1640 | int ret = SWAP_AGAIN; |
1645 | 1641 | ||
@@ -1680,7 +1676,7 @@ static int rmap_walk_anon(struct page *page, struct rmap_walk_control *rwc) | |||
1680 | static int rmap_walk_file(struct page *page, struct rmap_walk_control *rwc) | 1676 | static int rmap_walk_file(struct page *page, struct rmap_walk_control *rwc) |
1681 | { | 1677 | { |
1682 | struct address_space *mapping = page->mapping; | 1678 | struct address_space *mapping = page->mapping; |
1683 | pgoff_t pgoff = page->index << compound_order(page); | 1679 | pgoff_t pgoff = page_to_pgoff(page); |
1684 | struct vm_area_struct *vma; | 1680 | struct vm_area_struct *vma; |
1685 | int ret = SWAP_AGAIN; | 1681 | int ret = SWAP_AGAIN; |
1686 | 1682 | ||
diff --git a/mm/shmem.c b/mm/shmem.c index 1140f49b6ded..af68b15a8fc1 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -85,7 +85,7 @@ static struct vfsmount *shm_mnt; | |||
85 | * a time): we would prefer not to enlarge the shmem inode just for that. | 85 | * a time): we would prefer not to enlarge the shmem inode just for that. |
86 | */ | 86 | */ |
87 | struct shmem_falloc { | 87 | struct shmem_falloc { |
88 | int mode; /* FALLOC_FL mode currently operating */ | 88 | wait_queue_head_t *waitq; /* faults into hole wait for punch to end */ |
89 | pgoff_t start; /* start of range currently being fallocated */ | 89 | pgoff_t start; /* start of range currently being fallocated */ |
90 | pgoff_t next; /* the next page offset to be fallocated */ | 90 | pgoff_t next; /* the next page offset to be fallocated */ |
91 | pgoff_t nr_falloced; /* how many new pages have been fallocated */ | 91 | pgoff_t nr_falloced; /* how many new pages have been fallocated */ |
@@ -468,23 +468,20 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, | |||
468 | return; | 468 | return; |
469 | 469 | ||
470 | index = start; | 470 | index = start; |
471 | for ( ; ; ) { | 471 | while (index < end) { |
472 | cond_resched(); | 472 | cond_resched(); |
473 | 473 | ||
474 | pvec.nr = find_get_entries(mapping, index, | 474 | pvec.nr = find_get_entries(mapping, index, |
475 | min(end - index, (pgoff_t)PAGEVEC_SIZE), | 475 | min(end - index, (pgoff_t)PAGEVEC_SIZE), |
476 | pvec.pages, indices); | 476 | pvec.pages, indices); |
477 | if (!pvec.nr) { | 477 | if (!pvec.nr) { |
478 | if (index == start || unfalloc) | 478 | /* If all gone or hole-punch or unfalloc, we're done */ |
479 | if (index == start || end != -1) | ||
479 | break; | 480 | break; |
481 | /* But if truncating, restart to make sure all gone */ | ||
480 | index = start; | 482 | index = start; |
481 | continue; | 483 | continue; |
482 | } | 484 | } |
483 | if ((index == start || unfalloc) && indices[0] >= end) { | ||
484 | pagevec_remove_exceptionals(&pvec); | ||
485 | pagevec_release(&pvec); | ||
486 | break; | ||
487 | } | ||
488 | mem_cgroup_uncharge_start(); | 485 | mem_cgroup_uncharge_start(); |
489 | for (i = 0; i < pagevec_count(&pvec); i++) { | 486 | for (i = 0; i < pagevec_count(&pvec); i++) { |
490 | struct page *page = pvec.pages[i]; | 487 | struct page *page = pvec.pages[i]; |
@@ -496,8 +493,12 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, | |||
496 | if (radix_tree_exceptional_entry(page)) { | 493 | if (radix_tree_exceptional_entry(page)) { |
497 | if (unfalloc) | 494 | if (unfalloc) |
498 | continue; | 495 | continue; |
499 | nr_swaps_freed += !shmem_free_swap(mapping, | 496 | if (shmem_free_swap(mapping, index, page)) { |
500 | index, page); | 497 | /* Swap was replaced by page: retry */ |
498 | index--; | ||
499 | break; | ||
500 | } | ||
501 | nr_swaps_freed++; | ||
501 | continue; | 502 | continue; |
502 | } | 503 | } |
503 | 504 | ||
@@ -506,6 +507,11 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, | |||
506 | if (page->mapping == mapping) { | 507 | if (page->mapping == mapping) { |
507 | VM_BUG_ON_PAGE(PageWriteback(page), page); | 508 | VM_BUG_ON_PAGE(PageWriteback(page), page); |
508 | truncate_inode_page(mapping, page); | 509 | truncate_inode_page(mapping, page); |
510 | } else { | ||
511 | /* Page was replaced by swap: retry */ | ||
512 | unlock_page(page); | ||
513 | index--; | ||
514 | break; | ||
509 | } | 515 | } |
510 | } | 516 | } |
511 | unlock_page(page); | 517 | unlock_page(page); |
@@ -760,7 +766,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) | |||
760 | spin_lock(&inode->i_lock); | 766 | spin_lock(&inode->i_lock); |
761 | shmem_falloc = inode->i_private; | 767 | shmem_falloc = inode->i_private; |
762 | if (shmem_falloc && | 768 | if (shmem_falloc && |
763 | !shmem_falloc->mode && | 769 | !shmem_falloc->waitq && |
764 | index >= shmem_falloc->start && | 770 | index >= shmem_falloc->start && |
765 | index < shmem_falloc->next) | 771 | index < shmem_falloc->next) |
766 | shmem_falloc->nr_unswapped++; | 772 | shmem_falloc->nr_unswapped++; |
@@ -1248,38 +1254,58 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1248 | * Trinity finds that probing a hole which tmpfs is punching can | 1254 | * Trinity finds that probing a hole which tmpfs is punching can |
1249 | * prevent the hole-punch from ever completing: which in turn | 1255 | * prevent the hole-punch from ever completing: which in turn |
1250 | * locks writers out with its hold on i_mutex. So refrain from | 1256 | * locks writers out with its hold on i_mutex. So refrain from |
1251 | * faulting pages into the hole while it's being punched, and | 1257 | * faulting pages into the hole while it's being punched. Although |
1252 | * wait on i_mutex to be released if vmf->flags permits. | 1258 | * shmem_undo_range() does remove the additions, it may be unable to |
1259 | * keep up, as each new page needs its own unmap_mapping_range() call, | ||
1260 | * and the i_mmap tree grows ever slower to scan if new vmas are added. | ||
1261 | * | ||
1262 | * It does not matter if we sometimes reach this check just before the | ||
1263 | * hole-punch begins, so that one fault then races with the punch: | ||
1264 | * we just need to make racing faults a rare case. | ||
1265 | * | ||
1266 | * The implementation below would be much simpler if we just used a | ||
1267 | * standard mutex or completion: but we cannot take i_mutex in fault, | ||
1268 | * and bloating every shmem inode for this unlikely case would be sad. | ||
1253 | */ | 1269 | */ |
1254 | if (unlikely(inode->i_private)) { | 1270 | if (unlikely(inode->i_private)) { |
1255 | struct shmem_falloc *shmem_falloc; | 1271 | struct shmem_falloc *shmem_falloc; |
1256 | 1272 | ||
1257 | spin_lock(&inode->i_lock); | 1273 | spin_lock(&inode->i_lock); |
1258 | shmem_falloc = inode->i_private; | 1274 | shmem_falloc = inode->i_private; |
1259 | if (!shmem_falloc || | 1275 | if (shmem_falloc && |
1260 | shmem_falloc->mode != FALLOC_FL_PUNCH_HOLE || | 1276 | shmem_falloc->waitq && |
1261 | vmf->pgoff < shmem_falloc->start || | 1277 | vmf->pgoff >= shmem_falloc->start && |
1262 | vmf->pgoff >= shmem_falloc->next) | 1278 | vmf->pgoff < shmem_falloc->next) { |
1263 | shmem_falloc = NULL; | 1279 | wait_queue_head_t *shmem_falloc_waitq; |
1264 | spin_unlock(&inode->i_lock); | 1280 | DEFINE_WAIT(shmem_fault_wait); |
1265 | /* | 1281 | |
1266 | * i_lock has protected us from taking shmem_falloc seriously | 1282 | ret = VM_FAULT_NOPAGE; |
1267 | * once return from shmem_fallocate() went back up that stack. | ||
1268 | * i_lock does not serialize with i_mutex at all, but it does | ||
1269 | * not matter if sometimes we wait unnecessarily, or sometimes | ||
1270 | * miss out on waiting: we just need to make those cases rare. | ||
1271 | */ | ||
1272 | if (shmem_falloc) { | ||
1273 | if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) && | 1283 | if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) && |
1274 | !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { | 1284 | !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { |
1285 | /* It's polite to up mmap_sem if we can */ | ||
1275 | up_read(&vma->vm_mm->mmap_sem); | 1286 | up_read(&vma->vm_mm->mmap_sem); |
1276 | mutex_lock(&inode->i_mutex); | 1287 | ret = VM_FAULT_RETRY; |
1277 | mutex_unlock(&inode->i_mutex); | ||
1278 | return VM_FAULT_RETRY; | ||
1279 | } | 1288 | } |
1280 | /* cond_resched? Leave that to GUP or return to user */ | 1289 | |
1281 | return VM_FAULT_NOPAGE; | 1290 | shmem_falloc_waitq = shmem_falloc->waitq; |
1291 | prepare_to_wait(shmem_falloc_waitq, &shmem_fault_wait, | ||
1292 | TASK_UNINTERRUPTIBLE); | ||
1293 | spin_unlock(&inode->i_lock); | ||
1294 | schedule(); | ||
1295 | |||
1296 | /* | ||
1297 | * shmem_falloc_waitq points into the shmem_fallocate() | ||
1298 | * stack of the hole-punching task: shmem_falloc_waitq | ||
1299 | * is usually invalid by the time we reach here, but | ||
1300 | * finish_wait() does not dereference it in that case; | ||
1301 | * though i_lock needed lest racing with wake_up_all(). | ||
1302 | */ | ||
1303 | spin_lock(&inode->i_lock); | ||
1304 | finish_wait(shmem_falloc_waitq, &shmem_fault_wait); | ||
1305 | spin_unlock(&inode->i_lock); | ||
1306 | return ret; | ||
1282 | } | 1307 | } |
1308 | spin_unlock(&inode->i_lock); | ||
1283 | } | 1309 | } |
1284 | 1310 | ||
1285 | error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret); | 1311 | error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret); |
@@ -1774,13 +1800,13 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, | |||
1774 | 1800 | ||
1775 | mutex_lock(&inode->i_mutex); | 1801 | mutex_lock(&inode->i_mutex); |
1776 | 1802 | ||
1777 | shmem_falloc.mode = mode & ~FALLOC_FL_KEEP_SIZE; | ||
1778 | |||
1779 | if (mode & FALLOC_FL_PUNCH_HOLE) { | 1803 | if (mode & FALLOC_FL_PUNCH_HOLE) { |
1780 | struct address_space *mapping = file->f_mapping; | 1804 | struct address_space *mapping = file->f_mapping; |
1781 | loff_t unmap_start = round_up(offset, PAGE_SIZE); | 1805 | loff_t unmap_start = round_up(offset, PAGE_SIZE); |
1782 | loff_t unmap_end = round_down(offset + len, PAGE_SIZE) - 1; | 1806 | loff_t unmap_end = round_down(offset + len, PAGE_SIZE) - 1; |
1807 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(shmem_falloc_waitq); | ||
1783 | 1808 | ||
1809 | shmem_falloc.waitq = &shmem_falloc_waitq; | ||
1784 | shmem_falloc.start = unmap_start >> PAGE_SHIFT; | 1810 | shmem_falloc.start = unmap_start >> PAGE_SHIFT; |
1785 | shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT; | 1811 | shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT; |
1786 | spin_lock(&inode->i_lock); | 1812 | spin_lock(&inode->i_lock); |
@@ -1792,8 +1818,13 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, | |||
1792 | 1 + unmap_end - unmap_start, 0); | 1818 | 1 + unmap_end - unmap_start, 0); |
1793 | shmem_truncate_range(inode, offset, offset + len - 1); | 1819 | shmem_truncate_range(inode, offset, offset + len - 1); |
1794 | /* No need to unmap again: hole-punching leaves COWed pages */ | 1820 | /* No need to unmap again: hole-punching leaves COWed pages */ |
1821 | |||
1822 | spin_lock(&inode->i_lock); | ||
1823 | inode->i_private = NULL; | ||
1824 | wake_up_all(&shmem_falloc_waitq); | ||
1825 | spin_unlock(&inode->i_lock); | ||
1795 | error = 0; | 1826 | error = 0; |
1796 | goto undone; | 1827 | goto out; |
1797 | } | 1828 | } |
1798 | 1829 | ||
1799 | /* We need to check rlimit even when FALLOC_FL_KEEP_SIZE */ | 1830 | /* We need to check rlimit even when FALLOC_FL_KEEP_SIZE */ |
@@ -1809,6 +1840,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, | |||
1809 | goto out; | 1840 | goto out; |
1810 | } | 1841 | } |
1811 | 1842 | ||
1843 | shmem_falloc.waitq = NULL; | ||
1812 | shmem_falloc.start = start; | 1844 | shmem_falloc.start = start; |
1813 | shmem_falloc.next = start; | 1845 | shmem_falloc.next = start; |
1814 | shmem_falloc.nr_falloced = 0; | 1846 | shmem_falloc.nr_falloced = 0; |
diff --git a/mm/truncate.c b/mm/truncate.c index 6a78c814bebf..eda247307164 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -355,14 +355,16 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
355 | for ( ; ; ) { | 355 | for ( ; ; ) { |
356 | cond_resched(); | 356 | cond_resched(); |
357 | if (!pagevec_lookup_entries(&pvec, mapping, index, | 357 | if (!pagevec_lookup_entries(&pvec, mapping, index, |
358 | min(end - index, (pgoff_t)PAGEVEC_SIZE), | 358 | min(end - index, (pgoff_t)PAGEVEC_SIZE), indices)) { |
359 | indices)) { | 359 | /* If all gone from start onwards, we're done */ |
360 | if (index == start) | 360 | if (index == start) |
361 | break; | 361 | break; |
362 | /* Otherwise restart to make sure all gone */ | ||
362 | index = start; | 363 | index = start; |
363 | continue; | 364 | continue; |
364 | } | 365 | } |
365 | if (index == start && indices[0] >= end) { | 366 | if (index == start && indices[0] >= end) { |
367 | /* All gone out of hole to be punched, we're done */ | ||
366 | pagevec_remove_exceptionals(&pvec); | 368 | pagevec_remove_exceptionals(&pvec); |
367 | pagevec_release(&pvec); | 369 | pagevec_release(&pvec); |
368 | break; | 370 | break; |
@@ -373,8 +375,11 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
373 | 375 | ||
374 | /* We rely upon deletion not changing page->index */ | 376 | /* We rely upon deletion not changing page->index */ |
375 | index = indices[i]; | 377 | index = indices[i]; |
376 | if (index >= end) | 378 | if (index >= end) { |
379 | /* Restart punch to make sure all gone */ | ||
380 | index = start - 1; | ||
377 | break; | 381 | break; |
382 | } | ||
378 | 383 | ||
379 | if (radix_tree_exceptional_entry(page)) { | 384 | if (radix_tree_exceptional_entry(page)) { |
380 | clear_exceptional_entry(mapping, index, page); | 385 | clear_exceptional_entry(mapping, index, page); |