Sometimes it might be desirable to prohibit removing a directory in configfs. One example is USB gadget (mass_storage function): when gadget is already bound, if lun directory is removed, the gadget must be thrown away, too. A better solution would be to fail with e.g. -EBUSY. Currently configfs has configfs_depend/undepend_item() methods but they cannot be used in configfs callbacks. This commit adds unlocked version of this methods which can be used only in configfs callbacks. Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> --- fs/configfs/dir.c | 29 +++++++++++++++++++++++++++++ include/linux/configfs.h | 9 +++++++++ 2 files changed, 38 insertions(+) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index cf0db00..7875a5e 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1152,6 +1152,35 @@ void configfs_undepend_item(struct configfs_subsystem *subsys, } EXPORT_SYMBOL(configfs_undepend_item); +int configfs_depend_item_unlocked(struct config_item *target) +{ + struct configfs_dirent *sd; + int ret = -ENOENT; + + spin_lock(&configfs_dirent_lock); + BUG_ON(!target->ci_dentry); + + sd = target->ci_dentry->d_fsdata; + if ((sd->s_type & CONFIGFS_DIR) && + ((sd->s_type & CONFIGFS_USET_DROPPING) || + (sd->s_type & CONFIGFS_USET_CREATING))) + goto out_unlock_dirent_lock; + + sd->s_dependent_count += 1; + ret = 0; + +out_unlock_dirent_lock: + spin_unlock(&configfs_dirent_lock); + return ret; +} +EXPORT_SYMBOL(configfs_depend_item_unlocked); + +void configfs_undepend_item_unlocked(struct config_item *target) +{ + configfs_undepend_item(NULL, target); +} +EXPORT_SYMBOL(configfs_undepend_item_unlocked); + static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { int ret = 0; diff --git a/include/linux/configfs.h b/include/linux/configfs.h index 34025df..e9dbf01 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h @@ -257,4 +257,13 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys); int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target); void configfs_undepend_item(struct configfs_subsystem *subsys, struct config_item *target); +/* + * These functions can sleep and can alloc with GFP_KERNEL + * NOTE: These should be called only underneath configfs callbacks. + * WARNING: These cannot be called on newly created item + * (in make_group()/make_item callback) + */ +int configfs_depend_item_unlocked(struct config_item *target); +void configfs_undepend_item_unlocked(struct config_item *target); + #endif /* _CONFIGFS_H_ */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html