Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[pandora-kernel.git] / fs / dlm / config.c
index 5069b2c..c4e7d72 100644 (file)
@@ -114,7 +114,7 @@ struct cluster_attribute {
 };
 
 static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field,
-                          unsigned int *info_field, int check_zero,
+                          int *info_field, int check_zero,
                           const char *buf, size_t len)
 {
        unsigned int x;
@@ -133,14 +133,6 @@ static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field,
        return len;
 }
 
-#define __CONFIGFS_ATTR(_name,_mode,_read,_write) {                           \
-       .attr   = { .ca_name = __stringify(_name),                            \
-                   .ca_mode = _mode,                                         \
-                   .ca_owner = THIS_MODULE },                                \
-       .show   = _read,                                                      \
-       .store  = _write,                                                     \
-}
-
 #define CLUSTER_ATTR(name, check_zero)                                        \
 static ssize_t name##_write(struct cluster *cl, const char *buf, size_t len)  \
 {                                                                             \
@@ -292,6 +284,7 @@ struct node {
        struct list_head list; /* space->members */
        int nodeid;
        int weight;
+       int new;
 };
 
 static struct configfs_group_operations clusters_ops = {
@@ -445,7 +438,7 @@ static struct config_group *make_cluster(struct config_group *g,
        kfree(gps);
        kfree(sps);
        kfree(cms);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 static void drop_cluster(struct config_group *g, struct config_item *i)
@@ -502,7 +495,7 @@ static struct config_group *make_space(struct config_group *g, const char *name)
        kfree(sp);
        kfree(gps);
        kfree(nds);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 static void drop_space(struct config_group *g, struct config_item *i)
@@ -535,7 +528,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name)
 
        cm = kzalloc(sizeof(struct comm), GFP_KERNEL);
        if (!cm)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        config_item_init_type_name(&cm->item, name, &comm_type);
        cm->nodeid = -1;
@@ -568,11 +561,12 @@ static struct config_item *make_node(struct config_group *g, const char *name)
 
        nd = kzalloc(sizeof(struct node), GFP_KERNEL);
        if (!nd)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        config_item_init_type_name(&nd->item, name, &node_type);
        nd->nodeid = -1;
        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() */
 
        mutex_lock(&sp->members_lock);
        list_add(&nd->list, &sp->members);
@@ -612,10 +606,10 @@ static struct clusters clusters_root = {
        },
 };
 
-int dlm_config_init(void)
+int __init dlm_config_init(void)
 {
        config_group_init(&clusters_root.subsys.su_group);
-       init_MUTEX(&clusters_root.subsys.su_sem);
+       mutex_init(&clusters_root.subsys.su_mutex);
        return configfs_register_subsystem(&clusters_root.subsys);
 }
 
@@ -759,9 +753,9 @@ static struct space *get_space(char *name)
        if (!space_list)
                return NULL;
 
-       down(&space_list->cg_subsys->su_sem);
-       i = config_group_find_obj(space_list, name);
-       up(&space_list->cg_subsys->su_sem);
+       mutex_lock(&space_list->cg_subsys->su_mutex);
+       i = config_group_find_item(space_list, name);
+       mutex_unlock(&space_list->cg_subsys->su_mutex);
 
        return to_space(i);
 }
@@ -780,7 +774,7 @@ static struct comm *get_comm(int nodeid, struct sockaddr_storage *addr)
        if (!comm_list)
                return NULL;
 
-       down(&clusters_root.subsys.su_sem);
+       mutex_lock(&clusters_root.subsys.su_mutex);
 
        list_for_each_entry(i, &comm_list->cg_children, ci_entry) {
                cm = to_comm(i);
@@ -800,7 +794,7 @@ static struct comm *get_comm(int nodeid, struct sockaddr_storage *addr)
                        break;
                }
        }
-       up(&clusters_root.subsys.su_sem);
+       mutex_unlock(&clusters_root.subsys.su_mutex);
 
        if (!found)
                cm = NULL;
@@ -813,12 +807,13 @@ static void put_comm(struct comm *cm)
 }
 
 /* caller must free mem */
-int dlm_nodeid_list(char *lsname, int **ids_out)
+int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
+                   int **new_out, int *new_count_out)
 {
        struct space *sp;
        struct node *nd;
-       int i = 0, rv = 0;
-       int *ids;
+       int i = 0, rv = 0, ids_count = 0, new_count = 0;
+       int *ids, *new;
 
        sp = get_space(lsname);
        if (!sp)
@@ -826,23 +821,50 @@ int dlm_nodeid_list(char *lsname, int **ids_out)
 
        mutex_lock(&sp->members_lock);
        if (!sp->members_count) {
-               rv = 0;
+               rv = -EINVAL;
+               printk(KERN_ERR "dlm: zero members_count\n");
                goto out;
        }
 
-       ids = kcalloc(sp->members_count, sizeof(int), GFP_KERNEL);
+       ids_count = sp->members_count;
+
+       ids = kcalloc(ids_count, sizeof(int), GFP_KERNEL);
        if (!ids) {
                rv = -ENOMEM;
                goto out;
        }
 
-       rv = sp->members_count;
-       list_for_each_entry(nd, &sp->members, list)
+       list_for_each_entry(nd, &sp->members, list) {
                ids[i++] = nd->nodeid;
+               if (nd->new)
+                       new_count++;
+       }
+
+       if (ids_count != i)
+               printk(KERN_ERR "dlm: bad nodeid count %d %d\n", ids_count, i);
 
-       if (rv != i)
-               printk("bad nodeid count %d %d\n", rv, i);
+       if (!new_count)
+               goto out_ids;
+
+       new = kcalloc(new_count, sizeof(int), GFP_KERNEL);
+       if (!new) {
+               kfree(ids);
+               rv = -ENOMEM;
+               goto out;
+       }
+
+       i = 0;
+       list_for_each_entry(nd, &sp->members, list) {
+               if (nd->new) {
+                       new[i++] = nd->nodeid;
+                       nd->new = 0;
+               }
+       }
+       *new_count_out = new_count;
+       *new_out = new;
 
+ out_ids:
+       *ids_count_out = ids_count;
        *ids_out = ids;
  out:
        mutex_unlock(&sp->members_lock);