diff options
Diffstat (limited to 'fs/sysfs')
-rw-r--r-- | fs/sysfs/inode.c | 37 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 4 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 2 |
3 files changed, 35 insertions, 8 deletions
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 400c90be5685..565cac1d4200 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -91,18 +91,42 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
91 | return error; | 91 | return error; |
92 | } | 92 | } |
93 | 93 | ||
94 | struct inode * sysfs_new_inode(mode_t mode) | 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) | ||
95 | { | 113 | { |
96 | struct inode * inode = new_inode(sysfs_sb); | 114 | struct inode * inode = new_inode(sysfs_sb); |
97 | if (inode) { | 115 | if (inode) { |
98 | inode->i_mode = mode; | ||
99 | inode->i_uid = 0; | ||
100 | inode->i_gid = 0; | ||
101 | inode->i_blksize = PAGE_CACHE_SIZE; | 116 | inode->i_blksize = PAGE_CACHE_SIZE; |
102 | inode->i_blocks = 0; | 117 | inode->i_blocks = 0; |
103 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
104 | inode->i_mapping->a_ops = &sysfs_aops; | 118 | inode->i_mapping->a_ops = &sysfs_aops; |
105 | 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); | ||
106 | } | 130 | } |
107 | return inode; | 131 | return inode; |
108 | } | 132 | } |
@@ -113,7 +137,8 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) | |||
113 | struct inode * inode = NULL; | 137 | struct inode * inode = NULL; |
114 | if (dentry) { | 138 | if (dentry) { |
115 | if (!dentry->d_inode) { | 139 | if (!dentry->d_inode) { |
116 | if ((inode = sysfs_new_inode(mode))) { | 140 | struct sysfs_dirent * sd = dentry->d_fsdata; |
141 | if ((inode = sysfs_new_inode(mode, sd))) { | ||
117 | if (dentry->d_parent && dentry->d_parent->d_inode) { | 142 | if (dentry->d_parent && dentry->d_parent->d_inode) { |
118 | struct inode *p_inode = dentry->d_parent->d_inode; | 143 | struct inode *p_inode = dentry->d_parent->d_inode; |
119 | 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/sysfs.h b/fs/sysfs/sysfs.h index e8e9f0c2573e..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 *, |