Skip to content

Commit c12b582

Browse files
gamanakisbehlendorf
authored andcommitted
Fix the L2ARC write size calculating logic (2)
While commit bcd5321 adjusts the write size based on the size of the log block, this happens after comparing the unadjusted write size to the evicted (target) size. In this case l2ad_hand will exceed l2ad_evict and violate an assertion at the end of l2arc_write_buffers(). Fix this by adding the max log block size to the allocated size of the buffer to be committed before comparing the result to the target size. Also reset the l2arc_trim_ahead ZFS module variable when the adjusted write size exceeds the size of the L2ARC device. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: George Amanakis <[email protected]> Closes #14936 Closes #14954
1 parent 425f789 commit c12b582

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

module/zfs/arc.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8448,7 +8448,7 @@ l2arc_write_size(l2arc_dev_t *dev)
84488448
* device. This is important in l2arc_evict(), otherwise infinite
84498449
* iteration can occur.
84508450
*/
8451-
if (size >= dev->l2ad_end - dev->l2ad_start) {
8451+
if (size > dev->l2ad_end - dev->l2ad_start) {
84528452
cmn_err(CE_NOTE, "l2arc_write_max or l2arc_write_boost "
84538453
"plus the overhead of log blocks (persistent L2ARC, "
84548454
"%llu bytes) exceeds the size of the cache device "
@@ -8457,6 +8457,11 @@ l2arc_write_size(l2arc_dev_t *dev)
84578457
dev->l2ad_vdev->vdev_guid, L2ARC_WRITE_SIZE);
84588458
size = l2arc_write_max = l2arc_write_boost = L2ARC_WRITE_SIZE;
84598459

8460+
if (l2arc_trim_ahead > 1) {
8461+
cmn_err(CE_NOTE, "l2arc_trim_ahead set to 1");
8462+
l2arc_trim_ahead = 1;
8463+
}
8464+
84608465
if (arc_warm == B_FALSE)
84618466
size += l2arc_write_boost;
84628467

@@ -9087,7 +9092,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
90879092

90889093
top:
90899094
rerun = B_FALSE;
9090-
if (dev->l2ad_hand >= (dev->l2ad_end - distance)) {
9095+
if (dev->l2ad_hand + distance > dev->l2ad_end) {
90919096
/*
90929097
* When there is no space to accommodate upcoming writes,
90939098
* evict to the end. Then bump the write and evict hands
@@ -9281,7 +9286,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
92819286
*/
92829287
ASSERT3U(dev->l2ad_hand + distance, <, dev->l2ad_end);
92839288
if (!dev->l2ad_first)
9284-
ASSERT3U(dev->l2ad_hand, <, dev->l2ad_evict);
9289+
ASSERT3U(dev->l2ad_hand, <=, dev->l2ad_evict);
92859290
}
92869291
}
92879292

@@ -9547,7 +9552,13 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
95479552
uint64_t asize = vdev_psize_to_asize(dev->l2ad_vdev,
95489553
psize);
95499554

9550-
if ((write_asize + asize) > target_sz) {
9555+
/*
9556+
* If the allocated size of this buffer plus the max
9557+
* size for the pending log block exceeds the evicted
9558+
* target size, terminate writing buffers for this run.
9559+
*/
9560+
if (write_asize + asize +
9561+
sizeof (l2arc_log_blk_phys_t) > target_sz) {
95519562
full = B_TRUE;
95529563
mutex_exit(hash_lock);
95539564
break;
@@ -9669,7 +9680,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
96699680
*/
96709681
if (l2arc_log_blk_insert(dev, hdr)) {
96719682
/*
9672-
* l2ad_hand has been accounted for in
9683+
* l2ad_hand will be adjusted in
96739684
* l2arc_log_blk_commit().
96749685
*/
96759686
write_asize +=

0 commit comments

Comments
 (0)