Lines Matching +full:group +full:- +full:default
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * dir.c - Operations for configfs directories.
39 * subsys->su_mutex is held.
48 struct configfs_dirent *sd = dentry->d_fsdata; in configfs_d_iput()
54 * Set sd->s_dentry to null only when this dentry is the one in configfs_d_iput()
56 * run just after configfs_lookup and set sd->s_dentry to in configfs_d_iput()
59 if (sd->s_dentry == dentry) in configfs_d_iput()
60 sd->s_dentry = NULL; in configfs_d_iput()
75 * Helpers to make lockdep happy with our recursive locking of default groups'
77 * We put default groups i_mutexes in separate classes according to their depth
78 * from the youngest non-default group ancestor.
80 * For a non-default group A having default groups A/B, A/C, and A/C/D, default
82 * default_group_class[0], and default group A/C/D will be in
87 * The s_depth value is initialized to -1, adjusted to >= 0 when attaching
88 * default groups, and reset to -1 when all default groups are attached. During
90 * inode's mutex is set to default_group_class[s_depth - 1].
95 sd->s_depth = -1; in configfs_init_dirent_depth()
101 int parent_depth = parent_sd->s_depth; in configfs_set_dir_dirent_depth()
104 sd->s_depth = parent_depth + 1; in configfs_set_dir_dirent_depth()
112 * used to set new sub-directories s_depth, which is always done in configfs_adjust_dir_dirent_depth_before_populate()
116 * sd->s_depth == -1 iff we are a non default group. in configfs_adjust_dir_dirent_depth_before_populate()
117 * else (we are a default group) sd->s_depth > 0 (see in configfs_adjust_dir_dirent_depth_before_populate()
120 if (sd->s_depth == -1) in configfs_adjust_dir_dirent_depth_before_populate()
122 * We are a non default group and we are going to create in configfs_adjust_dir_dirent_depth_before_populate()
123 * default groups. in configfs_adjust_dir_dirent_depth_before_populate()
125 sd->s_depth = 0; in configfs_adjust_dir_dirent_depth_before_populate()
131 /* We will not create default groups anymore. */ in configfs_adjust_dir_dirent_depth_after_populate()
132 sd->s_depth = -1; in configfs_adjust_dir_dirent_depth_after_populate()
164 atomic_set(&p->frag_count, 1); in new_fragment()
165 init_rwsem(&p->frag_sem); in new_fragment()
166 p->frag_dead = false; in new_fragment()
173 if (frag && atomic_dec_and_test(&frag->frag_count)) in put_fragment()
180 atomic_inc(&frag->frag_count); in get_fragment()
195 return ERR_PTR(-ENOMEM); in configfs_new_dirent()
197 atomic_set(&sd->s_count, 1); in configfs_new_dirent()
198 INIT_LIST_HEAD(&sd->s_children); in configfs_new_dirent()
199 sd->s_element = element; in configfs_new_dirent()
200 sd->s_type = type; in configfs_new_dirent()
203 if (parent_sd->s_type & CONFIGFS_USET_DROPPING) { in configfs_new_dirent()
206 return ERR_PTR(-ENOENT); in configfs_new_dirent()
208 sd->s_frag = get_fragment(frag); in configfs_new_dirent()
216 if (sd->s_type & CONFIGFS_PINNED) in configfs_new_dirent()
217 list_add_tail(&sd->s_sibling, &parent_sd->s_children); in configfs_new_dirent()
219 list_add(&sd->s_sibling, &parent_sd->s_children); in configfs_new_dirent()
227 * Return -EEXIST if there is already a configfs element with the same
234 struct configfs_dirent *parent_sd = dentry->d_parent->d_fsdata; in configfs_dirent_exists()
235 const unsigned char *new = dentry->d_name.name; in configfs_dirent_exists()
238 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { in configfs_dirent_exists()
239 if (sd->s_element) { in configfs_dirent_exists()
244 return -EEXIST; in configfs_dirent_exists()
262 sd->s_mode = mode; in configfs_make_dirent()
263 sd->s_dentry = dentry; in configfs_make_dirent()
265 dentry->d_fsdata = configfs_get(sd); in configfs_make_dirent()
272 struct configfs_dirent *sd = dentry->d_fsdata; in configfs_remove_dirent()
277 list_del_init(&sd->s_sibling); in configfs_remove_dirent()
283 * configfs_create_dir - create a directory for an config_item.
288 * Note: user-created entries won't be allowed under this new directory
297 struct dentry *p = dentry->d_parent; in configfs_create_dir()
302 error = configfs_make_dirent(p->d_fsdata, dentry, item, mode, in configfs_create_dir()
308 configfs_set_dir_dirent_depth(p->d_fsdata, dentry->d_fsdata); in configfs_create_dir()
313 inode->i_op = &configfs_dir_inode_operations; in configfs_create_dir()
314 inode->i_fop = &configfs_dir_operations; in configfs_create_dir()
321 item->ci_dentry = dentry; in configfs_create_dir()
325 configfs_put(dentry->d_fsdata); in configfs_create_dir()
341 sd->s_type &= ~CONFIGFS_USET_CREATING; in configfs_dir_set_ready()
342 list_for_each_entry(child_sd, &sd->s_children, s_sibling) in configfs_dir_set_ready()
343 if (child_sd->s_type & CONFIGFS_USET_CREATING) in configfs_dir_set_ready()
352 * @return non-zero iff the directory was validated
362 ret = !(sd->s_type & CONFIGFS_USET_CREATING); in configfs_dirent_is_ready()
373 struct configfs_dirent *p = parent->d_fsdata; in configfs_create_link()
377 p->s_frag); in configfs_create_link()
385 inode->i_link = body; in configfs_create_link()
386 inode->i_op = &configfs_symlink_inode_operations; in configfs_create_link()
392 configfs_put(dentry->d_fsdata); in configfs_create_link()
399 struct dentry * parent = dget(d->d_parent); in remove_dir()
412 * configfs_remove_dir - remove an config_item's directory.
424 struct dentry * dentry = dget(item->ci_dentry); in configfs_remove_dir()
440 struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata; in configfs_lookup()
444 if (dentry->d_name.len > NAME_MAX) in configfs_lookup()
445 return ERR_PTR(-ENAMETOOLONG); in configfs_lookup()
448 * Fake invisibility if dir belongs to a group/default groups hierarchy in configfs_lookup()
456 return ERR_PTR(-ENOENT); in configfs_lookup()
459 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { in configfs_lookup()
465 if (sd->s_type & CONFIGFS_PINNED) in configfs_lookup()
472 if ((sd->s_type & CONFIGFS_NOT_PINNED) && in configfs_lookup()
473 !strcmp(configfs_get_name(sd), dentry->d_name.name)) { in configfs_lookup()
474 struct configfs_attribute *attr = sd->s_element; in configfs_lookup()
475 umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; in configfs_lookup()
477 dentry->d_fsdata = configfs_get(sd); in configfs_lookup()
478 sd->s_dentry = dentry; in configfs_lookup()
486 if (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) { in configfs_lookup()
487 inode->i_size = 0; in configfs_lookup()
488 inode->i_fop = &configfs_bin_file_operations; in configfs_lookup()
490 inode->i_size = PAGE_SIZE; in configfs_lookup()
491 inode->i_fop = &configfs_file_operations; in configfs_lookup()
506 * default detach.
512 struct configfs_dirent *parent_sd = dentry->d_fsdata; in configfs_detach_prep()
516 /* Mark that we're trying to drop the group */ in configfs_detach_prep()
517 parent_sd->s_type |= CONFIGFS_USET_DROPPING; in configfs_detach_prep()
519 ret = -EBUSY; in configfs_detach_prep()
520 if (parent_sd->s_links) in configfs_detach_prep()
524 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { in configfs_detach_prep()
525 if (!sd->s_element || in configfs_detach_prep()
526 (sd->s_type & CONFIGFS_NOT_PINNED)) in configfs_detach_prep()
528 if (sd->s_type & CONFIGFS_USET_DEFAULT) { in configfs_detach_prep()
530 if (sd->s_type & CONFIGFS_USET_IN_MKDIR) { in configfs_detach_prep()
532 *wait= dget(sd->s_dentry); in configfs_detach_prep()
533 return -EAGAIN; in configfs_detach_prep()
540 ret = configfs_detach_prep(sd->s_dentry, wait); in configfs_detach_prep()
544 ret = -ENOTEMPTY; in configfs_detach_prep()
559 struct configfs_dirent *parent_sd = dentry->d_fsdata; in configfs_detach_rollback()
562 parent_sd->s_type &= ~CONFIGFS_USET_DROPPING; in configfs_detach_rollback()
564 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) in configfs_detach_rollback()
565 if (sd->s_type & CONFIGFS_USET_DEFAULT) in configfs_detach_rollback()
566 configfs_detach_rollback(sd->s_dentry); in configfs_detach_rollback()
571 struct dentry * dentry = dget(item->ci_dentry); in detach_attrs()
579 dentry->d_name.name); in detach_attrs()
581 parent_sd = dentry->d_fsdata; in detach_attrs()
582 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { in detach_attrs()
583 if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED)) in detach_attrs()
586 list_del_init(&sd->s_sibling); in detach_attrs()
600 const struct config_item_type *t = item->ci_type; in populate_attrs()
608 return -EINVAL; in populate_attrs()
610 ops = t->ct_group_ops; in populate_attrs()
612 if (t->ct_attrs) { in populate_attrs()
613 for (i = 0; (attr = t->ct_attrs[i]) != NULL; i++) { in populate_attrs()
614 if (ops && ops->is_visible && !ops->is_visible(item, attr, i)) in populate_attrs()
621 if (!error && t->ct_bin_attrs) { in populate_attrs()
622 for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) { in populate_attrs()
623 if (ops && ops->is_bin_visible && !ops->is_bin_visible(item, bin_attr, i)) in populate_attrs()
644 static void detach_groups(struct config_group *group) in detach_groups() argument
646 struct dentry * dentry = dget(group->cg_item.ci_dentry); in detach_groups()
654 parent_sd = dentry->d_fsdata; in detach_groups()
655 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { in detach_groups()
656 if (!sd->s_element || in detach_groups()
657 !(sd->s_type & CONFIGFS_USET_DEFAULT)) in detach_groups()
660 child = sd->s_dentry; in detach_groups()
664 configfs_detach_group(sd->s_element); in detach_groups()
665 d_inode(child)->i_flags |= S_DEAD; in detach_groups()
683 * on the sd->s_type.
685 * We could, perhaps, tweak our parent's ->mkdir for a minute and
689 struct config_group *group, in create_default_group() argument
695 struct dentry *child, *parent = parent_group->cg_item.ci_dentry; in create_default_group()
697 if (!group->cg_item.ci_name) in create_default_group()
698 group->cg_item.ci_name = group->cg_item.ci_namebuf; in create_default_group()
700 ret = -ENOMEM; in create_default_group()
701 child = d_alloc_name(parent, group->cg_item.ci_name); in create_default_group()
705 ret = configfs_attach_group(&parent_group->cg_item, in create_default_group()
706 &group->cg_item, child, frag); in create_default_group()
708 sd = child->d_fsdata; in create_default_group()
709 sd->s_type |= CONFIGFS_USET_DEFAULT; in create_default_group()
720 static int populate_groups(struct config_group *group, in populate_groups() argument
726 list_for_each_entry(new_group, &group->default_groups, group_entry) { in populate_groups()
727 ret = create_default_group(group, new_group, frag); in populate_groups()
729 detach_groups(group); in populate_groups()
737 void configfs_remove_default_groups(struct config_group *group) in configfs_remove_default_groups() argument
741 list_for_each_entry_safe(g, n, &group->default_groups, group_entry) { in configfs_remove_default_groups()
742 list_del(&g->group_entry); in configfs_remove_default_groups()
743 config_item_put(&g->cg_item); in configfs_remove_default_groups()
750 * subsys->su_mutex is held.
755 struct config_group *group; in unlink_obj() local
757 group = item->ci_group; in unlink_obj()
758 if (group) { in unlink_obj()
759 list_del_init(&item->ci_entry); in unlink_obj()
761 item->ci_group = NULL; in unlink_obj()
762 item->ci_parent = NULL; in unlink_obj()
768 config_group_put(group); in unlink_obj()
775 * Parent seems redundant with group, but it makes certain in link_obj()
778 item->ci_parent = parent_item; in link_obj()
784 item->ci_group = config_group_get(to_config_group(parent_item)); in link_obj()
785 list_add_tail(&item->ci_entry, &item->ci_group->cg_children); in link_obj()
794 static void unlink_group(struct config_group *group) in unlink_group() argument
798 list_for_each_entry(new_group, &group->default_groups, group_entry) in unlink_group()
801 group->cg_subsys = NULL; in unlink_group()
802 unlink_obj(&group->cg_item); in unlink_group()
805 static void link_group(struct config_group *parent_group, struct config_group *group) in link_group() argument
810 link_obj(&parent_group->cg_item, &group->cg_item); in link_group()
812 if (parent_group->cg_subsys) in link_group()
813 subsys = parent_group->cg_subsys; in link_group()
814 else if (configfs_is_root(&parent_group->cg_item)) in link_group()
815 subsys = to_configfs_subsystem(group); in link_group()
818 group->cg_subsys = subsys; in link_group()
820 list_for_each_entry(new_group, &group->default_groups, group_entry) in link_group()
821 link_group(group, new_group); in link_group()
857 d_inode(dentry)->i_flags |= S_DEAD; in configfs_attach_item()
884 sd = dentry->d_fsdata; in configfs_attach_group()
885 sd->s_type |= CONFIGFS_USET_DIR; in configfs_attach_group()
889 * We must lock the group's inode to avoid races with the VFS in configfs_attach_group()
901 d_inode(dentry)->i_flags |= S_DEAD; in configfs_attach_group()
913 /* Caller holds the mutex of the group's inode */
934 type = parent_item->ci_type; in client_disconnect_notify()
937 if (type->ct_group_ops && type->ct_group_ops->disconnect_notify) in client_disconnect_notify()
938 type->ct_group_ops->disconnect_notify(to_config_group(parent_item), in client_disconnect_notify()
953 type = parent_item->ci_type; in client_drop_item()
957 * If ->drop_item() exists, it is responsible for the in client_drop_item()
960 if (type->ct_group_ops && type->ct_group_ops->drop_item) in client_drop_item()
961 type->ct_group_ops->drop_item(to_config_group(parent_item), in client_drop_item()
972 #define type_print(_type) if (sd->s_type & _type) pr_info("%*s %s\n", level, " ", #_type) in configfs_dump_one()
990 if (!(sd->s_type & (CONFIGFS_DIR|CONFIGFS_ROOT))) in configfs_dump()
993 list_for_each_entry(child_sd, &sd->s_children, s_sibling) { in configfs_dump()
1020 * VFS->configfs path. So it must take VFS locks to prevent the
1021 * VFS->configfs stuff (configfs_mkdir(), configfs_rmdir(), etc). This is
1043 * Here we do a depth-first search of the dentry hierarchy looking for
1054 * If the target is not found, -ENOENT is bubbled up.
1059 * much on the stack, though, so folks that need this function - be careful
1068 BUG_ON(!origin || !origin->d_fsdata); in configfs_depend_prep()
1069 sd = origin->d_fsdata; in configfs_depend_prep()
1071 if (sd->s_element == target) /* Boo-yah */ in configfs_depend_prep()
1074 list_for_each_entry(child_sd, &sd->s_children, s_sibling) { in configfs_depend_prep()
1075 if ((child_sd->s_type & CONFIGFS_DIR) && in configfs_depend_prep()
1076 !(child_sd->s_type & CONFIGFS_USET_DROPPING) && in configfs_depend_prep()
1077 !(child_sd->s_type & CONFIGFS_USET_CREATING)) { in configfs_depend_prep()
1078 ret = configfs_depend_prep(child_sd->s_dentry, in configfs_depend_prep()
1081 goto out; /* Child path boo-yah */ in configfs_depend_prep()
1086 ret = -ENOENT; in configfs_depend_prep()
1108 p = target->ci_dentry->d_fsdata; in configfs_do_depend_item()
1109 p->s_dependent_count += 1; in configfs_do_depend_item()
1124 list_for_each_entry(p, &root_sd->s_children, s_sibling) { in configfs_find_subsys_dentry()
1125 if (p->s_type & CONFIGFS_DIR && in configfs_find_subsys_dentry()
1126 p->s_element == subsys_item) { in configfs_find_subsys_dentry()
1141 struct config_item *s_item = &subsys->su_group.cg_item; in configfs_depend_item()
1159 subsys_sd = configfs_find_subsys_dentry(root->d_fsdata, s_item); in configfs_depend_item()
1161 ret = -ENOENT; in configfs_depend_item()
1166 ret = configfs_do_depend_item(subsys_sd->s_dentry, target); in configfs_depend_item()
1196 sd = target->ci_dentry->d_fsdata; in configfs_undepend_item()
1197 BUG_ON(sd->s_dependent_count < 1); in configfs_undepend_item()
1199 sd->s_dependent_count -= 1; in configfs_undepend_item()
1224 int ret = -ENOENT; in configfs_depend_item_unlocked()
1228 return -EINVAL; in configfs_depend_item_unlocked()
1230 parent = target->ci_group; in configfs_depend_item_unlocked()
1235 if (configfs_is_root(&parent->cg_item)) { in configfs_depend_item_unlocked()
1239 target_subsys = parent->cg_subsys; in configfs_depend_item_unlocked()
1241 for (root = parent; !configfs_is_root(&root->cg_item); in configfs_depend_item_unlocked()
1242 root = root->cg_item.ci_group) in configfs_depend_item_unlocked()
1252 inode_lock(d_inode(root->cg_item.ci_dentry)); in configfs_depend_item_unlocked()
1259 root->cg_item.ci_dentry->d_fsdata, in configfs_depend_item_unlocked()
1260 &target_subsys->su_group.cg_item); in configfs_depend_item_unlocked()
1264 subsys_sd = target_subsys->su_group.cg_item.ci_dentry->d_fsdata; in configfs_depend_item_unlocked()
1268 ret = configfs_do_depend_item(subsys_sd->s_dentry, target); in configfs_depend_item_unlocked()
1276 inode_unlock(d_inode(root->cg_item.ci_dentry)); in configfs_depend_item_unlocked()
1287 struct config_group *group = NULL; in configfs_mkdir() local
1297 sd = dentry->d_parent->d_fsdata; in configfs_mkdir()
1300 * Fake invisibility if dir belongs to a group/default groups hierarchy in configfs_mkdir()
1304 ret = -ENOENT; in configfs_mkdir()
1308 if (!(sd->s_type & CONFIGFS_USET_DIR)) { in configfs_mkdir()
1309 ret = -EPERM; in configfs_mkdir()
1315 ret = -ENOMEM; in configfs_mkdir()
1320 parent_item = configfs_get_config_item(dentry->d_parent); in configfs_mkdir()
1321 type = parent_item->ci_type; in configfs_mkdir()
1322 subsys = to_config_group(parent_item)->cg_subsys; in configfs_mkdir()
1325 if (!type || !type->ct_group_ops || in configfs_mkdir()
1326 (!type->ct_group_ops->make_group && in configfs_mkdir()
1327 !type->ct_group_ops->make_item)) { in configfs_mkdir()
1328 ret = -EPERM; /* Lack-of-mkdir returns -EPERM */ in configfs_mkdir()
1337 if (!subsys->su_group.cg_item.ci_type) { in configfs_mkdir()
1338 ret = -EINVAL; in configfs_mkdir()
1341 subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner; in configfs_mkdir()
1343 ret = -EINVAL; in configfs_mkdir()
1347 name = kmalloc(dentry->d_name.len + 1, GFP_KERNEL); in configfs_mkdir()
1349 ret = -ENOMEM; in configfs_mkdir()
1353 snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name); in configfs_mkdir()
1355 mutex_lock(&subsys->su_mutex); in configfs_mkdir()
1356 if (type->ct_group_ops->make_group) { in configfs_mkdir()
1357 group = type->ct_group_ops->make_group(to_config_group(parent_item), name); in configfs_mkdir()
1358 if (!group) in configfs_mkdir()
1359 group = ERR_PTR(-ENOMEM); in configfs_mkdir()
1360 if (!IS_ERR(group)) { in configfs_mkdir()
1361 link_group(to_config_group(parent_item), group); in configfs_mkdir()
1362 item = &group->cg_item; in configfs_mkdir()
1364 ret = PTR_ERR(group); in configfs_mkdir()
1366 item = type->ct_group_ops->make_item(to_config_group(parent_item), name); in configfs_mkdir()
1368 item = ERR_PTR(-ENOMEM); in configfs_mkdir()
1374 mutex_unlock(&subsys->su_mutex); in configfs_mkdir()
1390 type = item->ci_type; in configfs_mkdir()
1392 ret = -EINVAL; in configfs_mkdir()
1396 new_item_owner = type->ct_owner; in configfs_mkdir()
1398 ret = -EINVAL; in configfs_mkdir()
1417 sd->s_type |= CONFIGFS_USET_IN_MKDIR; in configfs_mkdir()
1420 if (group) in configfs_mkdir()
1426 sd->s_type &= ~CONFIGFS_USET_IN_MKDIR; in configfs_mkdir()
1428 configfs_dir_set_ready(dentry->d_fsdata); in configfs_mkdir()
1434 mutex_lock(&subsys->su_mutex); in configfs_mkdir()
1437 if (group) in configfs_mkdir()
1438 unlink_group(group); in configfs_mkdir()
1443 mutex_unlock(&subsys->su_mutex); in configfs_mkdir()
1455 * link_obj()/link_group() took a reference from child->parent, in configfs_mkdir()
1476 sd = dentry->d_fsdata; in configfs_rmdir()
1477 if (sd->s_type & CONFIGFS_USET_DEFAULT) in configfs_rmdir()
1478 return -EPERM; in configfs_rmdir()
1481 parent_item = configfs_get_config_item(dentry->d_parent); in configfs_rmdir()
1482 subsys = to_config_group(parent_item)->cg_subsys; in configfs_rmdir()
1485 if (!parent_item->ci_type) { in configfs_rmdir()
1487 return -EINVAL; in configfs_rmdir()
1491 BUG_ON(!subsys->su_group.cg_item.ci_type); in configfs_rmdir()
1492 subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner; in configfs_rmdir()
1508 ret = sd->s_dependent_count ? -EBUSY : 0; in configfs_rmdir()
1518 if (ret != -EAGAIN) { in configfs_rmdir()
1528 } while (ret == -EAGAIN); in configfs_rmdir()
1530 frag = sd->s_frag; in configfs_rmdir()
1531 if (down_write_killable(&frag->frag_sem)) { in configfs_rmdir()
1536 return -EINTR; in configfs_rmdir()
1538 frag->frag_dead = true; in configfs_rmdir()
1539 up_write(&frag->frag_sem); in configfs_rmdir()
1547 if (item->ci_type) in configfs_rmdir()
1548 dead_item_owner = item->ci_type->ct_owner; in configfs_rmdir()
1550 if (sd->s_type & CONFIGFS_USET_DIR) { in configfs_rmdir()
1553 mutex_lock(&subsys->su_mutex); in configfs_rmdir()
1559 mutex_lock(&subsys->su_mutex); in configfs_rmdir()
1565 mutex_unlock(&subsys->su_mutex); in configfs_rmdir()
1592 struct dentry * dentry = file->f_path.dentry; in configfs_dir_open()
1593 struct configfs_dirent * parent_sd = dentry->d_fsdata; in configfs_dir_open()
1598 * Fake invisibility if dir belongs to a group/default groups hierarchy in configfs_dir_open()
1601 err = -ENOENT; in configfs_dir_open()
1603 file->private_data = configfs_new_dirent(parent_sd, NULL, 0, NULL); in configfs_dir_open()
1604 err = PTR_ERR_OR_ZERO(file->private_data); in configfs_dir_open()
1613 struct dentry * dentry = file->f_path.dentry; in configfs_dir_close()
1614 struct configfs_dirent * cursor = file->private_data; in configfs_dir_close()
1618 list_del_init(&cursor->s_sibling); in configfs_dir_close()
1629 struct dentry *dentry = file->f_path.dentry; in configfs_readdir()
1630 struct super_block *sb = dentry->d_sb; in configfs_readdir()
1631 struct configfs_dirent * parent_sd = dentry->d_fsdata; in configfs_readdir()
1632 struct configfs_dirent *cursor = file->private_data; in configfs_readdir()
1633 struct list_head *p, *q = &cursor->s_sibling; in configfs_readdir()
1639 if (ctx->pos == 2) in configfs_readdir()
1640 list_move(q, &parent_sd->s_children); in configfs_readdir()
1641 for (p = q->next; p != &parent_sd->s_children; p = p->next) { in configfs_readdir()
1648 if (!next->s_element) in configfs_readdir()
1664 dentry = next->s_dentry; in configfs_readdir()
1668 ino = inode->i_ino; in configfs_readdir()
1677 fs_umode_to_dtype(next->s_mode))) in configfs_readdir()
1683 ctx->pos++; in configfs_readdir()
1691 struct dentry * dentry = file->f_path.dentry; in configfs_dir_lseek()
1695 offset += file->f_pos; in configfs_dir_lseek()
1701 default: in configfs_dir_lseek()
1702 return -EINVAL; in configfs_dir_lseek()
1704 if (offset != file->f_pos) { in configfs_dir_lseek()
1705 file->f_pos = offset; in configfs_dir_lseek()
1706 if (file->f_pos >= 2) { in configfs_dir_lseek()
1707 struct configfs_dirent *sd = dentry->d_fsdata; in configfs_dir_lseek()
1708 struct configfs_dirent *cursor = file->private_data; in configfs_dir_lseek()
1710 loff_t n = file->f_pos - 2; in configfs_dir_lseek()
1713 list_del(&cursor->s_sibling); in configfs_dir_lseek()
1714 p = sd->s_children.next; in configfs_dir_lseek()
1715 while (n && p != &sd->s_children) { in configfs_dir_lseek()
1719 if (next->s_element) in configfs_dir_lseek()
1720 n--; in configfs_dir_lseek()
1721 p = p->next; in configfs_dir_lseek()
1723 list_add_tail(&cursor->s_sibling, p); in configfs_dir_lseek()
1739 * configfs_register_group - creates a parent-child relation between two groups
1740 * @parent_group: parent group
1741 * @group: child group
1749 struct config_group *group) in configfs_register_group() argument
1751 struct configfs_subsystem *subsys = parent_group->cg_subsys; in configfs_register_group()
1758 return -ENOMEM; in configfs_register_group()
1760 mutex_lock(&subsys->su_mutex); in configfs_register_group()
1761 link_group(parent_group, group); in configfs_register_group()
1762 mutex_unlock(&subsys->su_mutex); in configfs_register_group()
1764 parent = parent_group->cg_item.ci_dentry; in configfs_register_group()
1767 ret = create_default_group(parent_group, group, frag); in configfs_register_group()
1772 configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata); in configfs_register_group()
1779 mutex_lock(&subsys->su_mutex); in configfs_register_group()
1780 unlink_group(group); in configfs_register_group()
1781 mutex_unlock(&subsys->su_mutex); in configfs_register_group()
1788 * configfs_unregister_group() - unregisters a child group from its parent
1789 * @group: parent group to be unregistered
1793 void configfs_unregister_group(struct config_group *group) in configfs_unregister_group() argument
1795 struct configfs_subsystem *subsys = group->cg_subsys; in configfs_unregister_group()
1796 struct dentry *dentry = group->cg_item.ci_dentry; in configfs_unregister_group()
1797 struct dentry *parent = group->cg_item.ci_parent->ci_dentry; in configfs_unregister_group()
1798 struct configfs_dirent *sd = dentry->d_fsdata; in configfs_unregister_group()
1799 struct configfs_fragment *frag = sd->s_frag; in configfs_unregister_group()
1801 down_write(&frag->frag_sem); in configfs_unregister_group()
1802 frag->frag_dead = true; in configfs_unregister_group()
1803 up_write(&frag->frag_sem); in configfs_unregister_group()
1810 configfs_detach_group(&group->cg_item); in configfs_unregister_group()
1811 d_inode(dentry)->i_flags |= S_DEAD; in configfs_unregister_group()
1819 mutex_lock(&subsys->su_mutex); in configfs_unregister_group()
1820 unlink_group(group); in configfs_unregister_group()
1821 mutex_unlock(&subsys->su_mutex); in configfs_unregister_group()
1826 * configfs_register_default_group() - allocates and registers a child group
1827 * @parent_group: parent group
1828 * @name: child group name
1831 * boilerplate to allocate and register a child group with its parent. We need
1834 * Return: allocated config group or ERR_PTR() on error
1842 struct config_group *group; in configfs_register_default_group() local
1844 group = kzalloc(sizeof(*group), GFP_KERNEL); in configfs_register_default_group()
1845 if (!group) in configfs_register_default_group()
1846 return ERR_PTR(-ENOMEM); in configfs_register_default_group()
1847 config_group_init_type_name(group, name, item_type); in configfs_register_default_group()
1849 ret = configfs_register_group(parent_group, group); in configfs_register_default_group()
1851 kfree(group); in configfs_register_default_group()
1854 return group; in configfs_register_default_group()
1859 * configfs_unregister_default_group() - unregisters and frees a child group
1860 * @group: the group to act on
1862 void configfs_unregister_default_group(struct config_group *group) in configfs_unregister_default_group() argument
1864 configfs_unregister_group(group); in configfs_unregister_default_group()
1865 kfree(group); in configfs_unregister_default_group()
1872 struct config_group *group = &subsys->su_group; in configfs_register_subsystem() local
1880 return -ENOMEM; in configfs_register_subsystem()
1888 if (!group->cg_item.ci_name) in configfs_register_subsystem()
1889 group->cg_item.ci_name = group->cg_item.ci_namebuf; in configfs_register_subsystem()
1891 sd = root->d_fsdata; in configfs_register_subsystem()
1893 link_group(to_config_group(sd->s_element), group); in configfs_register_subsystem()
1898 err = -ENOMEM; in configfs_register_subsystem()
1899 dentry = d_alloc_name(root, group->cg_item.ci_name); in configfs_register_subsystem()
1905 err = configfs_attach_group(sd->s_element, in configfs_register_subsystem()
1906 &group->cg_item, in configfs_register_subsystem()
1914 configfs_dir_set_ready(dentry->d_fsdata); in configfs_register_subsystem()
1923 unlink_group(group); in configfs_register_subsystem()
1934 struct config_group *group = &subsys->su_group; in configfs_unregister_subsystem() local
1935 struct dentry *dentry = group->cg_item.ci_dentry; in configfs_unregister_subsystem()
1936 struct dentry *root = dentry->d_sb->s_root; in configfs_unregister_subsystem()
1937 struct configfs_dirent *sd = dentry->d_fsdata; in configfs_unregister_subsystem()
1938 struct configfs_fragment *frag = sd->s_frag; in configfs_unregister_subsystem()
1940 if (dentry->d_parent != root) { in configfs_unregister_subsystem()
1941 pr_err("Tried to unregister non-subsystem!\n"); in configfs_unregister_subsystem()
1945 down_write(&frag->frag_sem); in configfs_unregister_subsystem()
1946 frag->frag_dead = true; in configfs_unregister_subsystem()
1947 up_write(&frag->frag_sem); in configfs_unregister_subsystem()
1955 pr_err("Tried to unregister non-empty subsystem!\n"); in configfs_unregister_subsystem()
1959 configfs_detach_group(&group->cg_item); in configfs_unregister_subsystem()
1960 d_inode(dentry)->i_flags |= S_DEAD; in configfs_unregister_subsystem()
1972 unlink_group(group); in configfs_unregister_subsystem()