diff options
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; |