aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-03-09 19:21:46 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-04-26 18:02:41 -0400
commit49cb8d2d496ce06869ccca2ab368ed6b0b5b979d (patch)
tree7aded7178e87dc26eb2ceafb169d7e68a8ee5ded /fs/ocfs2/aops.c
parente48edee2d8eab812f31f0ff62c6ba635ca2e1e21 (diff)
ocfs2: Read from an unwritten extent returns zeros
Return an optional extent flags field from our lookup functions and wire up callers to treat unwritten regions as holes for the purpose of returning zeros to the user. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 014f4f52809c..eb67c902b002 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -137,6 +137,7 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
137 struct buffer_head *bh_result, int create) 137 struct buffer_head *bh_result, int create)
138{ 138{
139 int err = 0; 139 int err = 0;
140 unsigned int ext_flags;
140 u64 p_blkno, past_eof; 141 u64 p_blkno, past_eof;
141 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 142 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
142 143
@@ -153,7 +154,8 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
153 goto bail; 154 goto bail;
154 } 155 }
155 156
156 err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL); 157 err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL,
158 &ext_flags);
157 if (err) { 159 if (err) {
158 mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, " 160 mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, "
159 "%llu, NULL)\n", err, inode, (unsigned long long)iblock, 161 "%llu, NULL)\n", err, inode, (unsigned long long)iblock,
@@ -171,7 +173,8 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
171 "ino %lu, iblock %llu\n", inode->i_ino, 173 "ino %lu, iblock %llu\n", inode->i_ino,
172 (unsigned long long)iblock); 174 (unsigned long long)iblock);
173 175
174 if (p_blkno) 176 /* Treat the unwritten extent as a hole for zeroing purposes. */
177 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
175 map_bh(bh_result, inode->i_sb, p_blkno); 178 map_bh(bh_result, inode->i_sb, p_blkno);
176 179
177 if (!ocfs2_sparse_alloc(osb)) { 180 if (!ocfs2_sparse_alloc(osb)) {
@@ -396,7 +399,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
396 down_read(&OCFS2_I(inode)->ip_alloc_sem); 399 down_read(&OCFS2_I(inode)->ip_alloc_sem);
397 } 400 }
398 401
399 err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL); 402 err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, NULL);
400 403
401 if (!INODE_JOURNAL(inode)) { 404 if (!INODE_JOURNAL(inode)) {
402 up_read(&OCFS2_I(inode)->ip_alloc_sem); 405 up_read(&OCFS2_I(inode)->ip_alloc_sem);
@@ -438,6 +441,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
438 int ret; 441 int ret;
439 u64 p_blkno, inode_blocks; 442 u64 p_blkno, inode_blocks;
440 int contig_blocks; 443 int contig_blocks;
444 unsigned int ext_flags;
441 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; 445 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
442 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; 446 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
443 447
@@ -458,7 +462,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
458 /* This figures out the size of the next contiguous block, and 462 /* This figures out the size of the next contiguous block, and
459 * our logical offset */ 463 * our logical offset */
460 ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, 464 ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno,
461 &contig_blocks); 465 &contig_blocks, &ext_flags);
462 if (ret) { 466 if (ret) {
463 mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n", 467 mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n",
464 (unsigned long long)iblock); 468 (unsigned long long)iblock);
@@ -478,8 +482,10 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
478 /* 482 /*
479 * get_more_blocks() expects us to describe a hole by clearing 483 * get_more_blocks() expects us to describe a hole by clearing
480 * the mapped bit on bh_result(). 484 * the mapped bit on bh_result().
485 *
486 * Consider an unwritten extent as a hole.
481 */ 487 */
482 if (p_blkno) 488 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
483 map_bh(bh_result, inode->i_sb, p_blkno); 489 map_bh(bh_result, inode->i_sb, p_blkno);
484 else { 490 else {
485 /* 491 /*
@@ -1111,7 +1117,8 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle,
1111 } 1117 }
1112 } 1118 }
1113 1119
1114 ret = ocfs2_extent_map_get_blocks(inode, v_blkno, &p_blkno, NULL); 1120 ret = ocfs2_extent_map_get_blocks(inode, v_blkno, &p_blkno, NULL,
1121 NULL);
1115 if (ret < 0) { 1122 if (ret < 0) {
1116 1123
1117 /* 1124 /*
@@ -1215,7 +1222,7 @@ ssize_t ocfs2_buffered_write_cluster(struct file *file, loff_t pos,
1215 */ 1222 */
1216 down_write(&OCFS2_I(inode)->ip_alloc_sem); 1223 down_write(&OCFS2_I(inode)->ip_alloc_sem);
1217 1224
1218 ret = ocfs2_get_clusters(inode, wc.w_cpos, &phys, NULL); 1225 ret = ocfs2_get_clusters(inode, wc.w_cpos, &phys, NULL, NULL);
1219 if (ret) { 1226 if (ret) {
1220 mlog_errno(ret); 1227 mlog_errno(ret);
1221 goto out_meta; 1228 goto out_meta;