diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-03-09 19:21:46 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-04-26 18:02:41 -0400 |
commit | 49cb8d2d496ce06869ccca2ab368ed6b0b5b979d (patch) | |
tree | 7aded7178e87dc26eb2ceafb169d7e68a8ee5ded /fs/ocfs2/aops.c | |
parent | e48edee2d8eab812f31f0ff62c6ba635ca2e1e21 (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.c | 21 |
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; |