aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/inode.c
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/inode.c
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/inode.c')
-rw-r--r--fs/sysfs/inode.c64
1 files changed, 47 insertions, 17 deletions
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
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}