diff options
Diffstat (limited to 'fs/sysfs')
| -rw-r--r-- | fs/sysfs/bin.c | 4 | ||||
| -rw-r--r-- | fs/sysfs/dir.c | 26 | ||||
| -rw-r--r-- | fs/sysfs/file.c | 6 | ||||
| -rw-r--r-- | fs/sysfs/inode.c | 102 | ||||
| -rw-r--r-- | fs/sysfs/mount.c | 4 | ||||
| -rw-r--r-- | fs/sysfs/symlink.c | 8 | ||||
| -rw-r--r-- | fs/sysfs/sysfs.h | 4 |
7 files changed, 127 insertions, 27 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index d4aaa88d0214..78899eeab974 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
| @@ -25,7 +25,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) | |||
| 25 | struct kobject * kobj = to_kobj(dentry->d_parent); | 25 | struct kobject * kobj = to_kobj(dentry->d_parent); |
| 26 | 26 | ||
| 27 | if (!attr->read) | 27 | if (!attr->read) |
| 28 | return -EINVAL; | 28 | return -EIO; |
| 29 | 29 | ||
| 30 | return attr->read(kobj, buffer, off, count); | 30 | return attr->read(kobj, buffer, off, count); |
| 31 | } | 31 | } |
| @@ -71,7 +71,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) | |||
| 71 | struct kobject *kobj = to_kobj(dentry->d_parent); | 71 | struct kobject *kobj = to_kobj(dentry->d_parent); |
| 72 | 72 | ||
| 73 | if (!attr->write) | 73 | if (!attr->write) |
| 74 | return -EINVAL; | 74 | return -EIO; |
| 75 | 75 | ||
| 76 | return attr->write(kobj, buffer, offset, count); | 76 | return attr->write(kobj, buffer, offset, count); |
| 77 | } | 77 | } |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index fe198210bc2d..37d7a6875d86 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -101,18 +101,19 @@ static int create_dir(struct kobject * k, struct dentry * p, | |||
| 101 | down(&p->d_inode->i_sem); | 101 | down(&p->d_inode->i_sem); |
| 102 | *d = sysfs_get_dentry(p,n); | 102 | *d = sysfs_get_dentry(p,n); |
| 103 | if (!IS_ERR(*d)) { | 103 | if (!IS_ERR(*d)) { |
| 104 | error = sysfs_create(*d, mode, init_dir); | 104 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); |
| 105 | if (!error) { | 105 | if (!error) { |
| 106 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, | 106 | error = sysfs_create(*d, mode, init_dir); |
| 107 | SYSFS_DIR); | ||
| 108 | if (!error) { | 107 | if (!error) { |
| 109 | p->d_inode->i_nlink++; | 108 | p->d_inode->i_nlink++; |
| 110 | (*d)->d_op = &sysfs_dentry_ops; | 109 | (*d)->d_op = &sysfs_dentry_ops; |
| 111 | d_rehash(*d); | 110 | d_rehash(*d); |
| 112 | } | 111 | } |
| 113 | } | 112 | } |
| 114 | if (error && (error != -EEXIST)) | 113 | if (error && (error != -EEXIST)) { |
| 114 | sysfs_put((*d)->d_fsdata); | ||
| 115 | d_drop(*d); | 115 | d_drop(*d); |
| 116 | } | ||
| 116 | dput(*d); | 117 | dput(*d); |
| 117 | } else | 118 | } else |
| 118 | error = PTR_ERR(*d); | 119 | error = PTR_ERR(*d); |
| @@ -171,17 +172,19 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry) | |||
| 171 | init = init_file; | 172 | init = init_file; |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 175 | dentry->d_fsdata = sysfs_get(sd); | ||
| 176 | sd->s_dentry = dentry; | ||
| 174 | error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); | 177 | error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); |
| 175 | if (error) | 178 | if (error) { |
| 179 | sysfs_put(sd); | ||
| 176 | return error; | 180 | return error; |
| 181 | } | ||
| 177 | 182 | ||
| 178 | if (bin_attr) { | 183 | if (bin_attr) { |
| 179 | dentry->d_inode->i_size = bin_attr->size; | 184 | dentry->d_inode->i_size = bin_attr->size; |
| 180 | dentry->d_inode->i_fop = &bin_fops; | 185 | dentry->d_inode->i_fop = &bin_fops; |
| 181 | } | 186 | } |
| 182 | dentry->d_op = &sysfs_dentry_ops; | 187 | dentry->d_op = &sysfs_dentry_ops; |
| 183 | dentry->d_fsdata = sysfs_get(sd); | ||
| 184 | sd->s_dentry = dentry; | ||
| 185 | d_rehash(dentry); | 188 | d_rehash(dentry); |
| 186 | 189 | ||
| 187 | return 0; | 190 | return 0; |
| @@ -191,13 +194,15 @@ static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry) | |||
| 191 | { | 194 | { |
| 192 | int err = 0; | 195 | int err = 0; |
| 193 | 196 | ||
| 197 | dentry->d_fsdata = sysfs_get(sd); | ||
| 198 | sd->s_dentry = dentry; | ||
| 194 | err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); | 199 | err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); |
| 195 | if (!err) { | 200 | if (!err) { |
| 196 | dentry->d_op = &sysfs_dentry_ops; | 201 | dentry->d_op = &sysfs_dentry_ops; |
| 197 | dentry->d_fsdata = sysfs_get(sd); | ||
| 198 | sd->s_dentry = dentry; | ||
| 199 | d_rehash(dentry); | 202 | d_rehash(dentry); |
| 200 | } | 203 | } else |
| 204 | sysfs_put(sd); | ||
| 205 | |||
| 201 | return err; | 206 | return err; |
| 202 | } | 207 | } |
| 203 | 208 | ||
| @@ -228,6 +233,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 228 | 233 | ||
| 229 | struct inode_operations sysfs_dir_inode_operations = { | 234 | struct inode_operations sysfs_dir_inode_operations = { |
| 230 | .lookup = sysfs_lookup, | 235 | .lookup = sysfs_lookup, |
| 236 | .setattr = sysfs_setattr, | ||
| 231 | }; | 237 | }; |
| 232 | 238 | ||
| 233 | static void remove_dir(struct dentry * d) | 239 | static void remove_dir(struct dentry * d) |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 364208071e17..849aac115460 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
| @@ -23,7 +23,7 @@ subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page) | |||
| 23 | { | 23 | { |
| 24 | struct subsystem * s = to_subsys(kobj); | 24 | struct subsystem * s = to_subsys(kobj); |
| 25 | struct subsys_attribute * sattr = to_sattr(attr); | 25 | struct subsys_attribute * sattr = to_sattr(attr); |
| 26 | ssize_t ret = 0; | 26 | ssize_t ret = -EIO; |
| 27 | 27 | ||
| 28 | if (sattr->show) | 28 | if (sattr->show) |
| 29 | ret = sattr->show(s,page); | 29 | ret = sattr->show(s,page); |
| @@ -36,7 +36,7 @@ subsys_attr_store(struct kobject * kobj, struct attribute * attr, | |||
| 36 | { | 36 | { |
| 37 | struct subsystem * s = to_subsys(kobj); | 37 | struct subsystem * s = to_subsys(kobj); |
| 38 | struct subsys_attribute * sattr = to_sattr(attr); | 38 | struct subsys_attribute * sattr = to_sattr(attr); |
| 39 | ssize_t ret = 0; | 39 | ssize_t ret = -EIO; |
| 40 | 40 | ||
| 41 | if (sattr->store) | 41 | if (sattr->store) |
| 42 | ret = sattr->store(s,page,count); | 42 | ret = sattr->store(s,page,count); |
| @@ -182,7 +182,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t | |||
| 182 | return -ENOMEM; | 182 | return -ENOMEM; |
| 183 | 183 | ||
| 184 | if (count >= PAGE_SIZE) | 184 | if (count >= PAGE_SIZE) |
| 185 | count = PAGE_SIZE - 1; | 185 | count = PAGE_SIZE; |
| 186 | error = copy_from_user(buffer->page,buf,count); | 186 | error = copy_from_user(buffer->page,buf,count); |
| 187 | buffer->needs_read_fill = 1; | 187 | buffer->needs_read_fill = 1; |
| 188 | return error ? -EFAULT : count; | 188 | return error ? -EFAULT : count; |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index aff7b2dfa8ee..565cac1d4200 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
| @@ -26,18 +26,107 @@ static struct backing_dev_info sysfs_backing_dev_info = { | |||
| 26 | .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | 26 | .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | struct inode * sysfs_new_inode(mode_t mode) | 29 | static struct inode_operations sysfs_inode_operations ={ |
| 30 | .setattr = sysfs_setattr, | ||
| 31 | }; | ||
| 32 | |||
| 33 | int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) | ||
| 34 | { | ||
| 35 | struct inode * inode = dentry->d_inode; | ||
| 36 | struct sysfs_dirent * sd = dentry->d_fsdata; | ||
| 37 | struct iattr * sd_iattr; | ||
| 38 | unsigned int ia_valid = iattr->ia_valid; | ||
| 39 | int error; | ||
| 40 | |||
| 41 | if (!sd) | ||
| 42 | return -EINVAL; | ||
| 43 | |||
| 44 | sd_iattr = sd->s_iattr; | ||
| 45 | |||
| 46 | error = inode_change_ok(inode, iattr); | ||
| 47 | if (error) | ||
| 48 | return error; | ||
| 49 | |||
| 50 | error = inode_setattr(inode, iattr); | ||
| 51 | if (error) | ||
| 52 | return error; | ||
| 53 | |||
| 54 | if (!sd_iattr) { | ||
| 55 | /* setting attributes for the first time, allocate now */ | ||
| 56 | sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL); | ||
| 57 | if (!sd_iattr) | ||
| 58 | return -ENOMEM; | ||
| 59 | /* assign default attributes */ | ||
| 60 | memset(sd_iattr, 0, sizeof(struct iattr)); | ||
| 61 | sd_iattr->ia_mode = sd->s_mode; | ||
| 62 | sd_iattr->ia_uid = 0; | ||
| 63 | sd_iattr->ia_gid = 0; | ||
| 64 | sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; | ||
| 65 | sd->s_iattr = sd_iattr; | ||
| 66 | } | ||
| 67 | |||
| 68 | /* attributes were changed atleast once in past */ | ||
| 69 | |||
| 70 | if (ia_valid & ATTR_UID) | ||
| 71 | sd_iattr->ia_uid = iattr->ia_uid; | ||
| 72 | if (ia_valid & ATTR_GID) | ||
| 73 | sd_iattr->ia_gid = iattr->ia_gid; | ||
| 74 | if (ia_valid & ATTR_ATIME) | ||
| 75 | sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime, | ||
| 76 | inode->i_sb->s_time_gran); | ||
| 77 | if (ia_valid & ATTR_MTIME) | ||
| 78 | sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime, | ||
| 79 | inode->i_sb->s_time_gran); | ||
| 80 | if (ia_valid & ATTR_CTIME) | ||
| 81 | sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime, | ||
| 82 | inode->i_sb->s_time_gran); | ||
| 83 | if (ia_valid & ATTR_MODE) { | ||
| 84 | umode_t mode = iattr->ia_mode; | ||
| 85 | |||
| 86 | if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) | ||
| 87 | mode &= ~S_ISGID; | ||
| 88 | sd_iattr->ia_mode = mode; | ||
| 89 | } | ||
| 90 | |||
| 91 | return error; | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline void set_default_inode_attr(struct inode * inode, mode_t mode) | ||
| 95 | { | ||
| 96 | inode->i_mode = mode; | ||
| 97 | inode->i_uid = 0; | ||
| 98 | inode->i_gid = 0; | ||
| 99 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) | ||
| 103 | { | ||
| 104 | inode->i_mode = iattr->ia_mode; | ||
| 105 | inode->i_uid = iattr->ia_uid; | ||
| 106 | inode->i_gid = iattr->ia_gid; | ||
| 107 | inode->i_atime = iattr->ia_atime; | ||
| 108 | inode->i_mtime = iattr->ia_mtime; | ||
| 109 | inode->i_ctime = iattr->ia_ctime; | ||
| 110 | } | ||
| 111 | |||
| 112 | struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd) | ||
| 30 | { | 113 | { |
| 31 | struct inode * inode = new_inode(sysfs_sb); | 114 | struct inode * inode = new_inode(sysfs_sb); |
| 32 | if (inode) { | 115 | if (inode) { |
| 33 | inode->i_mode = mode; | ||
| 34 | inode->i_uid = 0; | ||
| 35 | inode->i_gid = 0; | ||
| 36 | inode->i_blksize = PAGE_CACHE_SIZE; | 116 | inode->i_blksize = PAGE_CACHE_SIZE; |
| 37 | inode->i_blocks = 0; | 117 | inode->i_blocks = 0; |
| 38 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 39 | inode->i_mapping->a_ops = &sysfs_aops; | 118 | inode->i_mapping->a_ops = &sysfs_aops; |
| 40 | inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; | 119 | inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; |
| 120 | inode->i_op = &sysfs_inode_operations; | ||
| 121 | |||
| 122 | if (sd->s_iattr) { | ||
| 123 | /* sysfs_dirent has non-default attributes | ||
| 124 | * get them for the new inode from persistent copy | ||
| 125 | * in sysfs_dirent | ||
| 126 | */ | ||
| 127 | set_inode_attr(inode, sd->s_iattr); | ||
| 128 | } else | ||
| 129 | set_default_inode_attr(inode, mode); | ||
| 41 | } | 130 | } |
| 42 | return inode; | 131 | return inode; |
| 43 | } | 132 | } |
| @@ -48,7 +137,8 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) | |||
| 48 | struct inode * inode = NULL; | 137 | struct inode * inode = NULL; |
| 49 | if (dentry) { | 138 | if (dentry) { |
| 50 | if (!dentry->d_inode) { | 139 | if (!dentry->d_inode) { |
| 51 | if ((inode = sysfs_new_inode(mode))) { | 140 | struct sysfs_dirent * sd = dentry->d_fsdata; |
| 141 | if ((inode = sysfs_new_inode(mode, sd))) { | ||
| 52 | if (dentry->d_parent && dentry->d_parent->d_inode) { | 142 | if (dentry->d_parent && dentry->d_parent->d_inode) { |
| 53 | struct inode *p_inode = dentry->d_parent->d_inode; | 143 | struct inode *p_inode = dentry->d_parent->d_inode; |
| 54 | p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; | 144 | p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 5c805bb1a4b7..f1117e885bd6 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
| @@ -28,6 +28,7 @@ static struct sysfs_dirent sysfs_root = { | |||
| 28 | .s_children = LIST_HEAD_INIT(sysfs_root.s_children), | 28 | .s_children = LIST_HEAD_INIT(sysfs_root.s_children), |
| 29 | .s_element = NULL, | 29 | .s_element = NULL, |
| 30 | .s_type = SYSFS_ROOT, | 30 | .s_type = SYSFS_ROOT, |
| 31 | .s_iattr = NULL, | ||
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| 33 | static int sysfs_fill_super(struct super_block *sb, void *data, int silent) | 34 | static int sysfs_fill_super(struct super_block *sb, void *data, int silent) |
| @@ -42,7 +43,8 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 42 | sb->s_time_gran = 1; | 43 | sb->s_time_gran = 1; |
| 43 | sysfs_sb = sb; | 44 | sysfs_sb = sb; |
| 44 | 45 | ||
| 45 | inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO); | 46 | inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, |
| 47 | &sysfs_root); | ||
| 46 | if (inode) { | 48 | if (inode) { |
| 47 | inode->i_op = &sysfs_dir_inode_operations; | 49 | inode->i_op = &sysfs_dir_inode_operations; |
| 48 | inode->i_fop = &sysfs_dir_operations; | 50 | inode->i_fop = &sysfs_dir_operations; |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index dfdf70174354..fae57c83a722 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
| @@ -43,7 +43,7 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length) | |||
| 43 | } | 43 | } |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | static int sysfs_add_link(struct dentry * parent, char * name, struct kobject * target) | 46 | static int sysfs_add_link(struct dentry * parent, const char * name, struct kobject * target) |
| 47 | { | 47 | { |
| 48 | struct sysfs_dirent * parent_sd = parent->d_fsdata; | 48 | struct sysfs_dirent * parent_sd = parent->d_fsdata; |
| 49 | struct sysfs_symlink * sl; | 49 | struct sysfs_symlink * sl; |
| @@ -79,7 +79,7 @@ exit1: | |||
| 79 | * @target: object we're pointing to. | 79 | * @target: object we're pointing to. |
| 80 | * @name: name of the symlink. | 80 | * @name: name of the symlink. |
| 81 | */ | 81 | */ |
| 82 | int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name) | 82 | int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) |
| 83 | { | 83 | { |
| 84 | struct dentry * dentry = kobj->dentry; | 84 | struct dentry * dentry = kobj->dentry; |
| 85 | int error = 0; | 85 | int error = 0; |
| @@ -99,13 +99,13 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * nam | |||
| 99 | * @name: name of the symlink to remove. | 99 | * @name: name of the symlink to remove. |
| 100 | */ | 100 | */ |
| 101 | 101 | ||
| 102 | void sysfs_remove_link(struct kobject * kobj, char * name) | 102 | void sysfs_remove_link(struct kobject * kobj, const char * name) |
| 103 | { | 103 | { |
| 104 | sysfs_hash_and_remove(kobj->dentry,name); | 104 | sysfs_hash_and_remove(kobj->dentry,name); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target, | 107 | static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target, |
| 108 | char *path) | 108 | char *path) |
| 109 | { | 109 | { |
| 110 | char * s; | 110 | char * s; |
| 111 | int depth, size; | 111 | int depth, size; |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index a8a24a0c0b3b..29da6f5f07c8 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | extern struct vfsmount * sysfs_mount; | 2 | extern struct vfsmount * sysfs_mount; |
| 3 | extern kmem_cache_t *sysfs_dir_cachep; | 3 | extern kmem_cache_t *sysfs_dir_cachep; |
| 4 | 4 | ||
| 5 | extern struct inode * sysfs_new_inode(mode_t mode); | 5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); |
| 6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); | 6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); |
| 7 | 7 | ||
| 8 | extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, | 8 | extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, |
| @@ -17,6 +17,7 @@ extern void sysfs_remove_subdir(struct dentry *); | |||
| 17 | 17 | ||
| 18 | extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd); | 18 | extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd); |
| 19 | extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent); | 19 | extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent); |
| 20 | extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | ||
| 20 | 21 | ||
| 21 | extern struct rw_semaphore sysfs_rename_sem; | 22 | extern struct rw_semaphore sysfs_rename_sem; |
| 22 | extern struct super_block * sysfs_sb; | 23 | extern struct super_block * sysfs_sb; |
| @@ -75,6 +76,7 @@ static inline void release_sysfs_dirent(struct sysfs_dirent * sd) | |||
| 75 | kobject_put(sl->target_kobj); | 76 | kobject_put(sl->target_kobj); |
| 76 | kfree(sl); | 77 | kfree(sl); |
| 77 | } | 78 | } |
| 79 | kfree(sd->s_iattr); | ||
| 78 | kmem_cache_free(sysfs_dir_cachep, sd); | 80 | kmem_cache_free(sysfs_dir_cachep, sd); |
| 79 | } | 81 | } |
| 80 | 82 | ||
