diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-05-09 13:40:18 -0700 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-07-10 17:19:57 -0700 |
commit | 2e89b2e48e1da09ed483f195968c9172aa95b5e2 (patch) | |
tree | 3e81f49c13134ebcbf4572474ad47b65e5ecffba /fs/ocfs2/file.c | |
parent | baf4661a8225d3a39622b795a8db0e6aa845c1ec (diff) | |
download | op-kernel-dev-2e89b2e48e1da09ed483f195968c9172aa95b5e2.zip op-kernel-dev-2e89b2e48e1da09ed483f195968c9172aa95b5e2.tar.gz |
ocfs2: take ip_alloc_sem during entire truncate
Use of the alloc sem during truncate was too narrow - we want to protect
the i_size change and page truncation against mmap now.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 4979b66..566f9b7 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -326,9 +326,6 @@ static int ocfs2_truncate_file(struct inode *inode, (unsigned long long)OCFS2_I(inode)->ip_blkno, (unsigned long long)new_i_size); - unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); - truncate_inode_pages(inode->i_mapping, new_i_size); - fe = (struct ocfs2_dinode *) di_bh->b_data; if (!OCFS2_IS_VALID_DINODE(fe)) { OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe); @@ -363,16 +360,23 @@ static int ocfs2_truncate_file(struct inode *inode, if (new_i_size == le64_to_cpu(fe->i_size)) goto bail; + down_write(&OCFS2_I(inode)->ip_alloc_sem); + /* This forces other nodes to sync and drop their pages. Do * this even if we have a truncate without allocation change - * ocfs2 cluster sizes can be much greater than page size, so * we have to truncate them anyway. */ status = ocfs2_data_lock(inode, 1); if (status < 0) { + up_write(&OCFS2_I(inode)->ip_alloc_sem); + mlog_errno(status); goto bail; } + unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); + truncate_inode_pages(inode->i_mapping, new_i_size); + /* alright, we're going to need to do a full blown alloc size * change. Orphan the inode so that recovery can complete the * truncate if necessary. This does the task of marking @@ -399,6 +403,8 @@ static int ocfs2_truncate_file(struct inode *inode, bail_unlock_data: ocfs2_data_unlock(inode, 1); + up_write(&OCFS2_I(inode)->ip_alloc_sem); + bail: mlog_exit(status); |