-static
-int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros);
-
-/**
- * ecryptfs_fill_zeros
- * @file: The ecryptfs file
- * @new_length: The new length of the data in the underlying file;
- * everything between the prior end of the file and the
- * new end of the file will be filled with zero's.
- * new_length must be greater than current length
- *
- * Function for handling lseek-ing past the end of the file.
- *
- * This function does not support shrinking, only growing a file.
- *
- * Returns zero on success; non-zero otherwise.
- */
-int ecryptfs_fill_zeros(struct file *file, loff_t new_length)
-{
- int rc = 0;
- struct dentry *dentry = file->f_path.dentry;
- struct inode *inode = dentry->d_inode;
- pgoff_t old_end_page_index = 0;
- pgoff_t index = old_end_page_index;
- int old_end_pos_in_page = -1;
- pgoff_t new_end_page_index;
- int new_end_pos_in_page;
- loff_t cur_length = i_size_read(inode);
-
- if (cur_length != 0) {
- index = old_end_page_index =
- ((cur_length - 1) >> PAGE_CACHE_SHIFT);
- old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK);
- }
- new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
- new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
- ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; "
- "old_end_pos_in_page = [%d]; "
- "new_end_page_index = [0x%.16x]; "
- "new_end_pos_in_page = [%d]\n",
- old_end_page_index, old_end_pos_in_page,
- new_end_page_index, new_end_pos_in_page);
- if (old_end_page_index == new_end_page_index) {
- /* Start and end are in the same page; we just need to
- * set a portion of the existing page to zero's */
- rc = write_zeros(file, index, (old_end_pos_in_page + 1),
- (new_end_pos_in_page - old_end_pos_in_page));
- if (rc)
- ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
- "index=[0x%.16x], "
- "old_end_pos_in_page=[d], "
- "(PAGE_CACHE_SIZE - new_end_pos_in_page"
- "=[%d]"
- ")=[d]) returned [%d]\n", file, index,
- old_end_pos_in_page,
- new_end_pos_in_page,
- (PAGE_CACHE_SIZE - new_end_pos_in_page),
- rc);
- goto out;
- }
- /* Fill the remainder of the previous last page with zeros */
- rc = write_zeros(file, index, (old_end_pos_in_page + 1),
- ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page));
- if (rc) {
- ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
- "index=[0x%.16x], old_end_pos_in_page=[d], "
- "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) "
- "returned [%d]\n", file, index,
- old_end_pos_in_page,
- (PAGE_CACHE_SIZE - old_end_pos_in_page), rc);
- goto out;
- }
- index++;
- while (index < new_end_page_index) {
- /* Fill all intermediate pages with zeros */
- rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
- "index=[0x%.16x], "
- "old_end_pos_in_page=[d], "
- "(PAGE_CACHE_SIZE - new_end_pos_in_page"
- "=[%d]"
- ")=[d]) returned [%d]\n", file, index,
- old_end_pos_in_page,
- new_end_pos_in_page,
- (PAGE_CACHE_SIZE - new_end_pos_in_page),
- rc);
- goto out;
- }
- index++;
- }
- /* Fill the portion at the beginning of the last new page with
- * zero's */
- rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1));
- if (rc) {
- ecryptfs_printk(KERN_ERR, "write_zeros(file="
- "[%p], index=[0x%.16x], 0, "
- "new_end_pos_in_page=[%d]"
- "returned [%d]\n", file, index,
- new_end_pos_in_page, rc);
- goto out;
- }
-out:
- return rc;
-}
-