diff options
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 55 |
1 files changed, 15 insertions, 40 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index b75b2e1f0e42..c5c183ac41fe 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -382,18 +382,13 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
382 | 382 | ||
383 | down_write(&OCFS2_I(inode)->ip_alloc_sem); | 383 | down_write(&OCFS2_I(inode)->ip_alloc_sem); |
384 | 384 | ||
385 | /* This forces other nodes to sync and drop their pages. Do | 385 | /* |
386 | * this even if we have a truncate without allocation change - | 386 | * The inode lock forced other nodes to sync and drop their |
387 | * ocfs2 cluster sizes can be much greater than page size, so | 387 | * pages, which (correctly) happens even if we have a truncate |
388 | * we have to truncate them anyway. */ | 388 | * without allocation change - ocfs2 cluster sizes can be much |
389 | status = ocfs2_data_lock(inode, 1); | 389 | * greater than page size, so we have to truncate them |
390 | if (status < 0) { | 390 | * anyway. |
391 | up_write(&OCFS2_I(inode)->ip_alloc_sem); | 391 | */ |
392 | |||
393 | mlog_errno(status); | ||
394 | goto bail; | ||
395 | } | ||
396 | |||
397 | unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); | 392 | unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); |
398 | truncate_inode_pages(inode->i_mapping, new_i_size); | 393 | truncate_inode_pages(inode->i_mapping, new_i_size); |
399 | 394 | ||
@@ -403,7 +398,7 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
403 | if (status) | 398 | if (status) |
404 | mlog_errno(status); | 399 | mlog_errno(status); |
405 | 400 | ||
406 | goto bail_unlock_data; | 401 | goto bail_unlock_sem; |
407 | } | 402 | } |
408 | 403 | ||
409 | /* alright, we're going to need to do a full blown alloc size | 404 | /* alright, we're going to need to do a full blown alloc size |
@@ -413,25 +408,23 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
413 | status = ocfs2_orphan_for_truncate(osb, inode, di_bh, new_i_size); | 408 | status = ocfs2_orphan_for_truncate(osb, inode, di_bh, new_i_size); |
414 | if (status < 0) { | 409 | if (status < 0) { |
415 | mlog_errno(status); | 410 | mlog_errno(status); |
416 | goto bail_unlock_data; | 411 | goto bail_unlock_sem; |
417 | } | 412 | } |
418 | 413 | ||
419 | status = ocfs2_prepare_truncate(osb, inode, di_bh, &tc); | 414 | status = ocfs2_prepare_truncate(osb, inode, di_bh, &tc); |
420 | if (status < 0) { | 415 | if (status < 0) { |
421 | mlog_errno(status); | 416 | mlog_errno(status); |
422 | goto bail_unlock_data; | 417 | goto bail_unlock_sem; |
423 | } | 418 | } |
424 | 419 | ||
425 | status = ocfs2_commit_truncate(osb, inode, di_bh, tc); | 420 | status = ocfs2_commit_truncate(osb, inode, di_bh, tc); |
426 | if (status < 0) { | 421 | if (status < 0) { |
427 | mlog_errno(status); | 422 | mlog_errno(status); |
428 | goto bail_unlock_data; | 423 | goto bail_unlock_sem; |
429 | } | 424 | } |
430 | 425 | ||
431 | /* TODO: orphan dir cleanup here. */ | 426 | /* TODO: orphan dir cleanup here. */ |
432 | bail_unlock_data: | 427 | bail_unlock_sem: |
433 | ocfs2_data_unlock(inode, 1); | ||
434 | |||
435 | up_write(&OCFS2_I(inode)->ip_alloc_sem); | 428 | up_write(&OCFS2_I(inode)->ip_alloc_sem); |
436 | 429 | ||
437 | bail: | 430 | bail: |
@@ -917,7 +910,7 @@ static int ocfs2_extend_file(struct inode *inode, | |||
917 | struct buffer_head *di_bh, | 910 | struct buffer_head *di_bh, |
918 | u64 new_i_size) | 911 | u64 new_i_size) |
919 | { | 912 | { |
920 | int ret = 0, data_locked = 0; | 913 | int ret = 0; |
921 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 914 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
922 | 915 | ||
923 | BUG_ON(!di_bh); | 916 | BUG_ON(!di_bh); |
@@ -943,20 +936,6 @@ static int ocfs2_extend_file(struct inode *inode, | |||
943 | && ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | 936 | && ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) |
944 | goto out_update_size; | 937 | goto out_update_size; |
945 | 938 | ||
946 | /* | ||
947 | * protect the pages that ocfs2_zero_extend is going to be | ||
948 | * pulling into the page cache.. we do this before the | ||
949 | * metadata extend so that we don't get into the situation | ||
950 | * where we've extended the metadata but can't get the data | ||
951 | * lock to zero. | ||
952 | */ | ||
953 | ret = ocfs2_data_lock(inode, 1); | ||
954 | if (ret < 0) { | ||
955 | mlog_errno(ret); | ||
956 | goto out; | ||
957 | } | ||
958 | data_locked = 1; | ||
959 | |||
960 | /* | 939 | /* |
961 | * The alloc sem blocks people in read/write from reading our | 940 | * The alloc sem blocks people in read/write from reading our |
962 | * allocation until we're done changing it. We depend on | 941 | * allocation until we're done changing it. We depend on |
@@ -980,7 +959,7 @@ static int ocfs2_extend_file(struct inode *inode, | |||
980 | up_write(&oi->ip_alloc_sem); | 959 | up_write(&oi->ip_alloc_sem); |
981 | 960 | ||
982 | mlog_errno(ret); | 961 | mlog_errno(ret); |
983 | goto out_unlock; | 962 | goto out; |
984 | } | 963 | } |
985 | } | 964 | } |
986 | 965 | ||
@@ -991,7 +970,7 @@ static int ocfs2_extend_file(struct inode *inode, | |||
991 | 970 | ||
992 | if (ret < 0) { | 971 | if (ret < 0) { |
993 | mlog_errno(ret); | 972 | mlog_errno(ret); |
994 | goto out_unlock; | 973 | goto out; |
995 | } | 974 | } |
996 | 975 | ||
997 | out_update_size: | 976 | out_update_size: |
@@ -999,10 +978,6 @@ out_update_size: | |||
999 | if (ret < 0) | 978 | if (ret < 0) |
1000 | mlog_errno(ret); | 979 | mlog_errno(ret); |
1001 | 980 | ||
1002 | out_unlock: | ||
1003 | if (data_locked) | ||
1004 | ocfs2_data_unlock(inode, 1); | ||
1005 | |||
1006 | out: | 981 | out: |
1007 | return ret; | 982 | return ret; |
1008 | } | 983 | } |