From patchwork Wed Dec 4 14:07:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikos Tsironis X-Patchwork-Id: 11272991 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9544A109A for ; Wed, 4 Dec 2019 14:08:02 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4DCF6206DF for ; Wed, 4 Dec 2019 14:08:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="g4hy6TNj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4DCF6206DF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arrikto.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=dm-devel-bounces@redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1575468481; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=4OP1aPZ7dY9qkqy+6VsHo3HvKjYNau4GZh3AkWlFRlM=; b=g4hy6TNjPjz/ajaOPNIy6wUJXc9igHBBAFThqDgJgI7+dAIbk2Mu7BXU94sE/7wSJKZbfb ykP7FHIUcqTWd+M1KYebvQqjEAJLLn0sOl0rO7CVnNB3GsKowAmCtFKUS2an8qFxFB4qZq hwpLvjj/nCEOVd2LqSckGYqFgatApWQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-339-ZD7PYoLxPlSuerSz9blfrA-1; Wed, 04 Dec 2019 09:07:59 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7D2761183E3D; Wed, 4 Dec 2019 14:07:54 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5955419C68; Wed, 4 Dec 2019 14:07:54 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 18D725BC09; Wed, 4 Dec 2019 14:07:54 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id xB4E7qws007070 for ; Wed, 4 Dec 2019 09:07:52 -0500 Received: by smtp.corp.redhat.com (Postfix) id 986B820899F4; Wed, 4 Dec 2019 14:07:52 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 93FB82026D68 for ; Wed, 4 Dec 2019 14:07:52 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 67E26802FF5 for ; Wed, 4 Dec 2019 14:07:52 +0000 (UTC) Received: from mail-lj1-f193.google.com (mail-lj1-f193.google.com [209.85.208.193]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-12-cLCR-SFjOE2ZCJPrjXam9Q-1; Wed, 04 Dec 2019 09:07:48 -0500 Received: by mail-lj1-f193.google.com with SMTP id h23so8240079ljc.8 for ; Wed, 04 Dec 2019 06:07:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GbVW51uGGUA9zYmXh+XLbV7Bbm2WrgiiCZpfqnLU31I=; b=XnOINMh4sP1tHLj5aYNOLxTAWZEOPbjascYAFYrmTyNp8wt00LmPCIso/lRG5SG1t7 2N8hjYqy2Rs4kgvPaNFDdBcXvsttIYmXxZSSJvlmCDMybOaWVQbYR30RbV40SUmACRD9 pxfc/4MiZQzO1oGxg3PED3Dwy+uRjZQGnDZ6VJqUdlfxDLJJIZoIKVqMff+1XaVES/5Z gFGAaNawJauhHj+k2n7aeWS6X09si7TvK9auR8RaMIFLhgzJEEpdCwfSfF1gv2jorf8E NByY4ae9VwGXYMVdp1yPrtZq97L4po4HLirBiE/p4xKK0OtXoD1e5yDuelXWIuOT82wb HxmQ== X-Gm-Message-State: APjAAAXq+oYHFUvakapavhfCUvuOFKleMR+juhfmI1Yz6EKgohVlkLdk EW3GSo+pWf4YE8kxnyoNP2LxlA== X-Google-Smtp-Source: APXvYqy7gP8L9Ojjr5/TMzB8GfZwuPuxTSvPrpf+JPNBzEJ9rpRfTa29OBWtkwDU5vOJVFke5EE7Ng== X-Received: by 2002:a05:651c:153:: with SMTP id c19mr2212376ljd.237.1575468467125; Wed, 04 Dec 2019 06:07:47 -0800 (PST) Received: from snf-864.vm.snf.arr ([31.177.62.212]) by smtp.gmail.com with ESMTPSA id n3sm3350450lfk.61.2019.12.04.06.07.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Dec 2019 06:07:46 -0800 (PST) From: Nikos Tsironis To: snitzer@redhat.com, agk@redhat.com, dm-devel@redhat.com Date: Wed, 4 Dec 2019 16:07:41 +0200 Message-Id: <20191204140742.26273-2-ntsironis@arrikto.com> In-Reply-To: <20191204140742.26273-1-ntsironis@arrikto.com> References: <20191204140742.26273-1-ntsironis@arrikto.com> X-MC-Unique: cLCR-SFjOE2ZCJPrjXam9Q-1 X-MC-Unique: ZD7PYoLxPlSuerSz9blfrA-1 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id xB4E7qws007070 X-loop: dm-devel@redhat.com Cc: thornber@redhat.com, ntsironis@arrikto.com Subject: [dm-devel] [PATCH 1/2] dm thin metadata: Add support for a pre-commit callback X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 Add support for one pre-commit callback which is run right before the metadata are committed. This allows the thin provisioning target to run a callback before the metadata are committed and is required by the next commit. Cc: stable@vger.kernel.org Signed-off-by: Nikos Tsironis --- drivers/md/dm-thin-metadata.c | 29 +++++++++++++++++++++++++++++ drivers/md/dm-thin-metadata.h | 7 +++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 4c68a7b93d5e..b88d6d701f5b 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -189,6 +189,15 @@ struct dm_pool_metadata { sector_t data_block_size; /* + * Pre-commit callback. + * + * This allows the thin provisioning target to run a callback before + * the metadata are committed. + */ + dm_pool_pre_commit_fn pre_commit_fn; + void *pre_commit_context; + + /* * We reserve a section of the metadata for commit overhead. * All reported space does *not* include this. */ @@ -826,6 +835,14 @@ static int __commit_transaction(struct dm_pool_metadata *pmd) if (unlikely(!pmd->in_service)) return 0; + if (pmd->pre_commit_fn) { + r = pmd->pre_commit_fn(pmd->pre_commit_context); + if (r < 0) { + DMERR("pre-commit callback failed"); + return r; + } + } + r = __write_changed_details(pmd); if (r < 0) return r; @@ -892,6 +909,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, pmd->in_service = false; pmd->bdev = bdev; pmd->data_block_size = data_block_size; + pmd->pre_commit_fn = NULL; + pmd->pre_commit_context = NULL; r = __create_persistent_data_objects(pmd, format_device); if (r) { @@ -2044,6 +2063,16 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, return r; } +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, + dm_pool_pre_commit_fn fn, + void *context) +{ + pmd_write_lock_in_core(pmd); + pmd->pre_commit_fn = fn; + pmd->pre_commit_context = context; + pmd_write_unlock(pmd); +} + int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd) { int r = -EINVAL; diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index f6be0d733c20..7ef56bd2a7e3 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h @@ -230,6 +230,13 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd); */ void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd); +/* Pre-commit callback */ +typedef int (*dm_pool_pre_commit_fn)(void *context); + +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, + dm_pool_pre_commit_fn fn, + void *context); + /*----------------------------------------------------------------*/ #endif From patchwork Wed Dec 4 14:07:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikos Tsironis X-Patchwork-Id: 11272995 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3ACEB6C1 for ; Wed, 4 Dec 2019 14:08:06 +0000 (UTC) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EF552206DF for ; Wed, 4 Dec 2019 14:08:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CvrjXRc2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EF552206DF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arrikto.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=dm-devel-bounces@redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1575468484; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=jVBY5vKprSzz2lrIL3D57V5OJ56ULJID2/+8akvWhJc=; b=CvrjXRc2WA4jZ+W+/WLFI0WH0JsnzDawl3WQklUS68ywq/mlXC5zGOU4DjYFqChv5tJlNL dL6mzBBvsch8oPT9n/jnH3n4f/0cJLlDi+w6A6EWQYMe+qL/XM+dSRJaZHj8vFfeAv2zAM /6oLMtiMl0qwHup20A170n2rFc6zmdw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-394-4YKAnfTkOdCzXOAU1GmKHg-1; Wed, 04 Dec 2019 09:08:02 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 92E12805847; Wed, 4 Dec 2019 14:07:57 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 717711001938; Wed, 4 Dec 2019 14:07:57 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 3178F5BC12; Wed, 4 Dec 2019 14:07:57 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id xB4E7tDH007094 for ; Wed, 4 Dec 2019 09:07:55 -0500 Received: by smtp.corp.redhat.com (Postfix) id 73445117C02; Wed, 4 Dec 2019 14:07:55 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mimecast-mx02.redhat.com (mimecast01.extmail.prod.ext.rdu2.redhat.com [10.11.55.17]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6C931117C0D for ; Wed, 4 Dec 2019 14:07:51 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BC21685A322 for ; Wed, 4 Dec 2019 14:07:51 +0000 (UTC) Received: from mail-lj1-f193.google.com (mail-lj1-f193.google.com [209.85.208.193]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-151-vd_qQIuQPRycGhmMla5bXA-1; Wed, 04 Dec 2019 09:07:49 -0500 Received: by mail-lj1-f193.google.com with SMTP id a13so8228055ljm.10 for ; Wed, 04 Dec 2019 06:07:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y+JWdTPa/RdHtAEGW2Bkm+DIkQbGaryMawNNljcThNk=; b=E2l+2O0/8OH1k4IEPIoXpopxxE/fcOqOk5eHqsGGwYMjV7TlH02LXiYzfjDk7EcWpP c5XJi5dGrGOCFiLOujLf0Kb6UEcKIjFucyKtJC43hUMSb95nugR8MnfQ+dclwFzULA5L AFWOdmWsDhfdvVlQWq5OmisQQ337fReC5fKsEDiQByVdF8gKpRYynsCX/NxPehHmCY7I L/NyL4A1kFks2EuwFYfMazRVORQQtacS++oihhimVGSLqprB1ZkOzfM3+bwUflUGsmLF eOr5Mx5babYjh5nJVL3xrTATToKHRH2IKEIiCHJrvzBilmF22Fq64w24pwewMVGrU9eV R+gw== X-Gm-Message-State: APjAAAVCykdWceQCqnNjgjDcX80y2aTQ0ZFtbbHWxCw6QegYIopgtDIy yufBwPxEU2FUCkpsiaYuRHvZWQ== X-Google-Smtp-Source: APXvYqxMOspOXRAoqpm4wC2FMU0sy0gvKxCVhjQ+HdAnFemqBfHhzOHqWYWHQ7UZstomnQJ5T3A4Rw== X-Received: by 2002:a2e:6f19:: with SMTP id k25mr2117612ljc.84.1575468468309; Wed, 04 Dec 2019 06:07:48 -0800 (PST) Received: from snf-864.vm.snf.arr ([31.177.62.212]) by smtp.gmail.com with ESMTPSA id n3sm3350450lfk.61.2019.12.04.06.07.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Dec 2019 06:07:47 -0800 (PST) From: Nikos Tsironis To: snitzer@redhat.com, agk@redhat.com, dm-devel@redhat.com Date: Wed, 4 Dec 2019 16:07:42 +0200 Message-Id: <20191204140742.26273-3-ntsironis@arrikto.com> In-Reply-To: <20191204140742.26273-1-ntsironis@arrikto.com> References: <20191204140742.26273-1-ntsironis@arrikto.com> X-MC-Unique: vd_qQIuQPRycGhmMla5bXA-1 X-MC-Unique: 4YKAnfTkOdCzXOAU1GmKHg-1 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id xB4E7tDH007094 X-loop: dm-devel@redhat.com Cc: thornber@redhat.com, ntsironis@arrikto.com Subject: [dm-devel] [PATCH 2/2] dm thin: Flush data device before committing metadata X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 The thin provisioning target maintains per thin device mappings that map virtual blocks to data blocks in the data device. When we write to a shared block, in case of internal snapshots, or provision a new block, in case of external snapshots, we copy the shared block to a new data block (COW), update the mapping for the relevant virtual block and then issue the write to the new data block. Suppose the data device has a volatile write-back cache and the following sequence of events occur: 1. We write to a shared block 2. A new data block is allocated 3. We copy the shared block to the new data block using kcopyd (COW) 4. We insert the new mapping for the virtual block in the btree for that thin device. 5. The commit timeout expires and we commit the metadata, that now includes the new mapping from step (4). 6. The system crashes and the data device's cache has not been flushed, meaning that the COWed data are lost. The next time we read that virtual block of the thin device we read it from the data block allocated in step (2), since the metadata have been successfully committed. The data are lost due to the crash, so we read garbage instead of the old, shared data. This has the following implications: 1. In case of writes to shared blocks, with size smaller than the pool's block size (which means we first copy the whole block and then issue the smaller write), we corrupt data that the user never touched. 2. In case of writes to shared blocks, with size equal to the device's logical block size, we fail to provide atomic sector writes. When the system recovers the user will read garbage from that sector instead of the old data or the new data. 3. Even for writes to shared blocks, with size equal to the pool's block size (overwrites), after the system recovers, the written sectors will contain garbage instead of a random mix of sectors containing either old data or new data, thus we fail again to provide atomic sectors writes. 4. Even when the user flushes the thin device, because we first commit the metadata and then pass down the flush, the same risk for corruption exists (if the system crashes after the metadata have been committed but before the flush is passed down to the data device.) The only case which is unaffected is that of writes with size equal to the pool's block size and with the FUA flag set. But, because FUA writes trigger metadata commits, this case can trigger the corruption indirectly. Moreover, apart from internal and external snapshots, the same issue exists for newly provisioned blocks, when block zeroing is enabled. After the system recovers the provisioned blocks might contain garbage instead of zeroes. To solve this and avoid the potential data corruption we flush the pool's data device **before** committing its metadata. This ensures that the data blocks of any newly inserted mappings are properly written to non-volatile storage and won't be lost in case of a crash. Cc: stable@vger.kernel.org Signed-off-by: Nikos Tsironis --- drivers/md/dm-thin.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 5a2c494cb552..e0be545080d0 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3180,6 +3180,34 @@ static void metadata_low_callback(void *context) dm_table_event(pool->ti->table); } +/* + * We need to flush the data device **before** committing the metadata. + * + * This ensures that the data blocks of any newly inserted mappings are + * properly written to non-volatile storage and won't be lost in case of a + * crash. + * + * Failure to do so can result in data corruption in the case of internal or + * external snapshots and in the case of newly provisioned blocks, when block + * zeroing is enabled. + */ +static int metadata_pre_commit_callback(void *context) +{ + struct pool_c *pt = context; + struct bio bio; + int r; + + bio_init(&bio, NULL, 0); + bio_set_dev(&bio, pt->data_dev->bdev); + bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; + + r = submit_bio_wait(&bio); + + bio_uninit(&bio); + + return r; +} + static sector_t get_dev_size(struct block_device *bdev) { return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; @@ -3374,6 +3402,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) if (r) goto out_flags_changed; + dm_pool_register_pre_commit_callback(pt->pool->pmd, + metadata_pre_commit_callback, + pt); + pt->callbacks.congested_fn = pool_is_congested; dm_table_add_target_callbacks(ti->table, &pt->callbacks);