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 <[email protected]>
Signed-off-by: Vishal Verma <[email protected]>
---
 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)
-- 
2.20.1
_______________________________________________
Linux-nvdimm mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to