From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3E68C31E49 for ; Wed, 19 Jun 2019 08:03:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 872CE21479 for ; Wed, 19 Jun 2019 08:03:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731203AbfFSIDY (ORCPT ); Wed, 19 Jun 2019 04:03:24 -0400 Received: from mx2.suse.de ([195.135.220.15]:45622 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730418AbfFSIDY (ORCPT ); Wed, 19 Jun 2019 04:03:24 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 1A296AF61; Wed, 19 Jun 2019 08:03:21 +0000 (UTC) From: Qu Wenruo To: dm-devel@redhat.com Cc: linux-btrfs@vger.kernel.org Subject: [PATCH 1/2] dm log writes: Allow dm-log-writes to filter bios based on types to reduce log device space usage Date: Wed, 19 Jun 2019 16:03:11 +0800 Message-Id: <20190619080312.11549-2-wqu@suse.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190619080312.11549-1-wqu@suse.com> References: <20190619080312.11549-1-wqu@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Since dm-log-writes will record all writes, include data and metadata writes, it can consume a lot of space. However for a lot of filesystems, the data bio (without METADATA flag) can be skipped for certain use case, thus we can skip them in dm-log-writes to hugely reduce space usage. This patch will introduce a new optional constructor parameter, "dump_type=%s", for dm-log-writes. The '%s' can be ALL, METADATA, FUA, FLUSH, DISCARD, MARK or the ORed result of them. The default dump_type will be 'ALL', so the behavior is not changed at all. But user can specify dump_type=METADATA|FUA|FLUSH|DISCARD|MARK to skip data writes to save space on log device. Currently the dump_type can only be speicified at contruction time. Signed-off-by: Qu Wenruo --- drivers/md/dm-log-writes.c | 146 +++++++++++++++++++++++++++++++++++-- 1 file changed, 141 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c index af94bbe77ce2..9edf0bdcae39 100644 --- a/drivers/md/dm-log-writes.c +++ b/drivers/md/dm-log-writes.c @@ -115,6 +115,7 @@ struct log_writes_c { struct list_head logging_blocks; wait_queue_head_t wait; struct task_struct *log_kthread; + u32 dump_type; }; struct pending_block { @@ -503,15 +504,99 @@ static int log_writes_kthread(void *arg) return 0; } +#define string_type_to_bit(string) \ +({ \ + if (!strcasecmp(p, #string)) { \ + dump_type |= LOG_##string##_FLAG; \ + continue; \ + } \ +}) +static int parse_dump_types(struct log_writes_c *lc, const char *string) +{ + char *orig; + char *opts; + char *p; + u32 dump_type = LOG_MARK_FLAG; + int ret = 0; + + opts = kstrdup(string, GFP_KERNEL); + if (!opts) + return -ENOMEM; + orig = opts; + + while ((p = strsep(&opts, "|")) != NULL) { + if (!*p) + continue; + if (!strcasecmp(p, "ALL")) { + dump_type = (u32)-1; + /* No need to check other flags */ + break; + } + string_type_to_bit(METADATA); + string_type_to_bit(FUA); + string_type_to_bit(FLUSH); + string_type_to_bit(DISCARD); + string_type_to_bit(MARK); + ret = -EINVAL; + goto out; + } +out: + kfree(orig); + if (!ret) + lc->dump_type = dump_type; + return ret; +} +#undef string_type_to_bit + +/* Must be large enough to contain "METADATA|FUA|FLUSH|DISCARD|MARK" */ +#define DUMP_TYPES_BUF_SIZE 256 +#define dump_type_to_string(name) \ +({ \ + if (lc->dump_type & LOG_##name##_FLAG) { \ + if (!first_word) \ + strcat(buf, "|"); \ + strcat(buf, #name); \ + first_word = false; \ + } \ + }) +static void status_dump_types(struct log_writes_c *lc, char *buf) +{ + bool first_word = true; + + buf[0] = '\0'; + + if (lc->dump_type == (u32)-1) { + strcat(buf, "ALL"); + return; + } + dump_type_to_string(METADATA); + dump_type_to_string(FUA); + dump_type_to_string(FLUSH); + dump_type_to_string(DISCARD); + dump_type_to_string(MARK); + return; +} +#undef dump_type_to_string + /* * Construct a log-writes mapping: - * log-writes + * log-writes [