diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-01-16 14:32:23 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-04-26 17:44:03 -0400 |
commit | dcd0538ff4e854fa9d7f4630b359ca8fdb5cb5a8 (patch) | |
tree | 226d725f8199907cea2433d1d183b01e51d9bc55 /fs/ocfs2/file.c | |
parent | 6f16bf655c5795586dd2ac96a7c70e0b9a378746 (diff) |
ocfs2: sparse b-tree support
Introduce tree rotations into the b-tree code. This will allow ocfs2 to
support sparse files. Much of the added code is designed to be generic (in
the ocfs2 sense) so that it can later be re-used to implement large
extended attributes.
This patch only adds the rotation code and does minimal updates to callers
of the extent api.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 25e36fbd7bc3..8c97fa1c45f6 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -397,6 +397,7 @@ bail: | |||
397 | */ | 397 | */ |
398 | int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | 398 | int ocfs2_do_extend_allocation(struct ocfs2_super *osb, |
399 | struct inode *inode, | 399 | struct inode *inode, |
400 | u32 *logical_offset, | ||
400 | u32 clusters_to_add, | 401 | u32 clusters_to_add, |
401 | struct buffer_head *fe_bh, | 402 | struct buffer_head *fe_bh, |
402 | handle_t *handle, | 403 | handle_t *handle, |
@@ -460,18 +461,14 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
460 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); | 461 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); |
461 | mlog(0, "Allocating %u clusters at block %u for inode %llu\n", | 462 | mlog(0, "Allocating %u clusters at block %u for inode %llu\n", |
462 | num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); | 463 | num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); |
463 | status = ocfs2_insert_extent(osb, handle, inode, fe_bh, block, | 464 | status = ocfs2_insert_extent(osb, handle, inode, fe_bh, |
464 | num_bits, meta_ac); | 465 | *logical_offset, block, num_bits, |
466 | meta_ac); | ||
465 | if (status < 0) { | 467 | if (status < 0) { |
466 | mlog_errno(status); | 468 | mlog_errno(status); |
467 | goto leave; | 469 | goto leave; |
468 | } | 470 | } |
469 | 471 | ||
470 | le32_add_cpu(&fe->i_clusters, num_bits); | ||
471 | spin_lock(&OCFS2_I(inode)->ip_lock); | ||
472 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); | ||
473 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
474 | |||
475 | status = ocfs2_journal_dirty(handle, fe_bh); | 472 | status = ocfs2_journal_dirty(handle, fe_bh); |
476 | if (status < 0) { | 473 | if (status < 0) { |
477 | mlog_errno(status); | 474 | mlog_errno(status); |
@@ -479,6 +476,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
479 | } | 476 | } |
480 | 477 | ||
481 | clusters_to_add -= num_bits; | 478 | clusters_to_add -= num_bits; |
479 | *logical_offset += num_bits; | ||
482 | 480 | ||
483 | if (clusters_to_add) { | 481 | if (clusters_to_add) { |
484 | mlog(0, "need to alloc once more, clusters = %u, wanted = " | 482 | mlog(0, "need to alloc once more, clusters = %u, wanted = " |
@@ -501,7 +499,7 @@ static int ocfs2_extend_allocation(struct inode *inode, | |||
501 | int restart_func = 0; | 499 | int restart_func = 0; |
502 | int drop_alloc_sem = 0; | 500 | int drop_alloc_sem = 0; |
503 | int credits, num_free_extents; | 501 | int credits, num_free_extents; |
504 | u32 prev_clusters; | 502 | u32 prev_clusters, logical_start; |
505 | struct buffer_head *bh = NULL; | 503 | struct buffer_head *bh = NULL; |
506 | struct ocfs2_dinode *fe = NULL; | 504 | struct ocfs2_dinode *fe = NULL; |
507 | handle_t *handle = NULL; | 505 | handle_t *handle = NULL; |
@@ -512,6 +510,12 @@ static int ocfs2_extend_allocation(struct inode *inode, | |||
512 | 510 | ||
513 | mlog_entry("(clusters_to_add = %u)\n", clusters_to_add); | 511 | mlog_entry("(clusters_to_add = %u)\n", clusters_to_add); |
514 | 512 | ||
513 | /* | ||
514 | * This function only exists for file systems which don't | ||
515 | * support holes. | ||
516 | */ | ||
517 | BUG_ON(ocfs2_sparse_alloc(osb)); | ||
518 | |||
515 | status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &bh, | 519 | status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &bh, |
516 | OCFS2_BH_CACHED, inode); | 520 | OCFS2_BH_CACHED, inode); |
517 | if (status < 0) { | 521 | if (status < 0) { |
@@ -526,6 +530,8 @@ static int ocfs2_extend_allocation(struct inode *inode, | |||
526 | goto leave; | 530 | goto leave; |
527 | } | 531 | } |
528 | 532 | ||
533 | logical_start = OCFS2_I(inode)->ip_clusters; | ||
534 | |||
529 | restart_all: | 535 | restart_all: |
530 | BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters); | 536 | BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters); |
531 | 537 | ||
@@ -590,6 +596,7 @@ restarted_transaction: | |||
590 | 596 | ||
591 | status = ocfs2_do_extend_allocation(osb, | 597 | status = ocfs2_do_extend_allocation(osb, |
592 | inode, | 598 | inode, |
599 | &logical_start, | ||
593 | clusters_to_add, | 600 | clusters_to_add, |
594 | bh, | 601 | bh, |
595 | handle, | 602 | handle, |