diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/sysfs/dir.c | 2 | ||||
| -rw-r--r-- | fs/sysfs/inode.c | 64 | ||||
| -rw-r--r-- | fs/sysfs/symlink.c | 3 | ||||
| -rw-r--r-- | fs/sysfs/sysfs.h | 2 |
4 files changed, 54 insertions, 17 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 36ee6d817956..e319379d36db 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -800,7 +800,9 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 800 | 800 | ||
| 801 | const struct inode_operations sysfs_dir_inode_operations = { | 801 | const struct inode_operations sysfs_dir_inode_operations = { |
| 802 | .lookup = sysfs_lookup, | 802 | .lookup = sysfs_lookup, |
| 803 | .permission = sysfs_permission, | ||
| 803 | .setattr = sysfs_setattr, | 804 | .setattr = sysfs_setattr, |
| 805 | .getattr = sysfs_getattr, | ||
| 804 | .setxattr = sysfs_setxattr, | 806 | .setxattr = sysfs_setxattr, |
| 805 | }; | 807 | }; |
| 806 | 808 | ||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 76e977c300f7..1ffd5559926f 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
| @@ -37,7 +37,9 @@ static struct backing_dev_info sysfs_backing_dev_info = { | |||
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | static const struct inode_operations sysfs_inode_operations ={ | 39 | static const struct inode_operations sysfs_inode_operations ={ |
| 40 | .permission = sysfs_permission, | ||
| 40 | .setattr = sysfs_setattr, | 41 | .setattr = sysfs_setattr, |
| 42 | .getattr = sysfs_getattr, | ||
| 41 | .setxattr = sysfs_setxattr, | 43 | .setxattr = sysfs_setxattr, |
| 42 | }; | 44 | }; |
| 43 | 45 | ||
| @@ -196,7 +198,6 @@ static inline void set_default_inode_attr(struct inode * inode, mode_t mode) | |||
| 196 | 198 | ||
| 197 | static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) | 199 | static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) |
| 198 | { | 200 | { |
| 199 | inode->i_mode = iattr->ia_mode; | ||
| 200 | inode->i_uid = iattr->ia_uid; | 201 | inode->i_uid = iattr->ia_uid; |
| 201 | inode->i_gid = iattr->ia_gid; | 202 | inode->i_gid = iattr->ia_gid; |
| 202 | inode->i_atime = iattr->ia_atime; | 203 | inode->i_atime = iattr->ia_atime; |
| @@ -227,38 +228,56 @@ static int sysfs_count_nlink(struct sysfs_dirent *sd) | |||
| 227 | return nr + 2; | 228 | return nr + 2; |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 231 | static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode) | ||
| 232 | { | ||
| 233 | struct sysfs_inode_attrs *iattrs = sd->s_iattr; | ||
| 234 | |||
| 235 | inode->i_mode = sd->s_mode; | ||
| 236 | if (iattrs) { | ||
| 237 | /* sysfs_dirent has non-default attributes | ||
| 238 | * get them from persistent copy in sysfs_dirent | ||
| 239 | */ | ||
| 240 | set_inode_attr(inode, &iattrs->ia_iattr); | ||
| 241 | security_inode_notifysecctx(inode, | ||
| 242 | iattrs->ia_secdata, | ||
| 243 | iattrs->ia_secdata_len); | ||
| 244 | } | ||
| 245 | |||
| 246 | if (sysfs_type(sd) == SYSFS_DIR) | ||
| 247 | inode->i_nlink = sysfs_count_nlink(sd); | ||
| 248 | } | ||
| 249 | |||
| 250 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | ||
| 251 | { | ||
| 252 | struct sysfs_dirent *sd = dentry->d_fsdata; | ||
| 253 | struct inode *inode = dentry->d_inode; | ||
| 254 | |||
| 255 | mutex_lock(&sysfs_mutex); | ||
| 256 | sysfs_refresh_inode(sd, inode); | ||
| 257 | mutex_unlock(&sysfs_mutex); | ||
| 258 | |||
| 259 | generic_fillattr(inode, stat); | ||
| 260 | return 0; | ||
| 261 | } | ||
| 262 | |||
| 230 | static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) | 263 | static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) |
| 231 | { | 264 | { |
| 232 | struct bin_attribute *bin_attr; | 265 | struct bin_attribute *bin_attr; |
| 233 | struct sysfs_inode_attrs *iattrs; | ||
| 234 | 266 | ||
| 235 | inode->i_private = sysfs_get(sd); | 267 | inode->i_private = sysfs_get(sd); |
| 236 | inode->i_mapping->a_ops = &sysfs_aops; | 268 | inode->i_mapping->a_ops = &sysfs_aops; |
| 237 | inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; | 269 | inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; |
| 238 | inode->i_op = &sysfs_inode_operations; | 270 | inode->i_op = &sysfs_inode_operations; |
| 239 | inode->i_ino = sd->s_ino; | ||
| 240 | lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); | 271 | lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); |
| 241 | 272 | ||
| 242 | iattrs = sd->s_iattr; | 273 | set_default_inode_attr(inode, sd->s_mode); |
| 243 | if (iattrs) { | 274 | sysfs_refresh_inode(sd, inode); |
| 244 | /* sysfs_dirent has non-default attributes | ||
| 245 | * get them for the new inode from persistent copy | ||
| 246 | * in sysfs_dirent | ||
| 247 | */ | ||
| 248 | set_inode_attr(inode, &iattrs->ia_iattr); | ||
| 249 | if (iattrs->ia_secdata) | ||
| 250 | security_inode_notifysecctx(inode, | ||
| 251 | iattrs->ia_secdata, | ||
| 252 | iattrs->ia_secdata_len); | ||
| 253 | } else | ||
| 254 | set_default_inode_attr(inode, sd->s_mode); | ||
| 255 | 275 | ||
| 256 | /* initialize inode according to type */ | 276 | /* initialize inode according to type */ |
| 257 | switch (sysfs_type(sd)) { | 277 | switch (sysfs_type(sd)) { |
| 258 | case SYSFS_DIR: | 278 | case SYSFS_DIR: |
| 259 | inode->i_op = &sysfs_dir_inode_operations; | 279 | inode->i_op = &sysfs_dir_inode_operations; |
| 260 | inode->i_fop = &sysfs_dir_operations; | 280 | inode->i_fop = &sysfs_dir_operations; |
| 261 | inode->i_nlink = sysfs_count_nlink(sd); | ||
| 262 | break; | 281 | break; |
| 263 | case SYSFS_KOBJ_ATTR: | 282 | case SYSFS_KOBJ_ATTR: |
| 264 | inode->i_size = PAGE_SIZE; | 283 | inode->i_size = PAGE_SIZE; |
| @@ -341,3 +360,14 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name) | |||
| 341 | else | 360 | else |
| 342 | return -ENOENT; | 361 | return -ENOENT; |
| 343 | } | 362 | } |
| 363 | |||
| 364 | int sysfs_permission(struct inode *inode, int mask) | ||
| 365 | { | ||
| 366 | struct sysfs_dirent *sd = inode->i_private; | ||
| 367 | |||
| 368 | mutex_lock(&sysfs_mutex); | ||
| 369 | sysfs_refresh_inode(sd, inode); | ||
| 370 | mutex_unlock(&sysfs_mutex); | ||
| 371 | |||
| 372 | return generic_permission(inode, mask, NULL); | ||
| 373 | } | ||
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 11374182ca67..c5eff49fa41b 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
| @@ -214,6 +214,9 @@ const struct inode_operations sysfs_symlink_inode_operations = { | |||
| 214 | .readlink = generic_readlink, | 214 | .readlink = generic_readlink, |
| 215 | .follow_link = sysfs_follow_link, | 215 | .follow_link = sysfs_follow_link, |
| 216 | .put_link = sysfs_put_link, | 216 | .put_link = sysfs_put_link, |
| 217 | .setattr = sysfs_setattr, | ||
| 218 | .getattr = sysfs_getattr, | ||
| 219 | .permission = sysfs_permission, | ||
| 217 | }; | 220 | }; |
| 218 | 221 | ||
| 219 | 222 | ||
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index a96d9678ae73..12ccc07459d8 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
| @@ -156,7 +156,9 @@ static inline void __sysfs_put(struct sysfs_dirent *sd) | |||
| 156 | struct inode *sysfs_get_inode(struct sysfs_dirent *sd); | 156 | struct inode *sysfs_get_inode(struct sysfs_dirent *sd); |
| 157 | void sysfs_delete_inode(struct inode *inode); | 157 | void sysfs_delete_inode(struct inode *inode); |
| 158 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); | 158 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); |
| 159 | int sysfs_permission(struct inode *inode, int mask); | ||
| 159 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | 160 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); |
| 161 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); | ||
| 160 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 162 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
| 161 | size_t size, int flags); | 163 | size_t size, int flags); |
| 162 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); | 164 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); |
