diff options
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 108 |
1 files changed, 76 insertions, 32 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 510bf84c9cf5..077583b50391 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -1188,6 +1188,31 @@ out: | |||
1188 | return ret; | 1188 | return ret; |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | static int ocfs2_write_cluster_by_desc(struct address_space *mapping, | ||
1192 | struct ocfs2_alloc_context *data_ac, | ||
1193 | struct ocfs2_alloc_context *meta_ac, | ||
1194 | struct ocfs2_write_ctxt *wc, | ||
1195 | loff_t pos, unsigned len) | ||
1196 | { | ||
1197 | int ret, i; | ||
1198 | struct ocfs2_write_cluster_desc *desc; | ||
1199 | |||
1200 | for (i = 0; i < wc->w_clen; i++) { | ||
1201 | desc = &wc->w_desc[i]; | ||
1202 | |||
1203 | ret = ocfs2_write_cluster(mapping, desc->c_phys, data_ac, | ||
1204 | meta_ac, wc, desc->c_cpos, pos, len); | ||
1205 | if (ret) { | ||
1206 | mlog_errno(ret); | ||
1207 | goto out; | ||
1208 | } | ||
1209 | } | ||
1210 | |||
1211 | ret = 0; | ||
1212 | out: | ||
1213 | return ret; | ||
1214 | } | ||
1215 | |||
1191 | /* | 1216 | /* |
1192 | * ocfs2_write_end() wants to know which parts of the target page it | 1217 | * ocfs2_write_end() wants to know which parts of the target page it |
1193 | * should complete the write on. It's easiest to compute them ahead of | 1218 | * should complete the write on. It's easiest to compute them ahead of |
@@ -1240,30 +1265,19 @@ static void ocfs2_set_target_boundaries(struct ocfs2_super *osb, | |||
1240 | } | 1265 | } |
1241 | } | 1266 | } |
1242 | 1267 | ||
1243 | int ocfs2_write_begin_nolock(struct address_space *mapping, | 1268 | /* |
1244 | loff_t pos, unsigned len, unsigned flags, | 1269 | * Populate each single-cluster write descriptor in the write context |
1245 | struct page **pagep, void **fsdata, | 1270 | * with information about the i/o to be done. |
1246 | struct buffer_head *di_bh, struct page *mmap_page) | 1271 | */ |
1272 | static int ocfs2_populate_write_desc(struct inode *inode, | ||
1273 | struct ocfs2_write_ctxt *wc, | ||
1274 | unsigned int *clusters_to_alloc) | ||
1247 | { | 1275 | { |
1248 | int ret, i, credits = OCFS2_INODE_UPDATE_CREDITS; | 1276 | int ret; |
1249 | unsigned int num_clusters = 0, clusters_to_alloc = 0; | ||
1250 | u32 phys = 0; | ||
1251 | struct ocfs2_write_ctxt *wc; | ||
1252 | struct inode *inode = mapping->host; | ||
1253 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1254 | struct ocfs2_dinode *di; | ||
1255 | struct ocfs2_alloc_context *data_ac = NULL; | ||
1256 | struct ocfs2_alloc_context *meta_ac = NULL; | ||
1257 | handle_t *handle; | ||
1258 | struct ocfs2_write_cluster_desc *desc; | 1277 | struct ocfs2_write_cluster_desc *desc; |
1259 | 1278 | unsigned int num_clusters = 0; | |
1260 | ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); | 1279 | u32 phys = 0; |
1261 | if (ret) { | 1280 | int i; |
1262 | mlog_errno(ret); | ||
1263 | return ret; | ||
1264 | } | ||
1265 | |||
1266 | di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; | ||
1267 | 1281 | ||
1268 | for (i = 0; i < wc->w_clen; i++) { | 1282 | for (i = 0; i < wc->w_clen; i++) { |
1269 | desc = &wc->w_desc[i]; | 1283 | desc = &wc->w_desc[i]; |
@@ -1287,12 +1301,46 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1287 | desc->c_phys = phys; | 1301 | desc->c_phys = phys; |
1288 | if (phys == 0) { | 1302 | if (phys == 0) { |
1289 | desc->c_new = 1; | 1303 | desc->c_new = 1; |
1290 | clusters_to_alloc++; | 1304 | *clusters_to_alloc = *clusters_to_alloc + 1; |
1291 | } | 1305 | } |
1292 | 1306 | ||
1293 | num_clusters--; | 1307 | num_clusters--; |
1294 | } | 1308 | } |
1295 | 1309 | ||
1310 | ret = 0; | ||
1311 | out: | ||
1312 | return ret; | ||
1313 | } | ||
1314 | |||
1315 | int ocfs2_write_begin_nolock(struct address_space *mapping, | ||
1316 | loff_t pos, unsigned len, unsigned flags, | ||
1317 | struct page **pagep, void **fsdata, | ||
1318 | struct buffer_head *di_bh, struct page *mmap_page) | ||
1319 | { | ||
1320 | int ret, credits = OCFS2_INODE_UPDATE_CREDITS; | ||
1321 | unsigned int clusters_to_alloc = 0; | ||
1322 | struct ocfs2_write_ctxt *wc; | ||
1323 | struct inode *inode = mapping->host; | ||
1324 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1325 | struct ocfs2_dinode *di; | ||
1326 | struct ocfs2_alloc_context *data_ac = NULL; | ||
1327 | struct ocfs2_alloc_context *meta_ac = NULL; | ||
1328 | handle_t *handle; | ||
1329 | |||
1330 | ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); | ||
1331 | if (ret) { | ||
1332 | mlog_errno(ret); | ||
1333 | return ret; | ||
1334 | } | ||
1335 | |||
1336 | ret = ocfs2_populate_write_desc(inode, wc, &clusters_to_alloc); | ||
1337 | if (ret) { | ||
1338 | mlog_errno(ret); | ||
1339 | goto out; | ||
1340 | } | ||
1341 | |||
1342 | di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; | ||
1343 | |||
1296 | /* | 1344 | /* |
1297 | * We set w_target_from, w_target_to here so that | 1345 | * We set w_target_from, w_target_to here so that |
1298 | * ocfs2_write_end() knows which range in the target page to | 1346 | * ocfs2_write_end() knows which range in the target page to |
@@ -1351,15 +1399,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1351 | goto out_commit; | 1399 | goto out_commit; |
1352 | } | 1400 | } |
1353 | 1401 | ||
1354 | for (i = 0; i < wc->w_clen; i++) { | 1402 | ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos, |
1355 | desc = &wc->w_desc[i]; | 1403 | len); |
1356 | 1404 | if (ret) { | |
1357 | ret = ocfs2_write_cluster(mapping, desc->c_phys, data_ac, | 1405 | mlog_errno(ret); |
1358 | meta_ac, wc, desc->c_cpos, pos, len); | 1406 | goto out_commit; |
1359 | if (ret) { | ||
1360 | mlog_errno(ret); | ||
1361 | goto out_commit; | ||
1362 | } | ||
1363 | } | 1407 | } |
1364 | 1408 | ||
1365 | if (data_ac) | 1409 | if (data_ac) |