forked from Minki/linux
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
@ -3631,8 +3631,6 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
|
|||||||
|
|
||||||
mlog_entry_void();
|
mlog_entry_void();
|
||||||
|
|
||||||
down_write(&OCFS2_I(inode)->ip_alloc_sem);
|
|
||||||
|
|
||||||
new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb,
|
new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb,
|
||||||
i_size_read(inode));
|
i_size_read(inode));
|
||||||
|
|
||||||
@ -3754,7 +3752,6 @@ start:
|
|||||||
goto start;
|
goto start;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
up_write(&OCFS2_I(inode)->ip_alloc_sem);
|
|
||||||
|
|
||||||
ocfs2_schedule_truncate_log_flush(osb, 1);
|
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)OCFS2_I(inode)->ip_blkno,
|
||||||
(unsigned long long)new_i_size);
|
(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;
|
fe = (struct ocfs2_dinode *) di_bh->b_data;
|
||||||
if (!OCFS2_IS_VALID_DINODE(fe)) {
|
if (!OCFS2_IS_VALID_DINODE(fe)) {
|
||||||
OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, 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))
|
if (new_i_size == le64_to_cpu(fe->i_size))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
down_write(&OCFS2_I(inode)->ip_alloc_sem);
|
||||||
|
|
||||||
/* This forces other nodes to sync and drop their pages. Do
|
/* This forces other nodes to sync and drop their pages. Do
|
||||||
* this even if we have a truncate without allocation change -
|
* this even if we have a truncate without allocation change -
|
||||||
* ocfs2 cluster sizes can be much greater than page size, so
|
* ocfs2 cluster sizes can be much greater than page size, so
|
||||||
* we have to truncate them anyway. */
|
* we have to truncate them anyway. */
|
||||||
status = ocfs2_data_lock(inode, 1);
|
status = ocfs2_data_lock(inode, 1);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
|
up_write(&OCFS2_I(inode)->ip_alloc_sem);
|
||||||
|
|
||||||
mlog_errno(status);
|
mlog_errno(status);
|
||||||
goto bail;
|
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
|
/* alright, we're going to need to do a full blown alloc size
|
||||||
* change. Orphan the inode so that recovery can complete the
|
* change. Orphan the inode so that recovery can complete the
|
||||||
* truncate if necessary. This does the task of marking
|
* truncate if necessary. This does the task of marking
|
||||||
@ -399,6 +403,8 @@ static int ocfs2_truncate_file(struct inode *inode,
|
|||||||
bail_unlock_data:
|
bail_unlock_data:
|
||||||
ocfs2_data_unlock(inode, 1);
|
ocfs2_data_unlock(inode, 1);
|
||||||
|
|
||||||
|
up_write(&OCFS2_I(inode)->ip_alloc_sem);
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
|
||||||
mlog_exit(status);
|
mlog_exit(status);
|
||||||
|
Loading…
Reference in New Issue
Block a user