aboutsummaryrefslogtreecommitdiffstats
path: root/mm/truncate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/truncate.c')
-rw-r--r--mm/truncate.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/mm/truncate.c b/mm/truncate.c
index 3a29a6180212..5b4c3a4847e9 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -603,3 +603,27 @@ int vmtruncate(struct inode *inode, loff_t offset)
603 return 0; 603 return 0;
604} 604}
605EXPORT_SYMBOL(vmtruncate); 605EXPORT_SYMBOL(vmtruncate);
606
607int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end)
608{
609 struct address_space *mapping = inode->i_mapping;
610
611 /*
612 * If the underlying filesystem is not going to provide
613 * a way to truncate a range of blocks (punch a hole) -
614 * we should return failure right now.
615 */
616 if (!inode->i_op->truncate_range)
617 return -ENOSYS;
618
619 mutex_lock(&inode->i_mutex);
620 down_write(&inode->i_alloc_sem);
621 unmap_mapping_range(mapping, offset, (end - offset), 1);
622 truncate_inode_pages_range(mapping, offset, end);
623 unmap_mapping_range(mapping, offset, (end - offset), 1);
624 inode->i_op->truncate_range(inode, offset, end);
625 up_write(&inode->i_alloc_sem);
626 mutex_unlock(&inode->i_mutex);
627
628 return 0;
629}