aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/inode.c')
-rw-r--r--fs/sysfs/inode.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index e22db6cd4df7..200e1bf6f932 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -122,8 +122,22 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
122 */ 122 */
123static struct lock_class_key sysfs_inode_imutex_key; 123static struct lock_class_key sysfs_inode_imutex_key;
124 124
125static int sysfs_count_nlink(struct sysfs_dirent *sd)
126{
127 struct sysfs_dirent *child;
128 int nr = 0;
129
130 for (child = sd->s_children; child; child = child->s_sibling)
131 if (sysfs_type(child) == SYSFS_DIR)
132 nr++;
133
134 return nr + 2;
135}
136
125static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 137static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
126{ 138{
139 struct bin_attribute *bin_attr;
140
127 inode->i_blocks = 0; 141 inode->i_blocks = 0;
128 inode->i_mapping->a_ops = &sysfs_aops; 142 inode->i_mapping->a_ops = &sysfs_aops;
129 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; 143 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
@@ -139,6 +153,37 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
139 set_inode_attr(inode, sd->s_iattr); 153 set_inode_attr(inode, sd->s_iattr);
140 } else 154 } else
141 set_default_inode_attr(inode, sd->s_mode); 155 set_default_inode_attr(inode, sd->s_mode);
156
157
158 /* initialize inode according to type */
159 switch (sysfs_type(sd)) {
160 case SYSFS_ROOT:
161 inode->i_op = &sysfs_dir_inode_operations;
162 inode->i_fop = &sysfs_dir_operations;
163 inc_nlink(inode); /* directory, account for "." */
164 break;
165 case SYSFS_DIR:
166 inode->i_op = &sysfs_dir_inode_operations;
167 inode->i_fop = &sysfs_dir_operations;
168 inode->i_nlink = sysfs_count_nlink(sd);
169 break;
170 case SYSFS_KOBJ_ATTR:
171 inode->i_size = PAGE_SIZE;
172 inode->i_fop = &sysfs_file_operations;
173 break;
174 case SYSFS_KOBJ_BIN_ATTR:
175 bin_attr = sd->s_elem.bin_attr.bin_attr;
176 inode->i_size = bin_attr->size;
177 inode->i_fop = &bin_fops;
178 break;
179 case SYSFS_KOBJ_LINK:
180 inode->i_op = &sysfs_symlink_inode_operations;
181 break;
182 default:
183 BUG();
184 }
185
186 unlock_new_inode(inode);
142} 187}
143 188
144/** 189/**
@@ -180,9 +225,6 @@ void sysfs_instantiate(struct dentry *dentry, struct inode *inode)
180{ 225{
181 BUG_ON(!dentry || dentry->d_inode); 226 BUG_ON(!dentry || dentry->d_inode);
182 227
183 if (inode->i_state & I_NEW)
184 unlock_new_inode(inode);
185
186 d_instantiate(dentry, inode); 228 d_instantiate(dentry, inode);
187} 229}
188 230