|
@@ -376,9 +376,31 @@ out:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * eCryptfs does not currently support holes. When writing after a
|
|
|
|
+ * seek past the end of the file, eCryptfs fills in 0's through to the
|
|
|
|
+ * current location. The code to fill in the 0's to all the
|
|
|
|
+ * intermediate pages calls ecryptfs_prepare_write_no_truncate().
|
|
|
|
+ */
|
|
|
|
+static int
|
|
|
|
+ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page,
|
|
|
|
+ unsigned from, unsigned to)
|
|
|
|
+{
|
|
|
|
+ int rc = 0;
|
|
|
|
+
|
|
|
|
+ if (from == 0 && to == PAGE_CACHE_SIZE)
|
|
|
|
+ goto out; /* If we are writing a full page, it will be
|
|
|
|
+ up to date. */
|
|
|
|
+ if (!PageUptodate(page))
|
|
|
|
+ rc = ecryptfs_do_readpage(file, page, page->index);
|
|
|
|
+out:
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
static int ecryptfs_prepare_write(struct file *file, struct page *page,
|
|
static int ecryptfs_prepare_write(struct file *file, struct page *page,
|
|
unsigned from, unsigned to)
|
|
unsigned from, unsigned to)
|
|
{
|
|
{
|
|
|
|
+ loff_t pos;
|
|
int rc = 0;
|
|
int rc = 0;
|
|
|
|
|
|
if (from == 0 && to == PAGE_CACHE_SIZE)
|
|
if (from == 0 && to == PAGE_CACHE_SIZE)
|
|
@@ -386,6 +408,16 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
|
|
up to date. */
|
|
up to date. */
|
|
if (!PageUptodate(page))
|
|
if (!PageUptodate(page))
|
|
rc = ecryptfs_do_readpage(file, page, page->index);
|
|
rc = ecryptfs_do_readpage(file, page, page->index);
|
|
|
|
+ pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
|
|
|
|
+ if (pos > i_size_read(page->mapping->host)) {
|
|
|
|
+ rc = ecryptfs_truncate(file->f_path.dentry, pos);
|
|
|
|
+ if (rc) {
|
|
|
|
+ printk(KERN_ERR "Error on attempt to "
|
|
|
|
+ "truncate to (higher) offset [%lld];"
|
|
|
|
+ " rc = [%d]\n", pos, rc);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
out:
|
|
out:
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
@@ -744,10 +776,10 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros)
|
|
rc = PTR_ERR(tmp_page);
|
|
rc = PTR_ERR(tmp_page);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
- rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros);
|
|
|
|
- if (rc) {
|
|
|
|
|
|
+ if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start,
|
|
|
|
+ (start + num_zeros)))) {
|
|
ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
|
|
ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
|
|
- "to remainder of page at index [0x%.16x]\n",
|
|
|
|
|
|
+ "to page at index [0x%.16x]\n",
|
|
index);
|
|
index);
|
|
page_cache_release(tmp_page);
|
|
page_cache_release(tmp_page);
|
|
goto out;
|
|
goto out;
|