diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-08-28 17:13:23 -0700 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-10-12 11:54:35 -0700 |
commit | 65ed39d6ca78f07d2958814e08440e4264b6b488 (patch) | |
tree | 477623ef58810a6d32c8d23fbf17e5258495ddb0 /fs/ocfs2/aops.c | |
parent | 92e91ce2a30b2af53ebf077512801dc01e75cca5 (diff) | |
download | lwn-65ed39d6ca78f07d2958814e08440e4264b6b488.tar.gz lwn-65ed39d6ca78f07d2958814e08440e4264b6b488.zip |
ocfs2: move nonsparse hole-filling into ocfs2_write_begin()
By doing this, we can remove any higher level logic which has to have
knowledge of btree functionality - any callers of ocfs2_write_begin() can
now expect it to do anything necessary to prepare the inode for new data.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Reviewed-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index f37f25c931f5..fae07672eb18 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -301,12 +301,8 @@ int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, { int ret; - down_read(&OCFS2_I(inode)->ip_alloc_sem); - ret = block_prepare_write(page, from, to, ocfs2_get_block); - up_read(&OCFS2_I(inode)->ip_alloc_sem); - return ret; } @@ -1360,6 +1356,36 @@ out: return ret; } +/* + * This function only does anything for file systems which can't + * handle sparse files. + * + * What we want to do here is fill in any hole between the current end + * of allocation and the end of our write. That way the rest of the + * write path can treat it as an non-allocating write, which has no + * special case code for sparse/nonsparse files. + */ +static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, + unsigned len, + struct ocfs2_write_ctxt *wc) +{ + int ret; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + loff_t newsize = pos + len; + + if (ocfs2_sparse_alloc(osb)) + return 0; + + if (newsize <= i_size_read(inode)) + return 0; + + ret = ocfs2_extend_no_holes(inode, newsize, newsize - len); + if (ret) + mlog_errno(ret); + + return ret; +} + int ocfs2_write_begin_nolock(struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata, @@ -1381,6 +1407,12 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, return ret; } + ret = ocfs2_expand_nonsparse_inode(inode, pos, len, wc); + if (ret) { + mlog_errno(ret); + goto out; + } + ret = ocfs2_populate_write_desc(inode, wc, &clusters_to_alloc, &extents_to_split); if (ret) { |