diff options
Diffstat (limited to 'fs/sysfs/sysfs.h')
-rw-r--r-- | fs/sysfs/sysfs.h | 169 |
1 files changed, 83 insertions, 86 deletions
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 502c949..6a37f23 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -1,9 +1,40 @@ +struct sysfs_elem_dir { + struct kobject * kobj; +}; + +struct sysfs_elem_symlink { + struct sysfs_dirent * target_sd; +}; + +struct sysfs_elem_attr { + struct attribute * attr; +}; + +struct sysfs_elem_bin_attr { + struct bin_attribute * bin_attr; +}; + +/* + * As long as s_count reference is held, the sysfs_dirent itself is + * accessible. Dereferencing s_elem or any other outer entity + * requires s_active reference. + */ struct sysfs_dirent { atomic_t s_count; - struct list_head s_sibling; - struct list_head s_children; - void * s_element; - int s_type; + atomic_t s_active; + struct sysfs_dirent * s_parent; + struct sysfs_dirent * s_sibling; + struct sysfs_dirent * s_children; + const char * s_name; + + union { + struct sysfs_elem_dir dir; + struct sysfs_elem_symlink symlink; + struct sysfs_elem_attr attr; + struct sysfs_elem_bin_attr bin_attr; + } s_elem; + + unsigned int s_flags; umode_t s_mode; ino_t s_ino; struct dentry * s_dentry; @@ -11,30 +42,60 @@ struct sysfs_dirent { atomic_t s_event; }; +#define SD_DEACTIVATED_BIAS INT_MIN + +struct sysfs_addrm_cxt { + struct sysfs_dirent *parent_sd; + struct inode *parent_inode; + struct sysfs_dirent *removed; + int cnt; +}; + extern struct vfsmount * sysfs_mount; +extern struct sysfs_dirent sysfs_root; extern struct kmem_cache *sysfs_dir_cachep; -extern void sysfs_delete_inode(struct inode *inode); -extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); -extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); +extern struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); +extern void sysfs_link_sibling(struct sysfs_dirent *sd); +extern void sysfs_unlink_sibling(struct sysfs_dirent *sd); +extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd); +extern void sysfs_put_active(struct sysfs_dirent *sd); +extern struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd); +extern void sysfs_put_active_two(struct sysfs_dirent *sd); +extern void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, + struct sysfs_dirent *parent_sd); +extern void sysfs_add_one(struct sysfs_addrm_cxt *acxt, + struct sysfs_dirent *sd); +extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, + struct sysfs_dirent *sd); +extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); -extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *); -extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, - umode_t, int); - -extern int sysfs_add_file(struct dentry *, const struct attribute *, int); -extern int sysfs_hash_and_remove(struct dentry * dir, const char * name); +extern void sysfs_delete_inode(struct inode *inode); +extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode); +extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd); +extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode); + +extern void release_sysfs_dirent(struct sysfs_dirent * sd); +extern struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, + const unsigned char *name); +extern struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, + const unsigned char *name); +extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, + int type); + +extern int sysfs_add_file(struct sysfs_dirent *dir_sd, + const struct attribute *attr, int type); +extern int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name); -extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **); -extern void sysfs_remove_subdir(struct dentry *); +extern int sysfs_create_subdir(struct kobject *kobj, const char *name, + struct sysfs_dirent **p_sd); +extern void sysfs_remove_subdir(struct sysfs_dirent *sd); -extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd); -extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent); extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); -extern spinlock_t sysfs_lock; -extern struct rw_semaphore sysfs_rename_sem; +extern spinlock_t sysfs_assoc_lock; +extern struct mutex sysfs_mutex; extern struct super_block * sysfs_sb; extern const struct file_operations sysfs_dir_operations; extern const struct file_operations sysfs_file_operations; @@ -42,73 +103,9 @@ extern const struct file_operations bin_fops; extern const struct inode_operations sysfs_dir_inode_operations; extern const struct inode_operations sysfs_symlink_inode_operations; -struct sysfs_symlink { - char * link_name; - struct kobject * target_kobj; -}; - -struct sysfs_buffer { - struct list_head associates; - size_t count; - loff_t pos; - char * page; - struct sysfs_ops * ops; - struct semaphore sem; - int orphaned; - int needs_read_fill; - int event; -}; - -struct sysfs_buffer_collection { - struct list_head associates; -}; - -static inline struct kobject * to_kobj(struct dentry * dentry) -{ - struct sysfs_dirent * sd = dentry->d_fsdata; - return ((struct kobject *) sd->s_element); -} - -static inline struct attribute * to_attr(struct dentry * dentry) +static inline unsigned int sysfs_type(struct sysfs_dirent *sd) { - struct sysfs_dirent * sd = dentry->d_fsdata; - return ((struct attribute *) sd->s_element); -} - -static inline struct bin_attribute * to_bin_attr(struct dentry * dentry) -{ - struct sysfs_dirent * sd = dentry->d_fsdata; - return ((struct bin_attribute *) sd->s_element); -} - -static inline struct kobject *sysfs_get_kobject(struct dentry *dentry) -{ - struct kobject * kobj = NULL; - - spin_lock(&dcache_lock); - if (!d_unhashed(dentry)) { - struct sysfs_dirent * sd = dentry->d_fsdata; - if (sd->s_type & SYSFS_KOBJ_LINK) { - struct sysfs_symlink * sl = sd->s_element; - kobj = kobject_get(sl->target_kobj); - } else - kobj = kobject_get(sd->s_element); - } - spin_unlock(&dcache_lock); - - return kobj; -} - -static inline void release_sysfs_dirent(struct sysfs_dirent * sd) -{ - if (sd->s_type & SYSFS_KOBJ_LINK) { - struct sysfs_symlink * sl = sd->s_element; - kfree(sl->link_name); - kobject_put(sl->target_kobj); - kfree(sl); - } - kfree(sd->s_iattr); - kmem_cache_free(sysfs_dir_cachep, sd); + return sd->s_flags & SYSFS_TYPE_MASK; } static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd) @@ -122,7 +119,7 @@ static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd) static inline void sysfs_put(struct sysfs_dirent * sd) { - if (atomic_dec_and_test(&sd->s_count)) + if (sd && atomic_dec_and_test(&sd->s_count)) release_sysfs_dirent(sd); } |