summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-02-16 20:46:50 +0100
committerMark Fasheh <mark.fasheh@oracle.com>2007-04-27 00:02:20 +0200
commit60b11392f1a09433740bda3048202213daa27736 (patch)
treea8687fcb0ce62b130b732d663b54a984564d28b2 /fs/ocfs2/aops.c
parentocfs2: Teach ocfs2_get_block() about holes (diff)
downloadlinux-60b11392f1a09433740bda3048202213daa27736.tar.xz
linux-60b11392f1a09433740bda3048202213daa27736.zip
ocfs2: zero tail of sparse files on truncate
Since we don't zero on extend anymore, truncate needs to be fixed up to zero the part of a file between i_size and and end of it's cluster. Otherwise a subsequent extend could expose bad data. This introduced a new helper, which can be used in ocfs2_write(). Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index acf8f0006725..605c82a93f01 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -308,13 +308,13 @@ int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page,
* functionality yet, but IMHO it's better to cut and paste the whole
* thing so we can avoid introducing our own bugs (and easily pick up
* their fixes when they happen) --Mark */
-static int walk_page_buffers( handle_t *handle,
- struct buffer_head *head,
- unsigned from,
- unsigned to,
- int *partial,
- int (*fn)( handle_t *handle,
- struct buffer_head *bh))
+int walk_page_buffers( handle_t *handle,
+ struct buffer_head *head,
+ unsigned from,
+ unsigned to,
+ int *partial,
+ int (*fn)( handle_t *handle,
+ struct buffer_head *bh))
{
struct buffer_head *bh;
unsigned block_start, block_end;
@@ -654,9 +654,9 @@ static void ocfs2_clear_page_regions(struct page *page,
*
* This will also skip zeroing, which is handled externally.
*/
-static int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
- struct inode *inode, unsigned int from,
- unsigned int to, int new)
+int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
+ struct inode *inode, unsigned int from,
+ unsigned int to, int new)
{
int ret = 0;
struct buffer_head *head, *bh, *wait[2], **wait_bh = wait;
@@ -675,8 +675,7 @@ static int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
* Ignore blocks outside of our i/o range -
* they may belong to unallocated clusters.
*/
- if (block_start >= to ||
- (block_start + bsize) <= from) {
+ if (block_start >= to || block_end <= from) {
if (PageUptodate(page))
set_buffer_uptodate(bh);
continue;
@@ -971,7 +970,6 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle,
u64 v_blkno, p_blkno;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
- unsigned int cbits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
unsigned long index, start;
struct page **cpages;
@@ -979,13 +977,11 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle,
/*
* Figure out how many pages we'll be manipulating here. For
- * non-allocating write, or any writes where cluster size is
- * less than page size, we only need one page. Otherwise,
- * allocating writes of cluster size larger than page size
- * need cluster size pages.
+ * non allocating write, we just change the one
+ * page. Otherwise, we'll need a whole clusters worth.
*/
- if (new && !wc->w_large_pages)
- numpages = (1 << cbits) / PAGE_SIZE;
+ if (new)
+ numpages = ocfs2_pages_per_cluster(inode->i_sb);
cpages = kzalloc(sizeof(*cpages) * numpages, GFP_NOFS);
if (!cpages) {