diff options
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 50cd8a209012..fa43810e5970 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -1211,18 +1211,33 @@ static int ocfs2_write_cluster_by_desc(struct address_space *mapping, | |||
1211 | loff_t pos, unsigned len) | 1211 | loff_t pos, unsigned len) |
1212 | { | 1212 | { |
1213 | int ret, i; | 1213 | int ret, i; |
1214 | loff_t cluster_off; | ||
1215 | unsigned int local_len = len; | ||
1214 | struct ocfs2_write_cluster_desc *desc; | 1216 | struct ocfs2_write_cluster_desc *desc; |
1217 | struct ocfs2_super *osb = OCFS2_SB(mapping->host->i_sb); | ||
1215 | 1218 | ||
1216 | for (i = 0; i < wc->w_clen; i++) { | 1219 | for (i = 0; i < wc->w_clen; i++) { |
1217 | desc = &wc->w_desc[i]; | 1220 | desc = &wc->w_desc[i]; |
1218 | 1221 | ||
1222 | /* | ||
1223 | * We have to make sure that the total write passed in | ||
1224 | * doesn't extend past a single cluster. | ||
1225 | */ | ||
1226 | local_len = len; | ||
1227 | cluster_off = pos & (osb->s_clustersize - 1); | ||
1228 | if ((cluster_off + local_len) > osb->s_clustersize) | ||
1229 | local_len = osb->s_clustersize - cluster_off; | ||
1230 | |||
1219 | ret = ocfs2_write_cluster(mapping, desc->c_phys, | 1231 | ret = ocfs2_write_cluster(mapping, desc->c_phys, |
1220 | desc->c_unwritten, data_ac, meta_ac, | 1232 | desc->c_unwritten, data_ac, meta_ac, |
1221 | wc, desc->c_cpos, pos, len); | 1233 | wc, desc->c_cpos, pos, local_len); |
1222 | if (ret) { | 1234 | if (ret) { |
1223 | mlog_errno(ret); | 1235 | mlog_errno(ret); |
1224 | goto out; | 1236 | goto out; |
1225 | } | 1237 | } |
1238 | |||
1239 | len -= local_len; | ||
1240 | pos += local_len; | ||
1226 | } | 1241 | } |
1227 | 1242 | ||
1228 | ret = 0; | 1243 | ret = 0; |