diff options
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r-- | fs/configfs/dir.c | 289 |
1 files changed, 280 insertions, 9 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 5e6e37e58f36..2f436d4f1d6d 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -355,6 +355,10 @@ static int configfs_detach_prep(struct dentry *dentry) | |||
355 | /* Mark that we've taken i_mutex */ | 355 | /* Mark that we've taken i_mutex */ |
356 | sd->s_type |= CONFIGFS_USET_DROPPING; | 356 | sd->s_type |= CONFIGFS_USET_DROPPING; |
357 | 357 | ||
358 | /* | ||
359 | * Yup, recursive. If there's a problem, blame | ||
360 | * deep nesting of default_groups | ||
361 | */ | ||
358 | ret = configfs_detach_prep(sd->s_dentry); | 362 | ret = configfs_detach_prep(sd->s_dentry); |
359 | if (!ret) | 363 | if (!ret) |
360 | continue; | 364 | continue; |
@@ -562,7 +566,7 @@ static int populate_groups(struct config_group *group) | |||
562 | 566 | ||
563 | /* | 567 | /* |
564 | * All of link_obj/unlink_obj/link_group/unlink_group require that | 568 | * All of link_obj/unlink_obj/link_group/unlink_group require that |
565 | * subsys->su_sem is held. | 569 | * subsys->su_mutex is held. |
566 | */ | 570 | */ |
567 | 571 | ||
568 | static void unlink_obj(struct config_item *item) | 572 | static void unlink_obj(struct config_item *item) |
@@ -714,6 +718,28 @@ static void configfs_detach_group(struct config_item *item) | |||
714 | } | 718 | } |
715 | 719 | ||
716 | /* | 720 | /* |
721 | * After the item has been detached from the filesystem view, we are | ||
722 | * ready to tear it out of the hierarchy. Notify the client before | ||
723 | * we do that so they can perform any cleanup that requires | ||
724 | * navigating the hierarchy. A client does not need to provide this | ||
725 | * callback. The subsystem semaphore MUST be held by the caller, and | ||
726 | * references must be valid for both items. It also assumes the | ||
727 | * caller has validated ci_type. | ||
728 | */ | ||
729 | static void client_disconnect_notify(struct config_item *parent_item, | ||
730 | struct config_item *item) | ||
731 | { | ||
732 | struct config_item_type *type; | ||
733 | |||
734 | type = parent_item->ci_type; | ||
735 | BUG_ON(!type); | ||
736 | |||
737 | if (type->ct_group_ops && type->ct_group_ops->disconnect_notify) | ||
738 | type->ct_group_ops->disconnect_notify(to_config_group(parent_item), | ||
739 | item); | ||
740 | } | ||
741 | |||
742 | /* | ||
717 | * Drop the initial reference from make_item()/make_group() | 743 | * Drop the initial reference from make_item()/make_group() |
718 | * This function assumes that reference is held on item | 744 | * This function assumes that reference is held on item |
719 | * and that item holds a valid reference to the parent. Also, it | 745 | * and that item holds a valid reference to the parent. Also, it |
@@ -733,11 +759,244 @@ static void client_drop_item(struct config_item *parent_item, | |||
733 | */ | 759 | */ |
734 | if (type->ct_group_ops && type->ct_group_ops->drop_item) | 760 | if (type->ct_group_ops && type->ct_group_ops->drop_item) |
735 | type->ct_group_ops->drop_item(to_config_group(parent_item), | 761 | type->ct_group_ops->drop_item(to_config_group(parent_item), |
736 | item); | 762 | item); |
737 | else | 763 | else |
738 | config_item_put(item); | 764 | config_item_put(item); |
739 | } | 765 | } |
740 | 766 | ||
767 | #ifdef DEBUG | ||
768 | static void configfs_dump_one(struct configfs_dirent *sd, int level) | ||
769 | { | ||
770 | printk(KERN_INFO "%*s\"%s\":\n", level, " ", configfs_get_name(sd)); | ||
771 | |||
772 | #define type_print(_type) if (sd->s_type & _type) printk(KERN_INFO "%*s %s\n", level, " ", #_type); | ||
773 | type_print(CONFIGFS_ROOT); | ||
774 | type_print(CONFIGFS_DIR); | ||
775 | type_print(CONFIGFS_ITEM_ATTR); | ||
776 | type_print(CONFIGFS_ITEM_LINK); | ||
777 | type_print(CONFIGFS_USET_DIR); | ||
778 | type_print(CONFIGFS_USET_DEFAULT); | ||
779 | type_print(CONFIGFS_USET_DROPPING); | ||
780 | #undef type_print | ||
781 | } | ||
782 | |||
783 | static int configfs_dump(struct configfs_dirent *sd, int level) | ||
784 | { | ||
785 | struct configfs_dirent *child_sd; | ||
786 | int ret = 0; | ||
787 | |||
788 | configfs_dump_one(sd, level); | ||
789 | |||
790 | if (!(sd->s_type & (CONFIGFS_DIR|CONFIGFS_ROOT))) | ||
791 | return 0; | ||
792 | |||
793 | list_for_each_entry(child_sd, &sd->s_children, s_sibling) { | ||
794 | ret = configfs_dump(child_sd, level + 2); | ||
795 | if (ret) | ||
796 | break; | ||
797 | } | ||
798 | |||
799 | return ret; | ||
800 | } | ||
801 | #endif | ||
802 | |||
803 | |||
804 | /* | ||
805 | * configfs_depend_item() and configfs_undepend_item() | ||
806 | * | ||
807 | * WARNING: Do not call these from a configfs callback! | ||
808 | * | ||
809 | * This describes these functions and their helpers. | ||
810 | * | ||
811 | * Allow another kernel system to depend on a config_item. If this | ||
812 | * happens, the item cannot go away until the dependant can live without | ||
813 | * it. The idea is to give client modules as simple an interface as | ||
814 | * possible. When a system asks them to depend on an item, they just | ||
815 | * call configfs_depend_item(). If the item is live and the client | ||
816 | * driver is in good shape, we'll happily do the work for them. | ||
817 | * | ||
818 | * Why is the locking complex? Because configfs uses the VFS to handle | ||
819 | * all locking, but this function is called outside the normal | ||
820 | * VFS->configfs path. So it must take VFS locks to prevent the | ||
821 | * VFS->configfs stuff (configfs_mkdir(), configfs_rmdir(), etc). This is | ||
822 | * why you can't call these functions underneath configfs callbacks. | ||
823 | * | ||
824 | * Note, btw, that this can be called at *any* time, even when a configfs | ||
825 | * subsystem isn't registered, or when configfs is loading or unloading. | ||
826 | * Just like configfs_register_subsystem(). So we take the same | ||
827 | * precautions. We pin the filesystem. We lock each i_mutex _in_order_ | ||
828 | * on our way down the tree. If we can find the target item in the | ||
829 | * configfs tree, it must be part of the subsystem tree as well, so we | ||
830 | * do not need the subsystem semaphore. Holding the i_mutex chain locks | ||
831 | * out mkdir() and rmdir(), who might be racing us. | ||
832 | */ | ||
833 | |||
834 | /* | ||
835 | * configfs_depend_prep() | ||
836 | * | ||
837 | * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are | ||
838 | * attributes. This is similar but not the same to configfs_detach_prep(). | ||
839 | * Note that configfs_detach_prep() expects the parent to be locked when it | ||
840 | * is called, but we lock the parent *inside* configfs_depend_prep(). We | ||
841 | * do that so we can unlock it if we find nothing. | ||
842 | * | ||
843 | * Here we do a depth-first search of the dentry hierarchy looking for | ||
844 | * our object. We take i_mutex on each step of the way down. IT IS | ||
845 | * ESSENTIAL THAT i_mutex LOCKING IS ORDERED. If we come back up a branch, | ||
846 | * we'll drop the i_mutex. | ||
847 | * | ||
848 | * If the target is not found, -ENOENT is bubbled up and we have released | ||
849 | * all locks. If the target was found, the locks will be cleared by | ||
850 | * configfs_depend_rollback(). | ||
851 | * | ||
852 | * This adds a requirement that all config_items be unique! | ||
853 | * | ||
854 | * This is recursive because the locking traversal is tricky. There isn't | ||
855 | * much on the stack, though, so folks that need this function - be careful | ||
856 | * about your stack! Patches will be accepted to make it iterative. | ||
857 | */ | ||
858 | static int configfs_depend_prep(struct dentry *origin, | ||
859 | struct config_item *target) | ||
860 | { | ||
861 | struct configfs_dirent *child_sd, *sd = origin->d_fsdata; | ||
862 | int ret = 0; | ||
863 | |||
864 | BUG_ON(!origin || !sd); | ||
865 | |||
866 | /* Lock this guy on the way down */ | ||
867 | mutex_lock(&sd->s_dentry->d_inode->i_mutex); | ||
868 | if (sd->s_element == target) /* Boo-yah */ | ||
869 | goto out; | ||
870 | |||
871 | list_for_each_entry(child_sd, &sd->s_children, s_sibling) { | ||
872 | if (child_sd->s_type & CONFIGFS_DIR) { | ||
873 | ret = configfs_depend_prep(child_sd->s_dentry, | ||
874 | target); | ||
875 | if (!ret) | ||
876 | goto out; /* Child path boo-yah */ | ||
877 | } | ||
878 | } | ||
879 | |||
880 | /* We looped all our children and didn't find target */ | ||
881 | mutex_unlock(&sd->s_dentry->d_inode->i_mutex); | ||
882 | ret = -ENOENT; | ||
883 | |||
884 | out: | ||
885 | return ret; | ||
886 | } | ||
887 | |||
888 | /* | ||
889 | * This is ONLY called if configfs_depend_prep() did its job. So we can | ||
890 | * trust the entire path from item back up to origin. | ||
891 | * | ||
892 | * We walk backwards from item, unlocking each i_mutex. We finish by | ||
893 | * unlocking origin. | ||
894 | */ | ||
895 | static void configfs_depend_rollback(struct dentry *origin, | ||
896 | struct config_item *item) | ||
897 | { | ||
898 | struct dentry *dentry = item->ci_dentry; | ||
899 | |||
900 | while (dentry != origin) { | ||
901 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
902 | dentry = dentry->d_parent; | ||
903 | } | ||
904 | |||
905 | mutex_unlock(&origin->d_inode->i_mutex); | ||
906 | } | ||
907 | |||
908 | int configfs_depend_item(struct configfs_subsystem *subsys, | ||
909 | struct config_item *target) | ||
910 | { | ||
911 | int ret; | ||
912 | struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; | ||
913 | struct config_item *s_item = &subsys->su_group.cg_item; | ||
914 | |||
915 | /* | ||
916 | * Pin the configfs filesystem. This means we can safely access | ||
917 | * the root of the configfs filesystem. | ||
918 | */ | ||
919 | ret = configfs_pin_fs(); | ||
920 | if (ret) | ||
921 | return ret; | ||
922 | |||
923 | /* | ||
924 | * Next, lock the root directory. We're going to check that the | ||
925 | * subsystem is really registered, and so we need to lock out | ||
926 | * configfs_[un]register_subsystem(). | ||
927 | */ | ||
928 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); | ||
929 | |||
930 | root_sd = configfs_sb->s_root->d_fsdata; | ||
931 | |||
932 | list_for_each_entry(p, &root_sd->s_children, s_sibling) { | ||
933 | if (p->s_type & CONFIGFS_DIR) { | ||
934 | if (p->s_element == s_item) { | ||
935 | subsys_sd = p; | ||
936 | break; | ||
937 | } | ||
938 | } | ||
939 | } | ||
940 | |||
941 | if (!subsys_sd) { | ||
942 | ret = -ENOENT; | ||
943 | goto out_unlock_fs; | ||
944 | } | ||
945 | |||
946 | /* Ok, now we can trust subsys/s_item */ | ||
947 | |||
948 | /* Scan the tree, locking i_mutex recursively, return 0 if found */ | ||
949 | ret = configfs_depend_prep(subsys_sd->s_dentry, target); | ||
950 | if (ret) | ||
951 | goto out_unlock_fs; | ||
952 | |||
953 | /* We hold all i_mutexes from the subsystem down to the target */ | ||
954 | p = target->ci_dentry->d_fsdata; | ||
955 | p->s_dependent_count += 1; | ||
956 | |||
957 | configfs_depend_rollback(subsys_sd->s_dentry, target); | ||
958 | |||
959 | out_unlock_fs: | ||
960 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | ||
961 | |||
962 | /* | ||
963 | * If we succeeded, the fs is pinned via other methods. If not, | ||
964 | * we're done with it anyway. So release_fs() is always right. | ||
965 | */ | ||
966 | configfs_release_fs(); | ||
967 | |||
968 | return ret; | ||
969 | } | ||
970 | EXPORT_SYMBOL(configfs_depend_item); | ||
971 | |||
972 | /* | ||
973 | * Release the dependent linkage. This is much simpler than | ||
974 | * configfs_depend_item() because we know that that the client driver is | ||
975 | * pinned, thus the subsystem is pinned, and therefore configfs is pinned. | ||
976 | */ | ||
977 | void configfs_undepend_item(struct configfs_subsystem *subsys, | ||
978 | struct config_item *target) | ||
979 | { | ||
980 | struct configfs_dirent *sd; | ||
981 | |||
982 | /* | ||
983 | * Since we can trust everything is pinned, we just need i_mutex | ||
984 | * on the item. | ||
985 | */ | ||
986 | mutex_lock(&target->ci_dentry->d_inode->i_mutex); | ||
987 | |||
988 | sd = target->ci_dentry->d_fsdata; | ||
989 | BUG_ON(sd->s_dependent_count < 1); | ||
990 | |||
991 | sd->s_dependent_count -= 1; | ||
992 | |||
993 | /* | ||
994 | * After this unlock, we cannot trust the item to stay alive! | ||
995 | * DO NOT REFERENCE item after this unlock. | ||
996 | */ | ||
997 | mutex_unlock(&target->ci_dentry->d_inode->i_mutex); | ||
998 | } | ||
999 | EXPORT_SYMBOL(configfs_undepend_item); | ||
741 | 1000 | ||
742 | static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 1001 | static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
743 | { | 1002 | { |
@@ -783,7 +1042,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
783 | 1042 | ||
784 | snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name); | 1043 | snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name); |
785 | 1044 | ||
786 | down(&subsys->su_sem); | 1045 | mutex_lock(&subsys->su_mutex); |
787 | group = NULL; | 1046 | group = NULL; |
788 | item = NULL; | 1047 | item = NULL; |
789 | if (type->ct_group_ops->make_group) { | 1048 | if (type->ct_group_ops->make_group) { |
@@ -797,7 +1056,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
797 | if (item) | 1056 | if (item) |
798 | link_obj(parent_item, item); | 1057 | link_obj(parent_item, item); |
799 | } | 1058 | } |
800 | up(&subsys->su_sem); | 1059 | mutex_unlock(&subsys->su_mutex); |
801 | 1060 | ||
802 | kfree(name); | 1061 | kfree(name); |
803 | if (!item) { | 1062 | if (!item) { |
@@ -841,13 +1100,16 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
841 | out_unlink: | 1100 | out_unlink: |
842 | if (ret) { | 1101 | if (ret) { |
843 | /* Tear down everything we built up */ | 1102 | /* Tear down everything we built up */ |
844 | down(&subsys->su_sem); | 1103 | mutex_lock(&subsys->su_mutex); |
1104 | |||
1105 | client_disconnect_notify(parent_item, item); | ||
845 | if (group) | 1106 | if (group) |
846 | unlink_group(group); | 1107 | unlink_group(group); |
847 | else | 1108 | else |
848 | unlink_obj(item); | 1109 | unlink_obj(item); |
849 | client_drop_item(parent_item, item); | 1110 | client_drop_item(parent_item, item); |
850 | up(&subsys->su_sem); | 1111 | |
1112 | mutex_unlock(&subsys->su_mutex); | ||
851 | 1113 | ||
852 | if (module_got) | 1114 | if (module_got) |
853 | module_put(owner); | 1115 | module_put(owner); |
@@ -881,6 +1143,13 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
881 | if (sd->s_type & CONFIGFS_USET_DEFAULT) | 1143 | if (sd->s_type & CONFIGFS_USET_DEFAULT) |
882 | return -EPERM; | 1144 | return -EPERM; |
883 | 1145 | ||
1146 | /* | ||
1147 | * Here's where we check for dependents. We're protected by | ||
1148 | * i_mutex. | ||
1149 | */ | ||
1150 | if (sd->s_dependent_count) | ||
1151 | return -EBUSY; | ||
1152 | |||
884 | /* Get a working ref until we have the child */ | 1153 | /* Get a working ref until we have the child */ |
885 | parent_item = configfs_get_config_item(dentry->d_parent); | 1154 | parent_item = configfs_get_config_item(dentry->d_parent); |
886 | subsys = to_config_group(parent_item)->cg_subsys; | 1155 | subsys = to_config_group(parent_item)->cg_subsys; |
@@ -910,17 +1179,19 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
910 | if (sd->s_type & CONFIGFS_USET_DIR) { | 1179 | if (sd->s_type & CONFIGFS_USET_DIR) { |
911 | configfs_detach_group(item); | 1180 | configfs_detach_group(item); |
912 | 1181 | ||
913 | down(&subsys->su_sem); | 1182 | mutex_lock(&subsys->su_mutex); |
1183 | client_disconnect_notify(parent_item, item); | ||
914 | unlink_group(to_config_group(item)); | 1184 | unlink_group(to_config_group(item)); |
915 | } else { | 1185 | } else { |
916 | configfs_detach_item(item); | 1186 | configfs_detach_item(item); |
917 | 1187 | ||
918 | down(&subsys->su_sem); | 1188 | mutex_lock(&subsys->su_mutex); |
1189 | client_disconnect_notify(parent_item, item); | ||
919 | unlink_obj(item); | 1190 | unlink_obj(item); |
920 | } | 1191 | } |
921 | 1192 | ||
922 | client_drop_item(parent_item, item); | 1193 | client_drop_item(parent_item, item); |
923 | up(&subsys->su_sem); | 1194 | mutex_unlock(&subsys->su_mutex); |
924 | 1195 | ||
925 | /* Drop our reference from above */ | 1196 | /* Drop our reference from above */ |
926 | config_item_put(item); | 1197 | config_item_put(item); |