]> www.infradead.org Git - linux.git/commitdiff
dlm: disallow different configs nodeid storages
authorAlexander Aring <aahringo@redhat.com>
Fri, 4 Oct 2024 15:13:39 +0000 (11:13 -0400)
committerDavid Teigland <teigland@redhat.com>
Fri, 4 Oct 2024 15:31:31 +0000 (10:31 -0500)
The DLM configfs path has usually a nodeid in it's directory path and
again a file to store the nodeid again in a separate storage. It is
forced that the user space will set both (the directory name and nodeid
file) storage to the same value if it doesn't do that we run in some
kind of broken state.

This patch will simply represent the file storage to it's upper
directory nodeid name. It will force the user now to use a valid
unsigned int as nodeid directory name and will ignore all nodeid writes
in the nodeid file storage as this will now always represent the upper
nodeid directory name.

Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
fs/dlm/config.c
fs/dlm/config.h
fs/dlm/member.c

index eac96f1c1d7428479ba52a4fea96c00255e1ed5c..1980afaaa68cbc146f7cb44a7783ddad636f7d06 100644 (file)
@@ -24,9 +24,9 @@
 #include "lowcomms.h"
 
 /*
- * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid
+ * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid (refers to <node>)
  * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
- * /config/dlm/<cluster>/comms/<comm>/nodeid
+ * /config/dlm/<cluster>/comms/<comm>/nodeid (refers to <comm>)
  * /config/dlm/<cluster>/comms/<comm>/local
  * /config/dlm/<cluster>/comms/<comm>/addr      (write only)
  * /config/dlm/<cluster>/comms/<comm>/addr_list (read only)
@@ -517,6 +517,12 @@ static void release_space(struct config_item *i)
 static struct config_item *make_comm(struct config_group *g, const char *name)
 {
        struct dlm_comm *cm;
+       unsigned int nodeid;
+       int rv;
+
+       rv = kstrtouint(name, 0, &nodeid);
+       if (rv)
+               return ERR_PTR(rv);
 
        cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS);
        if (!cm)
@@ -528,7 +534,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name)
        if (!cm->seq)
                cm->seq = dlm_comm_count++;
 
-       cm->nodeid = -1;
+       cm->nodeid = nodeid;
        cm->local = 0;
        cm->addr_count = 0;
        cm->mark = 0;
@@ -555,16 +561,25 @@ static void release_comm(struct config_item *i)
 static struct config_item *make_node(struct config_group *g, const char *name)
 {
        struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
+       unsigned int nodeid;
        struct dlm_node *nd;
+       uint32_t seq = 0;
+       int rv;
+
+       rv = kstrtouint(name, 0, &nodeid);
+       if (rv)
+               return ERR_PTR(rv);
 
        nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS);
        if (!nd)
                return ERR_PTR(-ENOMEM);
 
        config_item_init_type_name(&nd->item, name, &node_type);
-       nd->nodeid = -1;
+       nd->nodeid = nodeid;
        nd->weight = 1;  /* default weight of 1 if none is set */
        nd->new = 1;     /* set to 0 once it's been read by dlm_nodeid_list() */
+       dlm_comm_seq(nodeid, &seq, true);
+       nd->comm_seq = seq;
 
        mutex_lock(&sp->members_lock);
        list_add(&nd->list, &sp->members);
@@ -622,16 +637,19 @@ void dlm_config_exit(void)
 
 static ssize_t comm_nodeid_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%d\n", config_item_to_comm(item)->nodeid);
+       unsigned int nodeid;
+       int rv;
+
+       rv = kstrtouint(config_item_name(item), 0, &nodeid);
+       if (WARN_ON(rv))
+               return rv;
+
+       return sprintf(buf, "%u\n", nodeid);
 }
 
 static ssize_t comm_nodeid_store(struct config_item *item, const char *buf,
                                 size_t len)
 {
-       int rc = kstrtoint(buf, 0, &config_item_to_comm(item)->nodeid);
-
-       if (rc)
-               return rc;
        return len;
 }
 
@@ -772,20 +790,19 @@ static struct configfs_attribute *comm_attrs[] = {
 
 static ssize_t node_nodeid_show(struct config_item *item, char *buf)
 {
-       return sprintf(buf, "%d\n", config_item_to_node(item)->nodeid);
+       unsigned int nodeid;
+       int rv;
+
+       rv = kstrtouint(config_item_name(item), 0, &nodeid);
+       if (WARN_ON(rv))
+               return rv;
+
+       return sprintf(buf, "%u\n", nodeid);
 }
 
 static ssize_t node_nodeid_store(struct config_item *item, const char *buf,
                                 size_t len)
 {
-       struct dlm_node *nd = config_item_to_node(item);
-       uint32_t seq = 0;
-       int rc = kstrtoint(buf, 0, &nd->nodeid);
-
-       if (rc)
-               return rc;
-       dlm_comm_seq(nd->nodeid, &seq);
-       nd->comm_seq = seq;
        return len;
 }
 
@@ -845,7 +862,7 @@ static struct dlm_comm *get_comm(int nodeid)
        if (!comm_list)
                return NULL;
 
-       mutex_lock(&clusters_root.subsys.su_mutex);
+       WARN_ON_ONCE(!mutex_is_locked(&clusters_root.subsys.su_mutex));
 
        list_for_each_entry(i, &comm_list->cg_children, ci_entry) {
                cm = config_item_to_comm(i);
@@ -856,7 +873,6 @@ static struct dlm_comm *get_comm(int nodeid)
                config_item_get(i);
                break;
        }
-       mutex_unlock(&clusters_root.subsys.su_mutex);
 
        if (!found)
                cm = NULL;
@@ -916,11 +932,20 @@ int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
        return rv;
 }
 
-int dlm_comm_seq(int nodeid, uint32_t *seq)
+int dlm_comm_seq(int nodeid, uint32_t *seq, bool locked)
 {
-       struct dlm_comm *cm = get_comm(nodeid);
+       struct dlm_comm *cm;
+
+       if (locked) {
+               cm = get_comm(nodeid);
+       } else {
+               mutex_lock(&clusters_root.subsys.su_mutex);
+               cm = get_comm(nodeid);
+               mutex_unlock(&clusters_root.subsys.su_mutex);
+       }
        if (!cm)
                return -EEXIST;
+
        *seq = cm->seq;
        put_comm(cm);
        return 0;
index ed237d9102085fe30749382704fd7f85f3aa1932..8a14a6e954632aa8f5cbd26a4c8e38f3061b32c7 100644 (file)
@@ -50,7 +50,7 @@ int dlm_config_init(void);
 void dlm_config_exit(void);
 int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
                     int *count_out);
-int dlm_comm_seq(int nodeid, uint32_t *seq);
+int dlm_comm_seq(int nodeid, uint32_t *seq, bool locked);
 int dlm_our_nodeid(void);
 int dlm_our_addr(struct sockaddr_storage *addr, int num);
 
index c9661906568a151f2af44a43246ff8fd18da20c8..b0864c93230f53dd4e31ee23550bcc7335fae765 100644 (file)
@@ -493,7 +493,7 @@ static void dlm_lsop_recover_slot(struct dlm_ls *ls, struct dlm_member *memb)
           we consider the node to have failed (versus
           being removed due to dlm_release_lockspace) */
 
-       error = dlm_comm_seq(memb->nodeid, &seq);
+       error = dlm_comm_seq(memb->nodeid, &seq, false);
 
        if (!error && seq == memb->comm_seq)
                return;