aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-06-12 17:00:18 -0400
committerMark Fasheh <mfasheh@suse.com>2008-07-14 16:57:16 -0400
commit11c3b79218390a139f2d474ee1e983a672d5839a (patch)
tree03fa1a4927f2d9856ee45a64d522424478058b6f
parent6d8344baee99402de58b5fa5dfea197242955c15 (diff)
configfs: Allow ->make_item() and ->make_group() to return detailed errors.
The configfs operations ->make_item() and ->make_group() currently return a new item/group. A return of NULL signifies an error. Because of this, -ENOMEM is the only return code bubbled up the stack. Multiple folks have requested the ability to return specific error codes when these operations fail. This patch adds that ability by changing the ->make_item/group() ops to return an int. Also updated are the in-kernel users of configfs. Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--Documentation/filesystems/configfs/configfs.txt10
-rw-r--r--Documentation/filesystems/configfs/configfs_example.c14
-rw-r--r--drivers/net/netconsole.c10
-rw-r--r--fs/configfs/dir.c13
-rw-r--r--fs/dlm/config.c45
-rw-r--r--fs/ocfs2/cluster/heartbeat.c17
-rw-r--r--fs/ocfs2/cluster/nodemanager.c45
-rw-r--r--include/linux/configfs.h4
8 files changed, 94 insertions, 64 deletions
diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt
index 44c97e6accb2..15838d706ea2 100644
--- a/Documentation/filesystems/configfs/configfs.txt
+++ b/Documentation/filesystems/configfs/configfs.txt
@@ -233,10 +233,12 @@ accomplished via the group operations specified on the group's
233config_item_type. 233config_item_type.
234 234
235 struct configfs_group_operations { 235 struct configfs_group_operations {
236 struct config_item *(*make_item)(struct config_group *group, 236 int (*make_item)(struct config_group *group,
237 const char *name); 237 const char *name,
238 struct config_group *(*make_group)(struct config_group *group, 238 struct config_item **new_item);
239 const char *name); 239 int (*make_group)(struct config_group *group,
240 const char *name,
241 struct config_group **new_group);
240 int (*commit_item)(struct config_item *item); 242 int (*commit_item)(struct config_item *item);
241 void (*disconnect_notify)(struct config_group *group, 243 void (*disconnect_notify)(struct config_group *group,
242 struct config_item *item); 244 struct config_item *item);
diff --git a/Documentation/filesystems/configfs/configfs_example.c b/Documentation/filesystems/configfs/configfs_example.c
index 25151fd5c2c6..0b422acd470c 100644
--- a/Documentation/filesystems/configfs/configfs_example.c
+++ b/Documentation/filesystems/configfs/configfs_example.c
@@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite
273 return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; 273 return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
274} 274}
275 275
276static struct config_item *simple_children_make_item(struct config_group *group, const char *name) 276static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item)
277{ 277{
278 struct simple_child *simple_child; 278 struct simple_child *simple_child;
279 279
280 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); 280 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
281 if (!simple_child) 281 if (!simple_child)
282 return NULL; 282 return -ENOMEM;
283 283
284 284
285 config_item_init_type_name(&simple_child->item, name, 285 config_item_init_type_name(&simple_child->item, name,
@@ -287,7 +287,8 @@ static struct config_item *simple_children_make_item(struct config_group *group,
287 287
288 simple_child->storeme = 0; 288 simple_child->storeme = 0;
289 289
290 return &simple_child->item; 290 *new_item = &simple_child->item;
291 return 0;
291} 292}
292 293
293static struct configfs_attribute simple_children_attr_description = { 294static struct configfs_attribute simple_children_attr_description = {
@@ -359,20 +360,21 @@ static struct configfs_subsystem simple_children_subsys = {
359 * children of its own. 360 * children of its own.
360 */ 361 */
361 362
362static struct config_group *group_children_make_group(struct config_group *group, const char *name) 363static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group)
363{ 364{
364 struct simple_children *simple_children; 365 struct simple_children *simple_children;
365 366
366 simple_children = kzalloc(sizeof(struct simple_children), 367 simple_children = kzalloc(sizeof(struct simple_children),
367 GFP_KERNEL); 368 GFP_KERNEL);
368 if (!simple_children) 369 if (!simple_children)
369 return NULL; 370 return -ENOMEM;
370 371
371 372
372 config_group_init_type_name(&simple_children->group, name, 373 config_group_init_type_name(&simple_children->group, name,
373 &simple_children_type); 374 &simple_children_type);
374 375
375 return &simple_children->group; 376 *new_group = &simple_children->group;
377 return 0;
376} 378}
377 379
378static struct configfs_attribute group_children_attr_description = { 380static struct configfs_attribute group_children_attr_description = {
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 665341e43055..387a13395015 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -585,8 +585,9 @@ static struct config_item_type netconsole_target_type = {
585 * Group operations and type for netconsole_subsys. 585 * Group operations and type for netconsole_subsys.
586 */ 586 */
587 587
588static struct config_item *make_netconsole_target(struct config_group *group, 588static int make_netconsole_target(struct config_group *group,
589 const char *name) 589 const char *name,
590 struct config_item **new_item)
590{ 591{
591 unsigned long flags; 592 unsigned long flags;
592 struct netconsole_target *nt; 593 struct netconsole_target *nt;
@@ -598,7 +599,7 @@ static struct config_item *make_netconsole_target(struct config_group *group,
598 nt = kzalloc(sizeof(*nt), GFP_KERNEL); 599 nt = kzalloc(sizeof(*nt), GFP_KERNEL);
599 if (!nt) { 600 if (!nt) {
600 printk(KERN_ERR "netconsole: failed to allocate memory\n"); 601 printk(KERN_ERR "netconsole: failed to allocate memory\n");
601 return NULL; 602 return -ENOMEM;
602 } 603 }
603 604
604 nt->np.name = "netconsole"; 605 nt->np.name = "netconsole";
@@ -615,7 +616,8 @@ static struct config_item *make_netconsole_target(struct config_group *group,
615 list_add(&nt->list, &target_list); 616 list_add(&nt->list, &target_list);
616 spin_unlock_irqrestore(&target_list_lock, flags); 617 spin_unlock_irqrestore(&target_list_lock, flags);
617 618
618 return &nt->item; 619 *new_item = &nt->item;
620 return 0;
619} 621}
620 622
621static void drop_netconsole_target(struct config_group *group, 623static void drop_netconsole_target(struct config_group *group,
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 614e382a6049..0e64312a084c 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1073,25 +1073,24 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1073 group = NULL; 1073 group = NULL;
1074 item = NULL; 1074 item = NULL;
1075 if (type->ct_group_ops->make_group) { 1075 if (type->ct_group_ops->make_group) {
1076 group = type->ct_group_ops->make_group(to_config_group(parent_item), name); 1076 ret = type->ct_group_ops->make_group(to_config_group(parent_item), name, &group);
1077 if (group) { 1077 if (!ret) {
1078 link_group(to_config_group(parent_item), group); 1078 link_group(to_config_group(parent_item), group);
1079 item = &group->cg_item; 1079 item = &group->cg_item;
1080 } 1080 }
1081 } else { 1081 } else {
1082 item = type->ct_group_ops->make_item(to_config_group(parent_item), name); 1082 ret = type->ct_group_ops->make_item(to_config_group(parent_item), name, &item);
1083 if (item) 1083 if (!ret)
1084 link_obj(parent_item, item); 1084 link_obj(parent_item, item);
1085 } 1085 }
1086 mutex_unlock(&subsys->su_mutex); 1086 mutex_unlock(&subsys->su_mutex);
1087 1087
1088 kfree(name); 1088 kfree(name);
1089 if (!item) { 1089 if (ret) {
1090 /* 1090 /*
1091 * If item == NULL, then link_obj() was never called. 1091 * If ret != 0, then link_obj() was never called.
1092 * There are no extra references to clean up. 1092 * There are no extra references to clean up.
1093 */ 1093 */
1094 ret = -ENOMEM;
1095 goto out_put; 1094 goto out_put;
1096 } 1095 }
1097 1096
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index eac23bd288b2..492d8caaaf25 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -41,16 +41,20 @@ struct comm;
41struct nodes; 41struct nodes;
42struct node; 42struct node;
43 43
44static struct config_group *make_cluster(struct config_group *, const char *); 44static int make_cluster(struct config_group *, const char *,
45 struct config_group **);
45static void drop_cluster(struct config_group *, struct config_item *); 46static void drop_cluster(struct config_group *, struct config_item *);
46static void release_cluster(struct config_item *); 47static void release_cluster(struct config_item *);
47static struct config_group *make_space(struct config_group *, const char *); 48static int make_space(struct config_group *, const char *,
49 struct config_group **);
48static void drop_space(struct config_group *, struct config_item *); 50static void drop_space(struct config_group *, struct config_item *);
49static void release_space(struct config_item *); 51static void release_space(struct config_item *);
50static struct config_item *make_comm(struct config_group *, const char *); 52static int make_comm(struct config_group *, const char *,
53 struct config_item **);
51static void drop_comm(struct config_group *, struct config_item *); 54static void drop_comm(struct config_group *, struct config_item *);
52static void release_comm(struct config_item *); 55static void release_comm(struct config_item *);
53static struct config_item *make_node(struct config_group *, const char *); 56static int make_node(struct config_group *, const char *,
57 struct config_item **);
54static void drop_node(struct config_group *, struct config_item *); 58static void drop_node(struct config_group *, struct config_item *);
55static void release_node(struct config_item *); 59static void release_node(struct config_item *);
56 60
@@ -392,8 +396,8 @@ static struct node *to_node(struct config_item *i)
392 return i ? container_of(i, struct node, item) : NULL; 396 return i ? container_of(i, struct node, item) : NULL;
393} 397}
394 398
395static struct config_group *make_cluster(struct config_group *g, 399static int make_cluster(struct config_group *g, const char *name,
396 const char *name) 400 struct config_group **new_g)
397{ 401{
398 struct cluster *cl = NULL; 402 struct cluster *cl = NULL;
399 struct spaces *sps = NULL; 403 struct spaces *sps = NULL;
@@ -431,14 +435,15 @@ static struct config_group *make_cluster(struct config_group *g,
431 435
432 space_list = &sps->ss_group; 436 space_list = &sps->ss_group;
433 comm_list = &cms->cs_group; 437 comm_list = &cms->cs_group;
434 return &cl->group; 438 *new_g = &cl->group;
439 return 0;
435 440
436 fail: 441 fail:
437 kfree(cl); 442 kfree(cl);
438 kfree(gps); 443 kfree(gps);
439 kfree(sps); 444 kfree(sps);
440 kfree(cms); 445 kfree(cms);
441 return NULL; 446 return -ENOMEM;
442} 447}
443 448
444static void drop_cluster(struct config_group *g, struct config_item *i) 449static void drop_cluster(struct config_group *g, struct config_item *i)
@@ -466,7 +471,8 @@ static void release_cluster(struct config_item *i)
466 kfree(cl); 471 kfree(cl);
467} 472}
468 473
469static struct config_group *make_space(struct config_group *g, const char *name) 474static int make_space(struct config_group *g, const char *name,
475 struct config_group **new_g)
470{ 476{
471 struct space *sp = NULL; 477 struct space *sp = NULL;
472 struct nodes *nds = NULL; 478 struct nodes *nds = NULL;
@@ -489,13 +495,14 @@ static struct config_group *make_space(struct config_group *g, const char *name)
489 INIT_LIST_HEAD(&sp->members); 495 INIT_LIST_HEAD(&sp->members);
490 mutex_init(&sp->members_lock); 496 mutex_init(&sp->members_lock);
491 sp->members_count = 0; 497 sp->members_count = 0;
492 return &sp->group; 498 *new_g = &sp->group;
499 return 0;
493 500
494 fail: 501 fail:
495 kfree(sp); 502 kfree(sp);
496 kfree(gps); 503 kfree(gps);
497 kfree(nds); 504 kfree(nds);
498 return NULL; 505 return -ENOMEM;
499} 506}
500 507
501static void drop_space(struct config_group *g, struct config_item *i) 508static void drop_space(struct config_group *g, struct config_item *i)
@@ -522,19 +529,21 @@ static void release_space(struct config_item *i)
522 kfree(sp); 529 kfree(sp);
523} 530}
524 531
525static struct config_item *make_comm(struct config_group *g, const char *name) 532static int make_comm(struct config_group *g, const char *name,
533 struct config_item **new_i)
526{ 534{
527 struct comm *cm; 535 struct comm *cm;
528 536
529 cm = kzalloc(sizeof(struct comm), GFP_KERNEL); 537 cm = kzalloc(sizeof(struct comm), GFP_KERNEL);
530 if (!cm) 538 if (!cm)
531 return NULL; 539 return -ENOMEM;
532 540
533 config_item_init_type_name(&cm->item, name, &comm_type); 541 config_item_init_type_name(&cm->item, name, &comm_type);
534 cm->nodeid = -1; 542 cm->nodeid = -1;
535 cm->local = 0; 543 cm->local = 0;
536 cm->addr_count = 0; 544 cm->addr_count = 0;
537 return &cm->item; 545 *new_i = &cm->item;
546 return 0;
538} 547}
539 548
540static void drop_comm(struct config_group *g, struct config_item *i) 549static void drop_comm(struct config_group *g, struct config_item *i)
@@ -554,14 +563,15 @@ static void release_comm(struct config_item *i)
554 kfree(cm); 563 kfree(cm);
555} 564}
556 565
557static struct config_item *make_node(struct config_group *g, const char *name) 566static int make_node(struct config_group *g, const char *name,
567 struct config_item **new_i)
558{ 568{
559 struct space *sp = to_space(g->cg_item.ci_parent); 569 struct space *sp = to_space(g->cg_item.ci_parent);
560 struct node *nd; 570 struct node *nd;
561 571
562 nd = kzalloc(sizeof(struct node), GFP_KERNEL); 572 nd = kzalloc(sizeof(struct node), GFP_KERNEL);
563 if (!nd) 573 if (!nd)
564 return NULL; 574 return -ENOMEM;
565 575
566 config_item_init_type_name(&nd->item, name, &node_type); 576 config_item_init_type_name(&nd->item, name, &node_type);
567 nd->nodeid = -1; 577 nd->nodeid = -1;
@@ -573,7 +583,8 @@ static struct config_item *make_node(struct config_group *g, const char *name)
573 sp->members_count++; 583 sp->members_count++;
574 mutex_unlock(&sp->members_lock); 584 mutex_unlock(&sp->members_lock);
575 585
576 return &nd->item; 586 *new_i = &nd->item;
587 return 0;
577} 588}
578 589
579static void drop_node(struct config_group *g, struct config_item *i) 590static void drop_node(struct config_group *g, struct config_item *i)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index f02ccb34604d..443d108211ab 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1489,25 +1489,28 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group
1489 : NULL; 1489 : NULL;
1490} 1490}
1491 1491
1492static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group, 1492static int o2hb_heartbeat_group_make_item(struct config_group *group,
1493 const char *name) 1493 const char *name,
1494 struct config_item **new_item)
1494{ 1495{
1495 struct o2hb_region *reg = NULL; 1496 struct o2hb_region *reg = NULL;
1496 struct config_item *ret = NULL; 1497 int ret = 0;
1497 1498
1498 reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); 1499 reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
1499 if (reg == NULL) 1500 if (reg == NULL) {
1500 goto out; /* ENOMEM */ 1501 ret = -ENOMEM;
1502 goto out;
1503 }
1501 1504
1502 config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type); 1505 config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);
1503 1506
1504 ret = &reg->hr_item; 1507 *new_item = &reg->hr_item;
1505 1508
1506 spin_lock(&o2hb_live_lock); 1509 spin_lock(&o2hb_live_lock);
1507 list_add_tail(&reg->hr_all_item, &o2hb_all_regions); 1510 list_add_tail(&reg->hr_all_item, &o2hb_all_regions);
1508 spin_unlock(&o2hb_live_lock); 1511 spin_unlock(&o2hb_live_lock);
1509out: 1512out:
1510 if (ret == NULL) 1513 if (ret)
1511 kfree(reg); 1514 kfree(reg);
1512 1515
1513 return ret; 1516 return ret;
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index cfdb08b484ed..b364b7052e46 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -644,27 +644,32 @@ out:
644 return ret; 644 return ret;
645} 645}
646 646
647static struct config_item *o2nm_node_group_make_item(struct config_group *group, 647static int o2nm_node_group_make_item(struct config_group *group,
648 const char *name) 648 const char *name,
649 struct config_item **new_item)
649{ 650{
650 struct o2nm_node *node = NULL; 651 struct o2nm_node *node = NULL;
651 struct config_item *ret = NULL; 652 int ret = 0;
652 653
653 if (strlen(name) > O2NM_MAX_NAME_LEN) 654 if (strlen(name) > O2NM_MAX_NAME_LEN) {
654 goto out; /* ENAMETOOLONG */ 655 ret = -ENAMETOOLONG;
656 goto out;
657 }
655 658
656 node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); 659 node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
657 if (node == NULL) 660 if (node == NULL) {
658 goto out; /* ENOMEM */ 661 ret = -ENOMEM;
662 goto out;
663 }
659 664
660 strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ 665 strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
661 config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); 666 config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
662 spin_lock_init(&node->nd_lock); 667 spin_lock_init(&node->nd_lock);
663 668
664 ret = &node->nd_item; 669 *new_item = &node->nd_item;
665 670
666out: 671out:
667 if (ret == NULL) 672 if (ret)
668 kfree(node); 673 kfree(node);
669 674
670 return ret; 675 return ret;
@@ -751,25 +756,31 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro
751} 756}
752#endif 757#endif
753 758
754static struct config_group *o2nm_cluster_group_make_group(struct config_group *group, 759static int o2nm_cluster_group_make_group(struct config_group *group,
755 const char *name) 760 const char *name,
761 struct config_group **new_group)
756{ 762{
757 struct o2nm_cluster *cluster = NULL; 763 struct o2nm_cluster *cluster = NULL;
758 struct o2nm_node_group *ns = NULL; 764 struct o2nm_node_group *ns = NULL;
759 struct config_group *o2hb_group = NULL, *ret = NULL; 765 struct config_group *o2hb_group = NULL;
760 void *defs = NULL; 766 void *defs = NULL;
767 int ret = 0;
761 768
762 /* this runs under the parent dir's i_mutex; there can be only 769 /* this runs under the parent dir's i_mutex; there can be only
763 * one caller in here at a time */ 770 * one caller in here at a time */
764 if (o2nm_single_cluster) 771 if (o2nm_single_cluster) {
765 goto out; /* ENOSPC */ 772 ret = -ENOSPC;
773 goto out;
774 }
766 775
767 cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); 776 cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
768 ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); 777 ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
769 defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); 778 defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
770 o2hb_group = o2hb_alloc_hb_set(); 779 o2hb_group = o2hb_alloc_hb_set();
771 if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) 780 if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) {
781 ret = -ENOMEM;
772 goto out; 782 goto out;
783 }
773 784
774 config_group_init_type_name(&cluster->cl_group, name, 785 config_group_init_type_name(&cluster->cl_group, name,
775 &o2nm_cluster_type); 786 &o2nm_cluster_type);
@@ -786,11 +797,11 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
786 cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; 797 cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
787 cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; 798 cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
788 799
789 ret = &cluster->cl_group; 800 *new_group = &cluster->cl_group;
790 o2nm_single_cluster = cluster; 801 o2nm_single_cluster = cluster;
791 802
792out: 803out:
793 if (ret == NULL) { 804 if (ret) {
794 kfree(cluster); 805 kfree(cluster);
795 kfree(ns); 806 kfree(ns);
796 o2hb_free_hb_set(o2hb_group); 807 o2hb_free_hb_set(o2hb_group);
diff --git a/include/linux/configfs.h b/include/linux/configfs.h
index 3ae65b1bf90f..0488f937634a 100644
--- a/include/linux/configfs.h
+++ b/include/linux/configfs.h
@@ -165,8 +165,8 @@ struct configfs_item_operations {
165}; 165};
166 166
167struct configfs_group_operations { 167struct configfs_group_operations {
168 struct config_item *(*make_item)(struct config_group *group, const char *name); 168 int (*make_item)(struct config_group *group, const char *name, struct config_item **new_item);
169 struct config_group *(*make_group)(struct config_group *group, const char *name); 169 int (*make_group)(struct config_group *group, const char *name, struct config_group **new_group);
170 int (*commit_item)(struct config_item *item); 170 int (*commit_item)(struct config_item *item);
171 void (*disconnect_notify)(struct config_group *group, struct config_item *item); 171 void (*disconnect_notify)(struct config_group *group, struct config_item *item);
172 void (*drop_item)(struct config_group *group, struct config_item *item); 172 void (*drop_item)(struct config_group *group, struct config_item *item);