From patchwork Wed Oct 2 23:49:20 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: 11171929 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 0D41617EE for ; Wed, 2 Oct 2019 23:49:43 +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 EA279222BE for ; Wed, 2 Oct 2019 23:49:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EA279222BE 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 D46C510FC720C; Wed, 2 Oct 2019 16:50:55 -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 ABE18100DC430 for ; Wed, 2 Oct 2019 16:50:53 -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:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,250,1566889200"; d="scan'208";a="195032112" Received: from vverma7-desk1.lm.intel.com ([10.232.112.164]) by orsmga003.jf.intel.com with ESMTP; 02 Oct 2019 16:49:35 -0700 From: Vishal Verma To: Subject: [ndctl PATCH 05/10] libdaxctl: allow memblock_in_dev() to return an error Date: Wed, 2 Oct 2019 17:49:20 -0600 Message-Id: <20191002234925.9190-6-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: C3YST2VTQQBBKREHJNV6KXNF24Z2WED3 X-Message-ID-Hash: C3YST2VTQQBBKREHJNV6KXNF24Z2WED3 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: With the MEM_FIND_ZONE operation, and the expectation that it will be called from 'daxctl list' listings, it is possible that memblock_in_dev() gets called without sufficient privileges. If this happens, currently, the above simply returns a 'false'. This was acceptable when the only operations were onlining/offlining (as there would be an actual failure later). However, it is not acceptable in the MEM_FIND_ZONE case, as it could yeild a different answer based on the privilege level. Change memblock_in_dev() to return an 'int' instead of a 'bool' so that error cases can be distinguished from actual address range test. Cc: Dan Williams Signed-off-by: Vishal Verma Reviewed-by: Dan Williams --- daxctl/lib/libdaxctl.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index 4460174..617887c 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -1211,40 +1211,42 @@ static int memblock_find_zone(struct daxctl_memory *mem, char *memblock, return 0; } -static bool memblock_in_dev(struct daxctl_memory *mem, const char *memblock) +static int memblock_in_dev(struct daxctl_memory *mem, const char *memblock) { const char *mem_base = "/sys/devices/system/memory/"; struct daxctl_dev *dev = daxctl_memory_get_dev(mem); unsigned long long memblock_res, dev_start, dev_end; const char *devname = daxctl_dev_get_devname(dev); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); + int rc, path_len = mem->buf_len; unsigned long memblock_size; - int path_len = mem->buf_len; char buf[SYSFS_ATTR_SIZE]; unsigned long phys_index; char *path = mem->mem_buf; if (snprintf(path, path_len, "%s/%s/phys_index", mem_base, memblock) < 0) - return false; + return -ENXIO; - if (sysfs_read_attr(ctx, path, buf) == 0) { + rc = sysfs_read_attr(ctx, path, buf); + if (rc == 0) { phys_index = strtoul(buf, NULL, 16); if (phys_index == 0 || phys_index == ULONG_MAX) { + rc = -errno; err(ctx, "%s: %s: Unable to determine phys_index: %s\n", - devname, memblock, strerror(errno)); - return false; + devname, memblock, strerror(-rc)); + return rc; } } else { err(ctx, "%s: %s: Unable to determine phys_index: %s\n", - devname, memblock, strerror(errno)); - return false; + devname, memblock, strerror(-rc)); + return rc; } dev_start = daxctl_dev_get_resource(dev); if (!dev_start) { err(ctx, "%s: Unable to determine resource\n", devname); - return false; + return -EACCES; } dev_end = dev_start + daxctl_dev_get_size(dev); @@ -1252,14 +1254,14 @@ static bool memblock_in_dev(struct daxctl_memory *mem, const char *memblock) if (!memblock_size) { err(ctx, "%s: Unable to determine memory block size\n", devname); - return false; + return -ENXIO; } memblock_res = phys_index * memblock_size; if (memblock_res >= dev_start && memblock_res <= dev_end) - return true; + return 1; - return false; + return 0; } static int op_for_one_memblock(struct daxctl_memory *mem, char *memblock, @@ -1317,8 +1319,12 @@ static int daxctl_memory_op(struct daxctl_memory *mem, enum memory_op op) errno = 0; while ((de = readdir(node_dir)) != NULL) { if (strncmp(de->d_name, "memory", 6) == 0) { - if (!memblock_in_dev(mem, de->d_name)) + rc = memblock_in_dev(mem, de->d_name); + if (rc < 0) + goto out_dir; + if (rc == 0) /* memblock not in dev */ continue; + /* memblock is in dev, perform op */ rc = op_for_one_memblock(mem, de->d_name, op, &status_flags); if (rc < 0)