Skip to content

Commit 1bfad99

Browse files
mjkravetztorvalds
authored andcommitted
hugetlbfs: hugetlb_vmtruncate_list() needs to take a range to delete
fallocate hole punch will want to unmap a specific range of pages. Modify the existing hugetlb_vmtruncate_list() routine to take a start/end range. If end is 0, this indicates all pages after start should be unmapped. This is the same as the existing truncate functionality. Modify existing callers to add 0 as end of range. Since the routine will be used in hole punch as well as truncate operations, it is more appropriately renamed to hugetlb_vmdelete_list(). Signed-off-by: Mike Kravetz <[email protected]> Reviewed-by: Naoya Horiguchi <[email protected]> Acked-by: Hillf Danton <[email protected]> Cc: Dave Hansen <[email protected]> Cc: David Rientjes <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: Aneesh Kumar <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Michal Hocko <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c672c7f commit 1bfad99

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

fs/hugetlbfs/inode.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,15 @@ static void hugetlbfs_evict_inode(struct inode *inode)
349349
}
350350

351351
static inline void
352-
hugetlb_vmtruncate_list(struct rb_root *root, pgoff_t pgoff)
352+
hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end)
353353
{
354354
struct vm_area_struct *vma;
355355

356-
vma_interval_tree_foreach(vma, root, pgoff, ULONG_MAX) {
356+
/*
357+
* end == 0 indicates that the entire range after
358+
* start should be unmapped.
359+
*/
360+
vma_interval_tree_foreach(vma, root, start, end ? end : ULONG_MAX) {
357361
unsigned long v_offset;
358362

359363
/*
@@ -362,13 +366,20 @@ hugetlb_vmtruncate_list(struct rb_root *root, pgoff_t pgoff)
362366
* which overlap the truncated area starting at pgoff,
363367
* and no vma on a 32-bit arch can span beyond the 4GB.
364368
*/
365-
if (vma->vm_pgoff < pgoff)
366-
v_offset = (pgoff - vma->vm_pgoff) << PAGE_SHIFT;
369+
if (vma->vm_pgoff < start)
370+
v_offset = (start - vma->vm_pgoff) << PAGE_SHIFT;
367371
else
368372
v_offset = 0;
369373

370-
unmap_hugepage_range(vma, vma->vm_start + v_offset,
371-
vma->vm_end, NULL);
374+
if (end) {
375+
end = ((end - start) << PAGE_SHIFT) +
376+
vma->vm_start + v_offset;
377+
if (end > vma->vm_end)
378+
end = vma->vm_end;
379+
} else
380+
end = vma->vm_end;
381+
382+
unmap_hugepage_range(vma, vma->vm_start + v_offset, end, NULL);
372383
}
373384
}
374385

@@ -384,7 +395,7 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
384395
i_size_write(inode, offset);
385396
i_mmap_lock_write(mapping);
386397
if (!RB_EMPTY_ROOT(&mapping->i_mmap))
387-
hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
398+
hugetlb_vmdelete_list(&mapping->i_mmap, pgoff, 0);
388399
i_mmap_unlock_write(mapping);
389400
truncate_hugepages(inode, offset);
390401
return 0;

0 commit comments

Comments
 (0)