aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-05-09 16:40:18 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2007-07-10 20:19:57 -0400
commit2e89b2e48e1da09ed483f195968c9172aa95b5e2 (patch)
tree3e81f49c13134ebcbf4572474ad47b65e5ecffba
parentbaf4661a8225d3a39622b795a8db0e6aa845c1ec (diff)
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>
-rw-r--r--fs/ocfs2/alloc.c3
-rw-r--r--fs/ocfs2/file.c12
2 files changed, 9 insertions, 6 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 19712a7d145f..02b6e7af8edb 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -3631,8 +3631,6 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
3631 3631
3632 mlog_entry_void(); 3632 mlog_entry_void();
3633 3633
3634 down_write(&OCFS2_I(inode)->ip_alloc_sem);
3635
3636 new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb, 3634 new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb,
3637 i_size_read(inode)); 3635 i_size_read(inode));
3638 3636
@@ -3754,7 +3752,6 @@ start:
3754 goto start; 3752 goto start;
3755 3753
3756bail: 3754bail:
3757 up_write(&OCFS2_I(inode)->ip_alloc_sem);
3758 3755
3759 ocfs2_schedule_truncate_log_flush(osb, 1); 3756 ocfs2_schedule_truncate_log_flush(osb, 1);
3760 3757
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 4979b6675717..566f9b70ec91 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -326,9 +326,6 @@ static int ocfs2_truncate_file(struct inode *inode,
326 (unsigned long long)OCFS2_I(inode)->ip_blkno, 326 (unsigned long long)OCFS2_I(inode)->ip_blkno,
327 (unsigned long long)new_i_size); 327 (unsigned long long)new_i_size);
328 328
329 unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1);
330 truncate_inode_pages(inode->i_mapping, new_i_size);
331
332 fe = (struct ocfs2_dinode *) di_bh->b_data; 329 fe = (struct ocfs2_dinode *) di_bh->b_data;
333 if (!OCFS2_IS_VALID_DINODE(fe)) { 330 if (!OCFS2_IS_VALID_DINODE(fe)) {
334 OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe); 331 OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
@@ -363,16 +360,23 @@ static int ocfs2_truncate_file(struct inode *inode,
363 if (new_i_size == le64_to_cpu(fe->i_size)) 360 if (new_i_size == le64_to_cpu(fe->i_size))
364 goto bail; 361 goto bail;
365 362
363 down_write(&OCFS2_I(inode)->ip_alloc_sem);
364
366 /* This forces other nodes to sync and drop their pages. Do 365 /* This forces other nodes to sync and drop their pages. Do
367 * this even if we have a truncate without allocation change - 366 * this even if we have a truncate without allocation change -
368 * ocfs2 cluster sizes can be much greater than page size, so 367 * ocfs2 cluster sizes can be much greater than page size, so
369 * we have to truncate them anyway. */ 368 * we have to truncate them anyway. */
370 status = ocfs2_data_lock(inode, 1); 369 status = ocfs2_data_lock(inode, 1);
371 if (status < 0) { 370 if (status < 0) {
371 up_write(&OCFS2_I(inode)->ip_alloc_sem);
372
372 mlog_errno(status); 373 mlog_errno(status);
373 goto bail; 374 goto bail;
374 } 375 }
375 376
377 unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1);
378 truncate_inode_pages(inode->i_mapping, new_i_size);
379
376 /* alright, we're going to need to do a full blown alloc size 380 /* alright, we're going to need to do a full blown alloc size
377 * change. Orphan the inode so that recovery can complete the 381 * change. Orphan the inode so that recovery can complete the
378 * truncate if necessary. This does the task of marking 382 * truncate if necessary. This does the task of marking
@@ -399,6 +403,8 @@ static int ocfs2_truncate_file(struct inode *inode,
399bail_unlock_data: 403bail_unlock_data:
400 ocfs2_data_unlock(inode, 1); 404 ocfs2_data_unlock(inode, 1);
401 405
406 up_write(&OCFS2_I(inode)->ip_alloc_sem);
407
402bail: 408bail:
403 409
404 mlog_exit(status); 410 mlog_exit(status);