Fix write_end_cryptcompress(): update i_size, if pos + count > old i_size. Signed-off-by: Edward Shishkin --- fs/reiser4/plugin/file/cryptcompress.c | 47 +++++++++++++++++++++++-------- fs/reiser4/plugin/file/file.c | 2 - fs/reiser4/plugin/file/file.h | 4 +- fs/reiser4/plugin/file/file_conversion.c | 6 --- fs/reiser4/plugin/plugin.h | 2 - 5 files changed, 41 insertions(+), 20 deletions(-) --- linux-2.6.35.orig/fs/reiser4/plugin/file/cryptcompress.c +++ linux-2.6.35/fs/reiser4/plugin/file/cryptcompress.c @@ -3749,13 +3749,14 @@ int write_begin_cryptcompress(struct fil /* plugin->commit_write */ int write_end_cryptcompress(struct file *file, struct page *page, - unsigned from, unsigned to) + loff_t pos, unsigned copied) { - int ret; + int ret = 0; hint_t *hint; lock_handle *lh; struct inode * inode; struct cluster_handle clust; + struct reiser4_slide *win = NULL; unlock_page(page); @@ -3769,17 +3770,41 @@ int write_end_cryptcompress(struct file cluster_init_read(&clust, NULL); clust.hint = hint; - ret = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); - if (ret) - goto out; - clust.index = pg_to_clust(page->index, inode); - ret = capture_page_cluster(&clust, inode); - if (ret) - warning("edward-1557", - "Capture failed (inode %llu, result=%i)", - (unsigned long long)get_inode_oid(inode), ret); + if (pos + copied > inode->i_size) { + win = kmalloc(sizeof(*win), reiser4_ctx_gfp_mask_get()); + if (win == NULL) + goto out; + /* make sure there is no holes */ + assert("edward-xxx", pos <= inode->i_size); + ret = set_cluster_by_window(inode, &clust, win, copied, pos); + if (ret) + goto out; + ret = capture_page_cluster(&clust, inode); + if (ret) { + warning("edward-xxx", + "Capture failed (inode %llu, result=%i)", + (unsigned long long)get_inode_oid(inode), ret); + goto out; + } + /* FIXME-EDWARD: + reserve space for update_sd in write_begin() */ + ret = update_sd_cryptcompress(inode); + } + else { + ret = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); + if (ret) + goto out; + clust.index = pg_to_clust(page->index, inode); + ret = capture_page_cluster(&clust, inode); + if (ret) + warning("edward-1557", + "Capture failed (inode %llu, result=%i)", + (unsigned long long)get_inode_oid(inode), ret); + } out: done_lh(lh); + if (win) + kfree(win); kfree(hint); put_cluster_handle(&clust); return ret; --- linux-2.6.35.orig/fs/reiser4/plugin/file/file.c +++ linux-2.6.35/fs/reiser4/plugin/file/file.c @@ -893,7 +893,7 @@ static int capture_page_and_create_exten /* plugin->write_end() */ int write_end_unix_file(struct file *file, struct page *page, - unsigned from, unsigned to) + loff_t pos, unsigned copied) { unlock_page(page); return capture_page_and_create_extent(page); --- linux-2.6.35.orig/fs/reiser4/plugin/file/file.h +++ linux-2.6.35/fs/reiser4/plugin/file/file.h @@ -97,7 +97,7 @@ int writepages_unix_file(struct address_ int write_begin_unix_file(struct file *file, struct page *page, unsigned from, unsigned to); int write_end_unix_file(struct file *file, struct page *page, - unsigned from, unsigned to); + loff_t pos, unsigned copied); sector_t bmap_unix_file(struct address_space *, sector_t lblock); /* other private methods */ @@ -137,7 +137,7 @@ int writepages_cryptcompress(struct addr int write_begin_cryptcompress(struct file *file, struct page *page, unsigned from, unsigned to); int write_end_cryptcompress(struct file *file, struct page *page, - unsigned from, unsigned to); + loff_t pos, unsigned copied); sector_t bmap_cryptcompress(struct address_space *, sector_t lblock); /* other private methods */ --- linux-2.6.35.orig/fs/reiser4/plugin/file/file_conversion.c +++ linux-2.6.35/fs/reiser4/plugin/file/file_conversion.c @@ -694,16 +694,12 @@ int reiser4_write_end_careful(struct fil { int ret; reiser4_context *ctx; - unsigned start, end; struct inode *inode = page->mapping->host; assert("umka-3101", file != NULL); assert("umka-3102", page != NULL); assert("umka-3093", PageLocked(page)); - start = pos & (PAGE_CACHE_SIZE - 1); - end = start + len; - flush_dcache_page(page); SetPageUptodate(page); @@ -713,7 +709,7 @@ int reiser4_write_end_careful(struct fil ret = PTR_ERR(ctx); goto out; } - ret = PROT_PASSIVE(int, write_end, (file, page, start, end)); + ret = PROT_PASSIVE(int, write_end, (file, page, pos, copied)); /* don't commit transaction under inode semaphore */ context_set_commit_async(ctx); --- linux-2.6.35.orig/fs/reiser4/plugin/plugin.h +++ linux-2.6.35/fs/reiser4/plugin/plugin.h @@ -251,7 +251,7 @@ typedef struct file_plugin { int (*write_begin)(struct file *file, struct page *page, unsigned from, unsigned to); int (*write_end)(struct file *file, struct page *page, - unsigned from, unsigned to); + loff_t pos, unsigned copied); sector_t (*bmap) (struct address_space * mapping, sector_t lblock); /* other private methods */ /* save inode cached stat-data onto disk. It was called