diff --git a/module/zfs/arc.c b/module/zfs/arc.c index ce4a0239c..32ad80bcb 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -2104,8 +2104,9 @@ arc_do_user_evicts(void) void arc_adjust_meta(int64_t adjustment, boolean_t may_prune) { - int64_t delta; + int64_t delta, tmp = adjustment; + /* Evict MRU+MFU meta data to ghost lists */ if (adjustment > 0 && arc_mru->arcs_lsize[ARC_BUFC_METADATA] > 0) { delta = MIN(arc_mru->arcs_lsize[ARC_BUFC_METADATA], adjustment); arc_evict(arc_mru, 0, delta, FALSE, ARC_BUFC_METADATA); @@ -2115,9 +2116,24 @@ arc_adjust_meta(int64_t adjustment, boolean_t may_prune) if (adjustment > 0 && arc_mfu->arcs_lsize[ARC_BUFC_METADATA] > 0) { delta = MIN(arc_mfu->arcs_lsize[ARC_BUFC_METADATA], adjustment); arc_evict(arc_mfu, 0, delta, FALSE, ARC_BUFC_METADATA); + } + + /* Evict ghost MRU+MFU meta data */ + adjustment = tmp; + + if (adjustment > 0 && arc_mru_ghost->arcs_size > 0) { + delta = MIN(arc_mru_ghost->arcs_size, adjustment); + arc_evict_ghost(arc_mru_ghost, 0, delta, ARC_BUFC_METADATA); adjustment -= delta; } + if (adjustment > 0 && arc_mfu_ghost->arcs_size > 0) { + delta = MIN(arc_mfu_ghost->arcs_size, adjustment); + arc_evict_ghost(arc_mfu_ghost, 0, delta, ARC_BUFC_METADATA); + adjustment -= delta; + } + + /* Request the VFS release some meta data */ if (may_prune && (adjustment > 0) && (arc_meta_used > arc_meta_limit)) arc_do_user_prune(zfs_arc_meta_prune); }