aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/sysfs/inode.c37
-rw-r--r--fs/sysfs/mount.c4
-rw-r--r--fs/sysfs/sysfs.h2
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
94struct inode * sysfs_new_inode(mode_t mode) 94static 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
102static 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
112struct 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
33static int sysfs_fill_super(struct super_block *sb, void *data, int silent) 34static 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 @@
2extern struct vfsmount * sysfs_mount; 2extern struct vfsmount * sysfs_mount;
3extern kmem_cache_t *sysfs_dir_cachep; 3extern kmem_cache_t *sysfs_dir_cachep;
4 4
5extern struct inode * sysfs_new_inode(mode_t mode); 5extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); 6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
7 7
8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, 8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,