aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-02-14 18:30:30 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-04-26 18:02:16 -0400
commit25baf2da1473d9dcde1a4c7b0ab26e7d67d9bf62 (patch)
tree7e07eb6de18f07d4814ab75a02c1c6837fd3e3ea /fs/ocfs2/aops.c
parent5069120b7227fd323152a3755a0aa6bdeb361310 (diff)
ocfs2: Teach ocfs2_get_block() about holes
ocfs2_get_block() didn't understand sparse files, fix that. Also remove some code that isn't really useful anymore. We can fix up ocfs2_direct_IO_get_blocks() at the same time. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c99
1 files changed, 61 insertions, 38 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 8368036f434a..acf8f0006725 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{ 137{
138 int err = 0; 138 int err = 0;
139 u64 p_blkno, past_eof; 139 u64 p_blkno, past_eof;
140 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
140 141
141 mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode, 142 mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode,
142 (unsigned long long)iblock, bh_result, create); 143 (unsigned long long)iblock, bh_result, create);
@@ -151,15 +152,6 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
151 goto bail; 152 goto bail;
152 } 153 }
153 154
154 /* this can happen if another node truncs after our extend! */
155 spin_lock(&OCFS2_I(inode)->ip_lock);
156 if (iblock >= ocfs2_clusters_to_blocks(inode->i_sb,
157 OCFS2_I(inode)->ip_clusters))
158 err = -EIO;
159 spin_unlock(&OCFS2_I(inode)->ip_lock);
160 if (err)
161 goto bail;
162
163 err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL); 155 err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL);
164 if (err) { 156 if (err) {
165 mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, " 157 mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, "
@@ -168,22 +160,38 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
168 goto bail; 160 goto bail;
169 } 161 }
170 162
171 map_bh(bh_result, inode->i_sb, p_blkno); 163 /*
172 164 * ocfs2 never allocates in this function - the only time we
173 if (bh_result->b_blocknr == 0) { 165 * need to use BH_New is when we're extending i_size on a file
174 err = -EIO; 166 * system which doesn't support holes, in which case BH_New
175 mlog(ML_ERROR, "iblock = %llu p_blkno = %llu blkno=(%llu)\n", 167 * allows block_prepare_write() to zero.
176 (unsigned long long)iblock, 168 */
177 (unsigned long long)p_blkno, 169 mlog_bug_on_msg(create && p_blkno == 0 && ocfs2_sparse_alloc(osb),
178 (unsigned long long)OCFS2_I(inode)->ip_blkno); 170 "ino %lu, iblock %llu\n", inode->i_ino,
179 } 171 (unsigned long long)iblock);
172
173 if (p_blkno)
174 map_bh(bh_result, inode->i_sb, p_blkno);
175
176 if (!ocfs2_sparse_alloc(osb)) {
177 if (p_blkno == 0) {
178 err = -EIO;
179 mlog(ML_ERROR,
180 "iblock = %llu p_blkno = %llu blkno=(%llu)\n",
181 (unsigned long long)iblock,
182 (unsigned long long)p_blkno,
183 (unsigned long long)OCFS2_I(inode)->ip_blkno);
184 mlog(ML_ERROR, "Size %llu, clusters %u\n", (unsigned long long)i_size_read(inode), OCFS2_I(inode)->ip_clusters);
185 dump_stack();
186 }
180 187
181 past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode)); 188 past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
182 mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino, 189 mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino,
183 (unsigned long long)past_eof); 190 (unsigned long long)past_eof);
184 191
185 if (create && (iblock >= past_eof)) 192 if (create && (iblock >= past_eof))
186 set_buffer_new(bh_result); 193 set_buffer_new(bh_result);
194 }
187 195
188bail: 196bail:
189 if (err < 0) 197 if (err < 0)
@@ -436,28 +444,15 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
436 * nicely aligned and of the right size, so there's no need 444 * nicely aligned and of the right size, so there's no need
437 * for us to check any of that. */ 445 * for us to check any of that. */
438 446
439 spin_lock(&OCFS2_I(inode)->ip_lock); 447 inode_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
440 inode_blocks = ocfs2_clusters_to_blocks(inode->i_sb,
441 OCFS2_I(inode)->ip_clusters);
442
443 /*
444 * For a read which begins past the end of file, we return a hole.
445 */
446 if (!create && (iblock >= inode_blocks)) {
447 spin_unlock(&OCFS2_I(inode)->ip_lock);
448 ret = 0;
449 goto bail;
450 }
451 448
452 /* 449 /*
453 * Any write past EOF is not allowed because we'd be extending. 450 * Any write past EOF is not allowed because we'd be extending.
454 */ 451 */
455 if (create && (iblock + max_blocks) > inode_blocks) { 452 if (create && (iblock + max_blocks) > inode_blocks) {
456 spin_unlock(&OCFS2_I(inode)->ip_lock);
457 ret = -EIO; 453 ret = -EIO;
458 goto bail; 454 goto bail;
459 } 455 }
460 spin_unlock(&OCFS2_I(inode)->ip_lock);
461 456
462 /* This figures out the size of the next contiguous block, and 457 /* This figures out the size of the next contiguous block, and
463 * our logical offset */ 458 * our logical offset */
@@ -470,7 +465,35 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
470 goto bail; 465 goto bail;
471 } 466 }
472 467
473 map_bh(bh_result, inode->i_sb, p_blkno); 468 if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)) && !p_blkno) {
469 ocfs2_error(inode->i_sb,
470 "Inode %llu has a hole at block %llu\n",
471 (unsigned long long)OCFS2_I(inode)->ip_blkno,
472 (unsigned long long)iblock);
473 ret = -EROFS;
474 goto bail;
475 }
476
477 /*
478 * get_more_blocks() expects us to describe a hole by clearing
479 * the mapped bit on bh_result().
480 */
481 if (p_blkno)
482 map_bh(bh_result, inode->i_sb, p_blkno);
483 else {
484 /*
485 * ocfs2_prepare_inode_for_write() should have caught
486 * the case where we'd be filling a hole and triggered
487 * a buffered write instead.
488 */
489 if (create) {
490 ret = -EIO;
491 mlog_errno(ret);
492 goto bail;
493 }
494
495 clear_buffer_mapped(bh_result);
496 }
474 497
475 /* make sure we don't map more than max_blocks blocks here as 498 /* make sure we don't map more than max_blocks blocks here as
476 that's all the kernel will handle at this point. */ 499 that's all the kernel will handle at this point. */