@@ -849,7 +849,7 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
849
849
850
850
static int ocfs2_alloc_write_ctxt (struct ocfs2_write_ctxt * * wcp ,
851
851
struct ocfs2_super * osb , loff_t pos ,
852
- unsigned len )
852
+ unsigned len , struct buffer_head * di_bh )
853
853
{
854
854
struct ocfs2_write_ctxt * wc ;
855
855
@@ -859,6 +859,8 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
859
859
860
860
wc -> w_cpos = pos >> osb -> s_clustersize_bits ;
861
861
wc -> w_clen = ocfs2_clusters_for_bytes (osb -> sb , len );
862
+ get_bh (di_bh );
863
+ wc -> w_di_bh = di_bh ;
862
864
863
865
if (unlikely (PAGE_CACHE_SHIFT > osb -> s_clustersize_bits ))
864
866
wc -> w_large_pages = 1 ;
@@ -1211,9 +1213,10 @@ static void ocfs2_set_target_boundaries(struct ocfs2_super *osb,
1211
1213
}
1212
1214
}
1213
1215
1214
- int ocfs2_write_begin (struct file * file , struct address_space * mapping ,
1215
- loff_t pos , unsigned len , unsigned flags ,
1216
- struct page * * pagep , void * * fsdata )
1216
+ static int ocfs2_write_begin_nolock (struct address_space * mapping ,
1217
+ loff_t pos , unsigned len , unsigned flags ,
1218
+ struct page * * pagep , void * * fsdata ,
1219
+ struct buffer_head * di_bh )
1217
1220
{
1218
1221
int ret , i , credits = OCFS2_INODE_UPDATE_CREDITS ;
1219
1222
unsigned int num_clusters = 0 , clusters_to_alloc = 0 ;
@@ -1227,28 +1230,14 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1227
1230
handle_t * handle ;
1228
1231
struct ocfs2_write_cluster_desc * desc ;
1229
1232
1230
- ret = ocfs2_alloc_write_ctxt (& wc , osb , pos , len );
1233
+ ret = ocfs2_alloc_write_ctxt (& wc , osb , pos , len , di_bh );
1231
1234
if (ret ) {
1232
1235
mlog_errno (ret );
1233
1236
return ret ;
1234
1237
}
1235
1238
1236
- ret = ocfs2_meta_lock (inode , & wc -> w_di_bh , 1 );
1237
- if (ret ) {
1238
- mlog_errno (ret );
1239
- goto out ;
1240
- }
1241
1239
di = (struct ocfs2_dinode * )wc -> w_di_bh -> b_data ;
1242
1240
1243
- /*
1244
- * Take alloc sem here to prevent concurrent lookups. That way
1245
- * the mapping, zeroing and tree manipulation within
1246
- * ocfs2_write() will be safe against ->readpage(). This
1247
- * should also serve to lock out allocation from a shared
1248
- * writeable region.
1249
- */
1250
- down_write (& OCFS2_I (inode )-> ip_alloc_sem );
1251
-
1252
1241
for (i = 0 ; i < wc -> w_clen ; i ++ ) {
1253
1242
desc = & wc -> w_desc [i ];
1254
1243
desc -> c_cpos = wc -> w_cpos + i ;
@@ -1258,7 +1247,7 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1258
1247
& num_clusters , NULL );
1259
1248
if (ret ) {
1260
1249
mlog_errno (ret );
1261
- goto out_meta ;
1250
+ goto out ;
1262
1251
}
1263
1252
} else if (phys ) {
1264
1253
/*
@@ -1293,7 +1282,7 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1293
1282
& data_ac , & meta_ac );
1294
1283
if (ret ) {
1295
1284
mlog_errno (ret );
1296
- goto out_meta ;
1285
+ goto out ;
1297
1286
}
1298
1287
1299
1288
credits = ocfs2_calc_extend_credits (inode -> i_sb , di ,
@@ -1303,17 +1292,11 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1303
1292
1304
1293
ocfs2_set_target_boundaries (osb , wc , pos , len , clusters_to_alloc );
1305
1294
1306
- ret = ocfs2_data_lock (inode , 1 );
1307
- if (ret ) {
1308
- mlog_errno (ret );
1309
- goto out_meta ;
1310
- }
1311
-
1312
1295
handle = ocfs2_start_trans (osb , credits );
1313
1296
if (IS_ERR (handle )) {
1314
1297
ret = PTR_ERR (handle );
1315
1298
mlog_errno (ret );
1316
- goto out_data ;
1299
+ goto out ;
1317
1300
}
1318
1301
1319
1302
wc -> w_handle = handle ;
@@ -1363,13 +1346,6 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1363
1346
out_commit :
1364
1347
ocfs2_commit_trans (osb , handle );
1365
1348
1366
- out_data :
1367
- ocfs2_data_unlock (inode , 1 );
1368
-
1369
- out_meta :
1370
- up_write (& OCFS2_I (inode )-> ip_alloc_sem );
1371
- ocfs2_meta_unlock (inode , 1 );
1372
-
1373
1349
out :
1374
1350
ocfs2_free_write_ctxt (wc );
1375
1351
@@ -1380,9 +1356,60 @@ int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1380
1356
return ret ;
1381
1357
}
1382
1358
1383
- int ocfs2_write_end (struct file * file , struct address_space * mapping ,
1384
- loff_t pos , unsigned len , unsigned copied ,
1385
- struct page * page , void * fsdata )
1359
+ int ocfs2_write_begin (struct file * file , struct address_space * mapping ,
1360
+ loff_t pos , unsigned len , unsigned flags ,
1361
+ struct page * * pagep , void * * fsdata )
1362
+ {
1363
+ int ret ;
1364
+ struct buffer_head * di_bh = NULL ;
1365
+ struct inode * inode = mapping -> host ;
1366
+
1367
+ ret = ocfs2_meta_lock (inode , & di_bh , 1 );
1368
+ if (ret ) {
1369
+ mlog_errno (ret );
1370
+ return ret ;
1371
+ }
1372
+
1373
+ /*
1374
+ * Take alloc sem here to prevent concurrent lookups. That way
1375
+ * the mapping, zeroing and tree manipulation within
1376
+ * ocfs2_write() will be safe against ->readpage(). This
1377
+ * should also serve to lock out allocation from a shared
1378
+ * writeable region.
1379
+ */
1380
+ down_write (& OCFS2_I (inode )-> ip_alloc_sem );
1381
+
1382
+ ret = ocfs2_data_lock (inode , 1 );
1383
+ if (ret ) {
1384
+ mlog_errno (ret );
1385
+ goto out_fail ;
1386
+ }
1387
+
1388
+ ret = ocfs2_write_begin_nolock (mapping , pos , len , flags , pagep ,
1389
+ fsdata , di_bh );
1390
+ if (ret ) {
1391
+ mlog_errno (ret );
1392
+ goto out_fail_data ;
1393
+ }
1394
+
1395
+ brelse (di_bh );
1396
+
1397
+ return 0 ;
1398
+
1399
+ out_fail_data :
1400
+ ocfs2_data_unlock (inode , 1 );
1401
+ out_fail :
1402
+ up_write (& OCFS2_I (inode )-> ip_alloc_sem );
1403
+
1404
+ brelse (di_bh );
1405
+ ocfs2_meta_unlock (inode , 1 );
1406
+
1407
+ return ret ;
1408
+ }
1409
+
1410
+ static int ocfs2_write_end_nolock (struct address_space * mapping ,
1411
+ loff_t pos , unsigned len , unsigned copied ,
1412
+ struct page * page , void * fsdata )
1386
1413
{
1387
1414
int i ;
1388
1415
unsigned from , to , start = pos & (PAGE_CACHE_SIZE - 1 );
@@ -1444,12 +1471,25 @@ int ocfs2_write_end(struct file *file, struct address_space *mapping,
1444
1471
ocfs2_journal_dirty (handle , wc -> w_di_bh );
1445
1472
1446
1473
ocfs2_commit_trans (osb , handle );
1474
+ ocfs2_free_write_ctxt (wc );
1475
+
1476
+ return copied ;
1477
+ }
1478
+
1479
+ int ocfs2_write_end (struct file * file , struct address_space * mapping ,
1480
+ loff_t pos , unsigned len , unsigned copied ,
1481
+ struct page * page , void * fsdata )
1482
+ {
1483
+ int ret ;
1484
+ struct inode * inode = mapping -> host ;
1485
+
1486
+ ret = ocfs2_write_end_nolock (mapping , pos , len , copied , page , fsdata );
1487
+
1447
1488
ocfs2_data_unlock (inode , 1 );
1448
1489
up_write (& OCFS2_I (inode )-> ip_alloc_sem );
1449
1490
ocfs2_meta_unlock (inode , 1 );
1450
- ocfs2_free_write_ctxt (wc );
1451
1491
1452
- return copied ;
1492
+ return ret ;
1453
1493
}
1454
1494
1455
1495
const struct address_space_operations ocfs2_aops = {
0 commit comments