aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 460d440310f2..f37f25c931f5 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -855,6 +855,7 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
855 struct ocfs2_super *osb, loff_t pos, 855 struct ocfs2_super *osb, loff_t pos,
856 unsigned len, struct buffer_head *di_bh) 856 unsigned len, struct buffer_head *di_bh)
857{ 857{
858 u32 cend;
858 struct ocfs2_write_ctxt *wc; 859 struct ocfs2_write_ctxt *wc;
859 860
860 wc = kzalloc(sizeof(struct ocfs2_write_ctxt), GFP_NOFS); 861 wc = kzalloc(sizeof(struct ocfs2_write_ctxt), GFP_NOFS);
@@ -862,7 +863,8 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
862 return -ENOMEM; 863 return -ENOMEM;
863 864
864 wc->w_cpos = pos >> osb->s_clustersize_bits; 865 wc->w_cpos = pos >> osb->s_clustersize_bits;
865 wc->w_clen = ocfs2_clusters_for_bytes(osb->sb, len); 866 cend = (pos + len - 1) >> osb->s_clustersize_bits;
867 wc->w_clen = cend - wc->w_cpos + 1;
866 get_bh(di_bh); 868 get_bh(di_bh);
867 wc->w_di_bh = di_bh; 869 wc->w_di_bh = di_bh;
868 870
@@ -928,18 +930,11 @@ static void ocfs2_write_failure(struct inode *inode,
928 loff_t user_pos, unsigned user_len) 930 loff_t user_pos, unsigned user_len)
929{ 931{
930 int i; 932 int i;
931 unsigned from, to; 933 unsigned from = user_pos & (PAGE_CACHE_SIZE - 1),
934 to = user_pos + user_len;
932 struct page *tmppage; 935 struct page *tmppage;
933 936
934 ocfs2_zero_new_buffers(wc->w_target_page, user_pos, user_len); 937 ocfs2_zero_new_buffers(wc->w_target_page, from, to);
935
936 if (wc->w_large_pages) {
937 from = wc->w_target_from;
938 to = wc->w_target_to;
939 } else {
940 from = 0;
941 to = PAGE_CACHE_SIZE;
942 }
943 938
944 for(i = 0; i < wc->w_num_pages; i++) { 939 for(i = 0; i < wc->w_num_pages; i++) {
945 tmppage = wc->w_pages[i]; 940 tmppage = wc->w_pages[i];
@@ -989,9 +984,6 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
989 map_from = cluster_start; 984 map_from = cluster_start;
990 map_to = cluster_end; 985 map_to = cluster_end;
991 } 986 }
992
993 wc->w_target_from = map_from;
994 wc->w_target_to = map_to;
995 } else { 987 } else {
996 /* 988 /*
997 * If we haven't allocated the new page yet, we 989 * If we haven't allocated the new page yet, we
@@ -1209,18 +1201,33 @@ static int ocfs2_write_cluster_by_desc(struct address_space *mapping,
1209 loff_t pos, unsigned len) 1201 loff_t pos, unsigned len)
1210{ 1202{
1211 int ret, i; 1203 int ret, i;
1204 loff_t cluster_off;
1205 unsigned int local_len = len;
1212 struct ocfs2_write_cluster_desc *desc; 1206 struct ocfs2_write_cluster_desc *desc;
1207 struct ocfs2_super *osb = OCFS2_SB(mapping->host->i_sb);
1213 1208
1214 for (i = 0; i < wc->w_clen; i++) { 1209 for (i = 0; i < wc->w_clen; i++) {
1215 desc = &wc->w_desc[i]; 1210 desc = &wc->w_desc[i];
1216 1211
1212 /*
1213 * We have to make sure that the total write passed in
1214 * doesn't extend past a single cluster.
1215 */
1216 local_len = len;
1217 cluster_off = pos & (osb->s_clustersize - 1);
1218 if ((cluster_off + local_len) > osb->s_clustersize)
1219 local_len = osb->s_clustersize - cluster_off;
1220
1217 ret = ocfs2_write_cluster(mapping, desc->c_phys, 1221 ret = ocfs2_write_cluster(mapping, desc->c_phys,
1218 desc->c_unwritten, data_ac, meta_ac, 1222 desc->c_unwritten, data_ac, meta_ac,
1219 wc, desc->c_cpos, pos, len); 1223 wc, desc->c_cpos, pos, local_len);
1220 if (ret) { 1224 if (ret) {
1221 mlog_errno(ret); 1225 mlog_errno(ret);
1222 goto out; 1226 goto out;
1223 } 1227 }
1228
1229 len -= local_len;
1230 pos += local_len;
1224 } 1231 }
1225 1232
1226 ret = 0; 1233 ret = 0;