Commit ab2789b7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'configfs-for-4.12' of git://git.infradead.org/users/hch/configfs

Pull configfs updates from Christoph Hellwig:
 "A fix from Nic for a race seen in production (including a stable tag).

  And while I'm sending you this I'm also sneaking in a trivial new
  helper from Bart so that we don't need inter-tree dependencies for the
  next merge window"

* tag 'configfs-for-4.12' of git://git.infradead.org/users/hch/configfs:
  configfs: Introduce config_item_get_unless_zero()
  configfs: Fix race between create_link and configfs_rmdir
parents 20223f0f 19e72d3a
...@@ -138,6 +138,14 @@ struct config_item *config_item_get(struct config_item *item) ...@@ -138,6 +138,14 @@ struct config_item *config_item_get(struct config_item *item)
} }
EXPORT_SYMBOL(config_item_get); EXPORT_SYMBOL(config_item_get);
struct config_item *config_item_get_unless_zero(struct config_item *item)
{
if (item && kref_get_unless_zero(&item->ci_kref))
return item;
return NULL;
}
EXPORT_SYMBOL(config_item_get_unless_zero);
static void config_item_cleanup(struct config_item *item) static void config_item_cleanup(struct config_item *item)
{ {
struct config_item_type *t = item->ci_type; struct config_item_type *t = item->ci_type;
......
...@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item, ...@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item,
ret = -ENOMEM; ret = -ENOMEM;
sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
if (sl) { if (sl) {
sl->sl_target = config_item_get(item);
spin_lock(&configfs_dirent_lock); spin_lock(&configfs_dirent_lock);
if (target_sd->s_type & CONFIGFS_USET_DROPPING) { if (target_sd->s_type & CONFIGFS_USET_DROPPING) {
spin_unlock(&configfs_dirent_lock); spin_unlock(&configfs_dirent_lock);
config_item_put(item);
kfree(sl); kfree(sl);
return -ENOENT; return -ENOENT;
} }
sl->sl_target = config_item_get(item);
list_add(&sl->sl_list, &target_sd->s_links); list_add(&sl->sl_list, &target_sd->s_links);
spin_unlock(&configfs_dirent_lock); spin_unlock(&configfs_dirent_lock);
ret = configfs_create_link(sl, parent_item->ci_dentry, ret = configfs_create_link(sl, parent_item->ci_dentry,
......
...@@ -74,7 +74,8 @@ extern void config_item_init_type_name(struct config_item *item, ...@@ -74,7 +74,8 @@ extern void config_item_init_type_name(struct config_item *item,
const char *name, const char *name,
struct config_item_type *type); struct config_item_type *type);
extern struct config_item * config_item_get(struct config_item *); extern struct config_item *config_item_get(struct config_item *);
extern struct config_item *config_item_get_unless_zero(struct config_item *);
extern void config_item_put(struct config_item *); extern void config_item_put(struct config_item *);
struct config_item_type { struct config_item_type {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment