android_kernel_motorola_sm6225/include/linux/sysfs.h
Eric W. Biederman 030c1d2bfc kobject: Fix kobject_rename and !CONFIG_SYSFS
When looking at kobject_rename I found two bugs with
that exist when sysfs support is disabled in the kernel.

kobject_rename does not change the name on the kobject when
sysfs support is not compiled in.

kobject_rename without locking attempts to check the
validity of a rename operation, which the kobject layer
simply does not have the infrastructure to do.

This patch documents the previously unstated requirement of
kobject_rename that is the responsibility of the caller to
provide mutual exclusion and to be certain that the new_name
for the kobject is valid.

This patch modifies sysfs_rename_dir in !CONFIG_SYSFS case
to call kobject_set_name to actually change the kobject_name.

This patch removes the bogus and misleading check in kobject_rename
that attempts to see if a rename is valid.  The check is bogus
because we do not have the proper locking.  The check is misleading
because it looks like we can and do perform checking at the kobject
level that we don't.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2008-10-16 09:24:52 -07:00

266 lines
6.5 KiB
C

/*
* sysfs.h - definitions for the device driver filesystem
*
* Copyright (c) 2001,2002 Patrick Mochel
* Copyright (c) 2004 Silicon Graphics, Inc.
* Copyright (c) 2007 SUSE Linux Products GmbH
* Copyright (c) 2007 Tejun Heo <teheo@suse.de>
*
* Please see Documentation/filesystems/sysfs.txt for more information.
*/
#ifndef _SYSFS_H_
#define _SYSFS_H_
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <asm/atomic.h>
struct kobject;
struct module;
extern int kobject_set_name(struct kobject *kobj, const char *name, ...)
__attribute__((format(printf, 2, 3)));
/* FIXME
* The *owner field is no longer used, but leave around
* until the tree gets cleaned up fully.
*/
struct attribute {
const char *name;
struct module *owner;
mode_t mode;
};
struct attribute_group {
const char *name;
mode_t (*is_visible)(struct kobject *,
struct attribute *, int);
struct attribute **attrs;
};
/**
* Use these macros to make defining attributes easier. See include/linux/device.h
* for examples..
*/
#define __ATTR(_name,_mode,_show,_store) { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
}
#define __ATTR_RO(_name) { \
.attr = { .name = __stringify(_name), .mode = 0444 }, \
.show = _name##_show, \
}
#define __ATTR_NULL { .attr = { .name = NULL } }
#define attr_name(_attr) (_attr).attr.name
struct vm_area_struct;
struct bin_attribute {
struct attribute attr;
size_t size;
void *private;
ssize_t (*read)(struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
ssize_t (*write)(struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
int (*mmap)(struct kobject *, struct bin_attribute *attr,
struct vm_area_struct *vma);
};
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *,char *);
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
struct sysfs_dirent;
#ifdef CONFIG_SYSFS
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
void *data, struct module *owner);
int __must_check sysfs_create_dir(struct kobject *kobj);
void sysfs_remove_dir(struct kobject *kobj);
int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
int __must_check sysfs_move_dir(struct kobject *kobj,
struct kobject *new_parent_kobj);
int __must_check sysfs_create_file(struct kobject *kobj,
const struct attribute *attr);
int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr,
mode_t mode);
void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
int __must_check sysfs_create_bin_file(struct kobject *kobj,
struct bin_attribute *attr);
void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
const char *name);
int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
struct kobject *target,
const char *name);
void sysfs_remove_link(struct kobject *kobj, const char *name);
int __must_check sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp);
int sysfs_update_group(struct kobject *kobj,
const struct attribute_group *grp);
void sysfs_remove_group(struct kobject *kobj,
const struct attribute_group *grp);
int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
void sysfs_remove_file_from_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
void sysfs_notify_dirent(struct sysfs_dirent *sd);
struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
const unsigned char *name);
struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
void sysfs_put(struct sysfs_dirent *sd);
void sysfs_printk_last_file(void);
int __must_check sysfs_init(void);
#else /* CONFIG_SYSFS */
static inline int sysfs_schedule_callback(struct kobject *kobj,
void (*func)(void *), void *data, struct module *owner)
{
return -ENOSYS;
}
static inline int sysfs_create_dir(struct kobject *kobj)
{
return 0;
}
static inline void sysfs_remove_dir(struct kobject *kobj)
{
}
static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
{
return kobject_set_name(kobj, "%s", new_name);
}
static inline int sysfs_move_dir(struct kobject *kobj,
struct kobject *new_parent_kobj)
{
return 0;
}
static inline int sysfs_create_file(struct kobject *kobj,
const struct attribute *attr)
{
return 0;
}
static inline int sysfs_chmod_file(struct kobject *kobj,
struct attribute *attr, mode_t mode)
{
return 0;
}
static inline void sysfs_remove_file(struct kobject *kobj,
const struct attribute *attr)
{
}
static inline int sysfs_create_bin_file(struct kobject *kobj,
struct bin_attribute *attr)
{
return 0;
}
static inline void sysfs_remove_bin_file(struct kobject *kobj,
struct bin_attribute *attr)
{
}
static inline int sysfs_create_link(struct kobject *kobj,
struct kobject *target, const char *name)
{
return 0;
}
static inline int sysfs_create_link_nowarn(struct kobject *kobj,
struct kobject *target,
const char *name)
{
return 0;
}
static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
{
}
static inline int sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp)
{
return 0;
}
static inline int sysfs_update_group(struct kobject *kobj,
const struct attribute_group *grp)
{
return 0;
}
static inline void sysfs_remove_group(struct kobject *kobj,
const struct attribute_group *grp)
{
}
static inline int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group)
{
return 0;
}
static inline void sysfs_remove_file_from_group(struct kobject *kobj,
const struct attribute *attr, const char *group)
{
}
static inline void sysfs_notify(struct kobject *kobj, const char *dir,
const char *attr)
{
}
static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
{
}
static inline
struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
const unsigned char *name)
{
return NULL;
}
static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
{
return NULL;
}
static inline void sysfs_put(struct sysfs_dirent *sd)
{
}
static inline int __must_check sysfs_init(void)
{
return 0;
}
static inline void sysfs_printk_last_file(void)
{
}
#endif /* CONFIG_SYSFS */
#endif /* _SYSFS_H_ */