diff --git a/drivers/base/core.c b/drivers/base/core.c index 3d6430eb0c6a..b8637c4c4048 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3524,7 +3524,7 @@ bool kill_device(struct device *dev) */ device_lock_assert(dev); - if (dev->p->dead) + if (!dev->p || dev->p->dead) return false; dev->p->dead = true; return true; @@ -3548,6 +3548,7 @@ void device_del(struct device *dev) { struct device *parent = dev->parent; struct kobject *glue_dir = NULL; + struct kobject *kobj = &dev->kobj; struct class_interface *class_intf; unsigned int noio_flag; @@ -3566,7 +3567,8 @@ void device_del(struct device *dev) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DEL_DEVICE, dev); - dpm_sysfs_remove(dev); + if (kobj->sd) + dpm_sysfs_remove(dev); if (parent) klist_del(&dev->p->knode_parent); if (MAJOR(dev->devt)) { @@ -3574,7 +3576,7 @@ void device_del(struct device *dev) device_remove_sys_dev_entry(dev); device_remove_file(dev, &dev_attr_dev); } - if (dev->class) { + if (dev->class && dev->p) { device_remove_class_symlinks(dev); mutex_lock(&dev->class->p->mutex); @@ -3587,11 +3589,15 @@ void device_del(struct device *dev) klist_del(&dev->p->knode_class); mutex_unlock(&dev->class->p->mutex); } - device_remove_file(dev, &dev_attr_uevent); + if (kobj->sd) + device_remove_file(dev, &dev_attr_uevent); + device_remove_attrs(dev); bus_remove_device(dev); device_pm_remove(dev); - driver_deferred_probe_del(dev); + if (dev->p) + driver_deferred_probe_del(dev); + device_platform_notify_remove(dev); device_links_purge(dev); diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index e205fde7163a..7b33f2dfb7d1 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1565,6 +1565,11 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, struct kernfs_node *kn; struct kernfs_root *root; + if (!name) { + WARN(1, KERN_WARNING "kernfs: can not remove directory. Name is NULL\n"); + return -ENOENT; + } + if (!parent) { WARN(1, KERN_WARNING "kernfs: can not remove '%s', no directory\n", name);