aboutsummaryrefslogtreecommitdiffstats
path: root/fs/configfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r--fs/configfs/dir.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index d3b1dbb9b5b8..125954723eb7 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -714,6 +714,28 @@ static void configfs_detach_group(struct config_item *item)
714} 714}
715 715
716/* 716/*
717 * After the item has been detached from the filesystem view, we are
718 * ready to tear it out of the hierarchy. Notify the client before
719 * we do that so they can perform any cleanup that requires
720 * navigating the hierarchy. A client does not need to provide this
721 * callback. The subsystem semaphore MUST be held by the caller, and
722 * references must be valid for both items. It also assumes the
723 * caller has validated ci_type.
724 */
725static void client_disconnect_notify(struct config_item *parent_item,
726 struct config_item *item)
727{
728 struct config_item_type *type;
729
730 type = parent_item->ci_type;
731 BUG_ON(!type);
732
733 if (type->ct_group_ops && type->ct_group_ops->disconnect_notify)
734 type->ct_group_ops->disconnect_notify(to_config_group(parent_item),
735 item);
736}
737
738/*
717 * Drop the initial reference from make_item()/make_group() 739 * Drop the initial reference from make_item()/make_group()
718 * This function assumes that reference is held on item 740 * This function assumes that reference is held on item
719 * and that item holds a valid reference to the parent. Also, it 741 * and that item holds a valid reference to the parent. Also, it
@@ -733,7 +755,7 @@ static void client_drop_item(struct config_item *parent_item,
733 */ 755 */
734 if (type->ct_group_ops && type->ct_group_ops->drop_item) 756 if (type->ct_group_ops && type->ct_group_ops->drop_item)
735 type->ct_group_ops->drop_item(to_config_group(parent_item), 757 type->ct_group_ops->drop_item(to_config_group(parent_item),
736 item); 758 item);
737 else 759 else
738 config_item_put(item); 760 config_item_put(item);
739} 761}
@@ -842,11 +864,14 @@ out_unlink:
842 if (ret) { 864 if (ret) {
843 /* Tear down everything we built up */ 865 /* Tear down everything we built up */
844 mutex_lock(&subsys->su_mutex); 866 mutex_lock(&subsys->su_mutex);
867
868 client_disconnect_notify(parent_item, item);
845 if (group) 869 if (group)
846 unlink_group(group); 870 unlink_group(group);
847 else 871 else
848 unlink_obj(item); 872 unlink_obj(item);
849 client_drop_item(parent_item, item); 873 client_drop_item(parent_item, item);
874
850 mutex_unlock(&subsys->su_mutex); 875 mutex_unlock(&subsys->su_mutex);
851 876
852 if (module_got) 877 if (module_got)
@@ -911,11 +936,13 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
911 configfs_detach_group(item); 936 configfs_detach_group(item);
912 937
913 mutex_lock(&subsys->su_mutex); 938 mutex_lock(&subsys->su_mutex);
939 client_disconnect_notify(parent_item, item);
914 unlink_group(to_config_group(item)); 940 unlink_group(to_config_group(item));
915 } else { 941 } else {
916 configfs_detach_item(item); 942 configfs_detach_item(item);
917 943
918 mutex_lock(&subsys->su_mutex); 944 mutex_lock(&subsys->su_mutex);
945 client_disconnect_notify(parent_item, item);
919 unlink_obj(item); 946 unlink_obj(item);
920 } 947 }
921 948