aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r--fs/ocfs2/file.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index d9ba0a931a03..1be74c4e7814 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -30,6 +30,7 @@
30#include <linux/highmem.h> 30#include <linux/highmem.h>
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/uio.h> 32#include <linux/uio.h>
33#include <linux/sched.h>
33 34
34#define MLOG_MASK_PREFIX ML_INODE 35#define MLOG_MASK_PREFIX ML_INODE
35#include <cluster/masklog.h> 36#include <cluster/masklog.h>
@@ -691,6 +692,12 @@ static int ocfs2_zero_extend(struct inode *inode,
691 } 692 }
692 693
693 start_off += sb->s_blocksize; 694 start_off += sb->s_blocksize;
695
696 /*
697 * Very large extends have the potential to lock up
698 * the cpu for extended periods of time.
699 */
700 cond_resched();
694 } 701 }
695 702
696out: 703out:
@@ -728,31 +735,36 @@ static int ocfs2_extend_file(struct inode *inode,
728 clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) - 735 clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) -
729 OCFS2_I(inode)->ip_clusters; 736 OCFS2_I(inode)->ip_clusters;
730 737
731 if (clusters_to_add) { 738 /*
732 /* 739 * protect the pages that ocfs2_zero_extend is going to be
733 * protect the pages that ocfs2_zero_extend is going to 740 * pulling into the page cache.. we do this before the
734 * be pulling into the page cache.. we do this before the 741 * metadata extend so that we don't get into the situation
735 * metadata extend so that we don't get into the situation 742 * where we've extended the metadata but can't get the data
736 * where we've extended the metadata but can't get the data 743 * lock to zero.
737 * lock to zero. 744 */
738 */ 745 ret = ocfs2_data_lock(inode, 1);
739 ret = ocfs2_data_lock(inode, 1); 746 if (ret < 0) {
740 if (ret < 0) { 747 mlog_errno(ret);
741 mlog_errno(ret); 748 goto out;
742 goto out; 749 }
743 }
744 750
751 if (clusters_to_add) {
745 ret = ocfs2_extend_allocation(inode, clusters_to_add); 752 ret = ocfs2_extend_allocation(inode, clusters_to_add);
746 if (ret < 0) { 753 if (ret < 0) {
747 mlog_errno(ret); 754 mlog_errno(ret);
748 goto out_unlock; 755 goto out_unlock;
749 } 756 }
757 }
750 758
751 ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip); 759 /*
752 if (ret < 0) { 760 * Call this even if we don't add any clusters to the tree. We
753 mlog_errno(ret); 761 * still need to zero the area between the old i_size and the
754 goto out_unlock; 762 * new i_size.
755 } 763 */
764 ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip);
765 if (ret < 0) {
766 mlog_errno(ret);
767 goto out_unlock;
756 } 768 }
757 769
758 if (!tail_to_skip) { 770 if (!tail_to_skip) {
@@ -764,8 +776,7 @@ static int ocfs2_extend_file(struct inode *inode,
764 } 776 }
765 777
766out_unlock: 778out_unlock:
767 if (clusters_to_add) /* this is the only case in which we lock */ 779 ocfs2_data_unlock(inode, 1);
768 ocfs2_data_unlock(inode, 1);
769 780
770out: 781out:
771 return ret; 782 return ret;