diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-06-18 14:22:56 -0400 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-07-10 20:32:03 -0400 |
commit | b27b7cbcf12a1bfff1ed68a73ddd7d11edc20daf (patch) | |
tree | a25a8ca272e7f0ef01987db3b3795a49e0ccb51f /fs/ocfs2/file.c | |
parent | 0d172baa5586071ae0ae0c07356a378fdbedecdb (diff) |
ocfs2: support writing of unwritten extents
Update the write code to detect when the user is asking to write to an
unwritten extent. Like writing to a hole, we must zero the region between
the write and the cluster boundaries. Most of the existing cluster zeroing
logic can be re-used with some additional checks for the unwritten flag on
extent records.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index a80f31776d94..6745086da6fd 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -527,20 +527,21 @@ leave: | |||
527 | * understand sparse inodes. | 527 | * understand sparse inodes. |
528 | */ | 528 | */ |
529 | int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di, | 529 | int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di, |
530 | u32 clusters_to_add, | 530 | u32 clusters_to_add, u32 extents_to_split, |
531 | struct ocfs2_alloc_context **data_ac, | 531 | struct ocfs2_alloc_context **data_ac, |
532 | struct ocfs2_alloc_context **meta_ac) | 532 | struct ocfs2_alloc_context **meta_ac) |
533 | { | 533 | { |
534 | int ret, num_free_extents; | 534 | int ret, num_free_extents; |
535 | unsigned int max_recs_needed = clusters_to_add + 2 * extents_to_split; | ||
535 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 536 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
536 | 537 | ||
537 | *meta_ac = NULL; | 538 | *meta_ac = NULL; |
538 | *data_ac = NULL; | 539 | *data_ac = NULL; |
539 | 540 | ||
540 | mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u, " | 541 | mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u, " |
541 | "clusters_to_add = %u\n", | 542 | "clusters_to_add = %u, extents_to_split = %u\n", |
542 | (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), | 543 | (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), |
543 | le32_to_cpu(di->i_clusters), clusters_to_add); | 544 | le32_to_cpu(di->i_clusters), clusters_to_add, extents_to_split); |
544 | 545 | ||
545 | num_free_extents = ocfs2_num_free_extents(osb, inode, di); | 546 | num_free_extents = ocfs2_num_free_extents(osb, inode, di); |
546 | if (num_free_extents < 0) { | 547 | if (num_free_extents < 0) { |
@@ -558,9 +559,12 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di, | |||
558 | * | 559 | * |
559 | * Most of the time we'll only be seeing this 1 cluster at a time | 560 | * Most of the time we'll only be seeing this 1 cluster at a time |
560 | * anyway. | 561 | * anyway. |
562 | * | ||
563 | * Always lock for any unwritten extents - we might want to | ||
564 | * add blocks during a split. | ||
561 | */ | 565 | */ |
562 | if (!num_free_extents || | 566 | if (!num_free_extents || |
563 | (ocfs2_sparse_alloc(osb) && num_free_extents < clusters_to_add)) { | 567 | (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) { |
564 | ret = ocfs2_reserve_new_metadata(osb, di, meta_ac); | 568 | ret = ocfs2_reserve_new_metadata(osb, di, meta_ac); |
565 | if (ret < 0) { | 569 | if (ret < 0) { |
566 | if (ret != -ENOSPC) | 570 | if (ret != -ENOSPC) |
@@ -641,7 +645,7 @@ restart_all: | |||
641 | down_write(&OCFS2_I(inode)->ip_alloc_sem); | 645 | down_write(&OCFS2_I(inode)->ip_alloc_sem); |
642 | drop_alloc_sem = 1; | 646 | drop_alloc_sem = 1; |
643 | 647 | ||
644 | status = ocfs2_lock_allocators(inode, fe, clusters_to_add, &data_ac, | 648 | status = ocfs2_lock_allocators(inode, fe, clusters_to_add, 0, &data_ac, |
645 | &meta_ac); | 649 | &meta_ac); |
646 | if (status) { | 650 | if (status) { |
647 | mlog_errno(status); | 651 | mlog_errno(status); |