aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-11-20 19:08:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:24:54 -0500
commite61ab4ae48fbf477f5b9fcbec9e1b8dc789920d0 (patch)
tree70199a29a97a4f5ba8aea4340bc828da4f550e5d /fs/sysfs
parentc099aacd48ee73bd2de7da029e536ed005d72a43 (diff)
sysfs: Implement sysfs_getattr & sysfs_permission
With the implementation of sysfs_getattr and sysfs_permission sysfs becomes able to lazily propogate inode attribute changes from the sysfs_dirents to the vfs inodes. This paves the way for deleting significant chunks of now unnecessary code. While doing this we did not reference sysfs_setattr from sysfs_symlink_inode_operations so I added along with sysfs_getattr and sysfs_permission. Acked-by: Tejun Heo <tj@kernel.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/dir.c2
-rw-r--r--fs/sysfs/inode.c64
-rw-r--r--fs/sysfs/symlink.c3
-rw-r--r--fs/sysfs/sysfs.h2
4 files changed, 54 insertions, 17 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 36ee6d81795..e319379d36d 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
801const struct inode_operations sysfs_dir_inode_operations = { 801const 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 76e977c300f..1ffd5559926 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
39static const struct inode_operations sysfs_inode_operations ={ 39static 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
197static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) 199static 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
231static 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
250int 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
230static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 263static 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
364int 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 11374182ca6..c5eff49fa41 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 a96d9678ae7..12ccc07459d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -156,7 +156,9 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
156struct inode *sysfs_get_inode(struct sysfs_dirent *sd); 156struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
157void sysfs_delete_inode(struct inode *inode); 157void sysfs_delete_inode(struct inode *inode);
158int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); 158int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
159int sysfs_permission(struct inode *inode, int mask);
159int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); 160int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
161int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
160int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, 162int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
161 size_t size, int flags); 163 size_t size, int flags);
162int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); 164int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);