tmpfs: take control of its truncate_range
[sfrench/cifs-2.6.git] / mm / truncate.c
index 3a29a6180212d7bcf25ab0d6fd97acdb16fc8f42..29a9b8a5a31a800e874e3a2622e25321a84d37af 100644 (file)
@@ -603,3 +603,27 @@ int vmtruncate(struct inode *inode, loff_t offset)
        return 0;
 }
 EXPORT_SYMBOL(vmtruncate);
+
+int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end)
+{
+       struct address_space *mapping = inode->i_mapping;
+
+       /*
+        * If the underlying filesystem is not going to provide
+        * a way to truncate a range of blocks (punch a hole) -
+        * we should return failure right now.
+        */
+       if (!inode->i_op->truncate_range)
+               return -ENOSYS;
+
+       mutex_lock(&inode->i_mutex);
+       down_write(&inode->i_alloc_sem);
+       unmap_mapping_range(mapping, offset, (end - offset), 1);
+       inode->i_op->truncate_range(inode, offset, end);
+       /* unmap again to remove racily COWed private pages */
+       unmap_mapping_range(mapping, offset, (end - offset), 1);
+       up_write(&inode->i_alloc_sem);
+       mutex_unlock(&inode->i_mutex);
+
+       return 0;
+}