diff options
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 37 |
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; |