mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
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>
This commit is contained in:
parent
baf4661a82
commit
2e89b2e48e
2 changed files with 9 additions and 6 deletions
|
@ -3631,8 +3631,6 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
|
|||
|
||||
mlog_entry_void();
|
||||
|
||||
down_write(&OCFS2_I(inode)->ip_alloc_sem);
|
||||
|
||||
new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb,
|
||||
i_size_read(inode));
|
||||
|
||||
|
@ -3754,7 +3752,6 @@ start:
|
|||
goto start;
|
||||
|
||||
bail:
|
||||
up_write(&OCFS2_I(inode)->ip_alloc_sem);
|
||||
|
||||
ocfs2_schedule_truncate_log_flush(osb, 1);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue