kobj->name, grp->name ?: "");
return -EINVAL;
}
+ kobject_get_ownership(kobj, &uid, &gid);
if (grp->name) {
- kn = kernfs_create_dir_ns(kobj->sd, grp->name,
- S_IRWXU | S_IRUGO | S_IXUGO,
- uid, gid, kobj, NULL);
- if (IS_ERR(kn)) {
- if (PTR_ERR(kn) == -EEXIST)
- sysfs_warn_dup(kobj->sd, grp->name);
- return PTR_ERR(kn);
+ if (update) {
+ kn = kernfs_find_and_get(kobj->sd, grp->name);
+ if (!kn) {
+ pr_warn("Can't update unknown attr grp name: %s/%s\n",
+ kobj->name, grp->name);
+ return -EINVAL;
+ }
+ } else {
- kn = kernfs_create_dir(kobj->sd, grp->name,
- S_IRWXU | S_IRUGO | S_IXUGO,
- kobj);
++ kn = kernfs_create_dir_ns(kobj->sd, grp->name,
++ S_IRWXU | S_IRUGO | S_IXUGO,
++ uid, gid, kobj, NULL);
+ if (IS_ERR(kn)) {
+ if (PTR_ERR(kn) == -EEXIST)
+ sysfs_warn_dup(kobj->sd, grp->name);
+ return PTR_ERR(kn);
+ }
}
} else
kn = kobj->sd;
struct device_link *device_link_add(struct device *consumer,
struct device *supplier, u32 flags);
void device_link_del(struct device_link *link);
+void device_link_remove(void *consumer, struct device *supplier);
+ #ifndef dev_fmt
+ #define dev_fmt(fmt) fmt
+ #endif
+
#ifdef CONFIG_PRINTK
- extern __printf(3, 0)
+ __printf(3, 0)
int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args);
- extern __printf(3, 4)
+ __printf(3, 4)
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
- extern __printf(3, 4)
+ __printf(3, 4)
void dev_printk(const char *level, const struct device *dev,
const char *fmt, ...);
- extern __printf(2, 3)
- void dev_emerg(const struct device *dev, const char *fmt, ...);
- extern __printf(2, 3)
- void dev_alert(const struct device *dev, const char *fmt, ...);
- extern __printf(2, 3)
- void dev_crit(const struct device *dev, const char *fmt, ...);
- extern __printf(2, 3)
- void dev_err(const struct device *dev, const char *fmt, ...);
- extern __printf(2, 3)
- void dev_warn(const struct device *dev, const char *fmt, ...);
- extern __printf(2, 3)
- void dev_notice(const struct device *dev, const char *fmt, ...);
- extern __printf(2, 3)
+ __printf(2, 3)
+ void _dev_emerg(const struct device *dev, const char *fmt, ...);
+ __printf(2, 3)
+ void _dev_alert(const struct device *dev, const char *fmt, ...);
+ __printf(2, 3)
+ void _dev_crit(const struct device *dev, const char *fmt, ...);
+ __printf(2, 3)
+ void _dev_err(const struct device *dev, const char *fmt, ...);
+ __printf(2, 3)
+ void _dev_warn(const struct device *dev, const char *fmt, ...);
+ __printf(2, 3)
+ void _dev_notice(const struct device *dev, const char *fmt, ...);
+ __printf(2, 3)
void _dev_info(const struct device *dev, const char *fmt, ...);
#else
extern void kobject_put(struct kobject *kobj);
extern const void *kobject_namespace(struct kobject *kobj);
+extern void kobject_get_ownership(struct kobject *kobj,
+ kuid_t *uid, kgid_t *gid);
extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
+ /**
+ * kobject_has_children - Returns whether a kobject has children.
+ * @kobj: the object to test
+ *
+ * This will return whether a kobject has other kobjects as children.
+ *
+ * It does NOT account for the presence of attribute files, only sub
+ * directories. It also assumes there is no concurrent addition or
+ * removal of such children, and thus relies on external locking.
+ */
+ static inline bool kobject_has_children(struct kobject *kobj)
+ {
+ WARN_ON_ONCE(kref_read(&kobj->kref) == 0);
+
+ return kobj->sd && kobj->sd->dir.subdirs;
+ }
+
struct kobj_type {
void (*release)(struct kobject *kobj);
const struct sysfs_ops *sysfs_ops;