From patchwork Wed Oct 2 23:49:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Verma, Vishal L" X-Patchwork-Id: 11171921 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 DAE0016B1 for ; Wed, 2 Oct 2019 23:49:39 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C3550222BE for ; Wed, 2 Oct 2019 23:49:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C3550222BE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from new-ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A30F1100DC436; Wed, 2 Oct 2019 16:50:54 -0700 (PDT) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=134.134.136.24; helo=mga09.intel.com; envelope-from=vishal.l.verma@intel.com; receiver= Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id F2B59100DC415 for ; Wed, 2 Oct 2019 16:50:51 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Oct 2019 16:49:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,250,1566889200"; d="scan'208";a="195032101" Received: from vverma7-desk1.lm.intel.com ([10.232.112.164]) by orsmga003.jf.intel.com with ESMTP; 02 Oct 2019 16:49:34 -0700 From: Vishal Verma To: Subject: [ndctl PATCH 02/10] libdaxctl: refactor memblock_is_online() checks Date: Wed, 2 Oct 2019 17:49:17 -0600 Message-Id: <20191002234925.9190-3-vishal.l.verma@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191002234925.9190-1-vishal.l.verma@intel.com> References: <20191002234925.9190-1-vishal.l.verma@intel.com> MIME-Version: 1.0 Message-ID-Hash: X75LQJ3GPHETSITXEHKLXW6DHORJ27XG X-Message-ID-Hash: X75LQJ3GPHETSITXEHKLXW6DHORJ27XG X-MailFrom: vishal.l.verma@intel.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Dave Hansen , Ben Olson , Michal Biesek X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: The {online,offline}_one_memblock() helpers both open-coded the check for whether a block is online. There is already a function to perform this check - memblock_is_online(). Consolidate the checking using this helper everywhere it is applicable. Cc: Dan Williams Signed-off-by: Vishal Verma Reviewed-by: Dan Williams --- daxctl/lib/libdaxctl.c | 90 +++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index a828644..6243857 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -1047,12 +1047,11 @@ DAXCTL_EXPORT unsigned long daxctl_memory_get_block_size(struct daxctl_memory *m return mem->block_size; } -static int online_one_memblock(struct daxctl_memory *mem, char *memblock) +static int memblock_is_online(struct daxctl_memory *mem, char *memblock) { struct daxctl_dev *dev = daxctl_memory_get_dev(mem); const char *devname = daxctl_dev_get_devname(dev); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); - const char *mode = "online_movable"; int len = mem->buf_len, rc; char buf[SYSFS_ATTR_SIZE]; char *path = mem->mem_buf; @@ -1073,41 +1072,20 @@ static int online_one_memblock(struct daxctl_memory *mem, char *memblock) return rc; } - /* - * if already online, possibly due to kernel config or a udev rule, - * there is nothing to do and we can skip over the memblock - */ if (strncmp(buf, "online", 6) == 0) return 1; - rc = sysfs_write_attr_quiet(ctx, path, mode); - if (rc) { - /* - * While we performed an already-online check above, there - * is still a TOCTOU hole where someone (such as a udev rule) - * may have raced to online the memory. In such a case, - * the sysfs store will fail, however we can check for this - * by simply reading the state again. If it changed to the - * desired state, then we don't have to error out. - */ - if (sysfs_read_attr(ctx, path, buf) == 0) { - if (strncmp(buf, "online", 6) == 0) - return 1; - } - err(ctx, "%s: Failed to online %s: %s\n", - devname, path, strerror(-rc)); - } - return rc; + /* offline */ + return 0; } -static int offline_one_memblock(struct daxctl_memory *mem, char *memblock) +static int online_one_memblock(struct daxctl_memory *mem, char *memblock) { struct daxctl_dev *dev = daxctl_memory_get_dev(mem); const char *devname = daxctl_dev_get_devname(dev); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); - const char *mode = "offline"; + const char *mode = "online_movable"; int len = mem->buf_len, rc; - char buf[SYSFS_ATTR_SIZE]; char *path = mem->mem_buf; const char *node_path; @@ -1119,37 +1097,39 @@ static int offline_one_memblock(struct daxctl_memory *mem, char *memblock) if (rc < 0) return -ENOMEM; - rc = sysfs_read_attr(ctx, path, buf); - if (rc) { - err(ctx, "%s: Failed to read %s: %s\n", - devname, path, strerror(-rc)); + /* + * if already online, possibly due to kernel config or a udev rule, + * there is nothing to do and we can skip over the memblock + */ + rc = memblock_is_online(mem, memblock); + if (rc) return rc; - } - - /* if already offline, there is nothing to do */ - if (strncmp(buf, "offline", 7) == 0) - return 1; rc = sysfs_write_attr_quiet(ctx, path, mode); if (rc) { - /* Close the TOCTOU hole like in online_one_memblock() above */ - if (sysfs_read_attr(ctx, path, buf) == 0) { - if (strncmp(buf, "offline", 7) == 0) - return 1; - } - err(ctx, "%s: Failed to offline %s: %s\n", + /* + * While we performed an already-online check above, there + * is still a TOCTOU hole where someone (such as a udev rule) + * may have raced to online the memory. In such a case, + * the sysfs store will fail, however we can check for this + * by simply reading the state again. If it changed to the + * desired state, then we don't have to error out. + */ + if (memblock_is_online(mem, memblock)) + return 1; + err(ctx, "%s: Failed to online %s: %s\n", devname, path, strerror(-rc)); } return rc; } -static int memblock_is_online(struct daxctl_memory *mem, char *memblock) +static int offline_one_memblock(struct daxctl_memory *mem, char *memblock) { struct daxctl_dev *dev = daxctl_memory_get_dev(mem); const char *devname = daxctl_dev_get_devname(dev); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); + const char *mode = "offline"; int len = mem->buf_len, rc; - char buf[SYSFS_ATTR_SIZE]; char *path = mem->mem_buf; const char *node_path; @@ -1161,18 +1141,22 @@ static int memblock_is_online(struct daxctl_memory *mem, char *memblock) if (rc < 0) return -ENOMEM; - rc = sysfs_read_attr(ctx, path, buf); - if (rc) { - err(ctx, "%s: Failed to read %s: %s\n", - devname, path, strerror(-rc)); + /* if already offline, there is nothing to do */ + rc = memblock_is_online(mem, memblock); + if (rc < 0) return rc; - } - - if (strncmp(buf, "online", 6) == 0) + if (!rc) return 1; - /* offline */ - return 0; + rc = sysfs_write_attr_quiet(ctx, path, mode); + if (rc) { + /* Close the TOCTOU hole like in online_one_memblock() above */ + if (!memblock_is_online(mem, memblock)) + return 1; + err(ctx, "%s: Failed to offline %s: %s\n", + devname, path, strerror(-rc)); + } + return rc; } static bool memblock_in_dev(struct daxctl_memory *mem, const char *memblock)