diff options
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r-- | fs/xfs/xfs_trans.c | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index f6d956b7711e..f80a067a4658 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1350,7 +1350,7 @@ xfs_trans_fill_vecs( | |||
1350 | * they could be immediately flushed and we'd have to race with the flusher | 1350 | * they could be immediately flushed and we'd have to race with the flusher |
1351 | * trying to pull the item from the AIL as we add it. | 1351 | * trying to pull the item from the AIL as we add it. |
1352 | */ | 1352 | */ |
1353 | void | 1353 | static void |
1354 | xfs_trans_item_committed( | 1354 | xfs_trans_item_committed( |
1355 | struct xfs_log_item *lip, | 1355 | struct xfs_log_item *lip, |
1356 | xfs_lsn_t commit_lsn, | 1356 | xfs_lsn_t commit_lsn, |
@@ -1425,6 +1425,83 @@ xfs_trans_committed( | |||
1425 | xfs_trans_free(tp); | 1425 | xfs_trans_free(tp); |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | static inline void | ||
1429 | xfs_log_item_batch_insert( | ||
1430 | struct xfs_ail *ailp, | ||
1431 | struct xfs_log_item **log_items, | ||
1432 | int nr_items, | ||
1433 | xfs_lsn_t commit_lsn) | ||
1434 | { | ||
1435 | int i; | ||
1436 | |||
1437 | spin_lock(&ailp->xa_lock); | ||
1438 | /* xfs_trans_ail_update_bulk drops ailp->xa_lock */ | ||
1439 | xfs_trans_ail_update_bulk(ailp, log_items, nr_items, commit_lsn); | ||
1440 | |||
1441 | for (i = 0; i < nr_items; i++) | ||
1442 | IOP_UNPIN(log_items[i], 0); | ||
1443 | } | ||
1444 | |||
1445 | /* | ||
1446 | * Bulk operation version of xfs_trans_committed that takes a log vector of | ||
1447 | * items to insert into the AIL. This uses bulk AIL insertion techniques to | ||
1448 | * minimise lock traffic. | ||
1449 | */ | ||
1450 | void | ||
1451 | xfs_trans_committed_bulk( | ||
1452 | struct xfs_ail *ailp, | ||
1453 | struct xfs_log_vec *log_vector, | ||
1454 | xfs_lsn_t commit_lsn, | ||
1455 | int aborted) | ||
1456 | { | ||
1457 | #define LOG_ITEM_BATCH_SIZE 32 | ||
1458 | struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE]; | ||
1459 | struct xfs_log_vec *lv; | ||
1460 | int i = 0; | ||
1461 | |||
1462 | /* unpin all the log items */ | ||
1463 | for (lv = log_vector; lv; lv = lv->lv_next ) { | ||
1464 | struct xfs_log_item *lip = lv->lv_item; | ||
1465 | xfs_lsn_t item_lsn; | ||
1466 | |||
1467 | if (aborted) | ||
1468 | lip->li_flags |= XFS_LI_ABORTED; | ||
1469 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | ||
1470 | |||
1471 | /* item_lsn of -1 means the item was freed */ | ||
1472 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | ||
1473 | continue; | ||
1474 | |||
1475 | if (item_lsn != commit_lsn) { | ||
1476 | |||
1477 | /* | ||
1478 | * Not a bulk update option due to unusual item_lsn. | ||
1479 | * Push into AIL immediately, rechecking the lsn once | ||
1480 | * we have the ail lock. Then unpin the item. | ||
1481 | */ | ||
1482 | spin_lock(&ailp->xa_lock); | ||
1483 | if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) | ||
1484 | xfs_trans_ail_update(ailp, lip, item_lsn); | ||
1485 | else | ||
1486 | spin_unlock(&ailp->xa_lock); | ||
1487 | IOP_UNPIN(lip, 0); | ||
1488 | continue; | ||
1489 | } | ||
1490 | |||
1491 | /* Item is a candidate for bulk AIL insert. */ | ||
1492 | log_items[i++] = lv->lv_item; | ||
1493 | if (i >= LOG_ITEM_BATCH_SIZE) { | ||
1494 | xfs_log_item_batch_insert(ailp, log_items, | ||
1495 | LOG_ITEM_BATCH_SIZE, commit_lsn); | ||
1496 | i = 0; | ||
1497 | } | ||
1498 | } | ||
1499 | |||
1500 | /* make sure we insert the remainder! */ | ||
1501 | if (i) | ||
1502 | xfs_log_item_batch_insert(ailp, log_items, i, commit_lsn); | ||
1503 | } | ||
1504 | |||
1428 | /* | 1505 | /* |
1429 | * Called from the trans_commit code when we notice that | 1506 | * Called from the trans_commit code when we notice that |
1430 | * the filesystem is in the middle of a forced shutdown. | 1507 | * the filesystem is in the middle of a forced shutdown. |