diff options
Diffstat (limited to 'fs/openpromfs')
-rw-r--r-- | fs/openpromfs/inode.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 6b7ff1618945..d17b4fd204e1 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -38,6 +38,8 @@ struct op_inode_info { | |||
38 | union op_inode_data u; | 38 | union op_inode_data u; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static struct inode *openprom_iget(struct super_block *sb, ino_t ino); | ||
42 | |||
41 | static inline struct op_inode_info *OP_I(struct inode *inode) | 43 | static inline struct op_inode_info *OP_I(struct inode *inode) |
42 | { | 44 | { |
43 | return container_of(inode, struct op_inode_info, vfs_inode); | 45 | return container_of(inode, struct op_inode_info, vfs_inode); |
@@ -226,10 +228,10 @@ static struct dentry *openpromfs_lookup(struct inode *dir, struct dentry *dentry | |||
226 | return ERR_PTR(-ENOENT); | 228 | return ERR_PTR(-ENOENT); |
227 | 229 | ||
228 | found: | 230 | found: |
229 | inode = iget(dir->i_sb, ino); | 231 | inode = openprom_iget(dir->i_sb, ino); |
230 | mutex_unlock(&op_mutex); | 232 | mutex_unlock(&op_mutex); |
231 | if (!inode) | 233 | if (IS_ERR(inode)) |
232 | return ERR_PTR(-EINVAL); | 234 | return ERR_CAST(inode); |
233 | ent_oi = OP_I(inode); | 235 | ent_oi = OP_I(inode); |
234 | ent_oi->type = ent_type; | 236 | ent_oi->type = ent_type; |
235 | ent_oi->u = ent_data; | 237 | ent_oi->u = ent_data; |
@@ -348,14 +350,23 @@ static void openprom_destroy_inode(struct inode *inode) | |||
348 | kmem_cache_free(op_inode_cachep, OP_I(inode)); | 350 | kmem_cache_free(op_inode_cachep, OP_I(inode)); |
349 | } | 351 | } |
350 | 352 | ||
351 | static void openprom_read_inode(struct inode * inode) | 353 | static struct inode *openprom_iget(struct super_block *sb, ino_t ino) |
352 | { | 354 | { |
353 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 355 | struct inode *inode; |
354 | if (inode->i_ino == OPENPROM_ROOT_INO) { | 356 | |
355 | inode->i_op = &openprom_inode_operations; | 357 | inode = iget_locked(sb, ino); |
356 | inode->i_fop = &openprom_operations; | 358 | if (!inode) |
357 | inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; | 359 | return ERR_PTR(-ENOMEM); |
360 | if (inode->i_state & I_NEW) { | ||
361 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | ||
362 | if (inode->i_ino == OPENPROM_ROOT_INO) { | ||
363 | inode->i_op = &openprom_inode_operations; | ||
364 | inode->i_fop = &openprom_operations; | ||
365 | inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; | ||
366 | } | ||
367 | unlock_new_inode(inode); | ||
358 | } | 368 | } |
369 | return inode; | ||
359 | } | 370 | } |
360 | 371 | ||
361 | static int openprom_remount(struct super_block *sb, int *flags, char *data) | 372 | static int openprom_remount(struct super_block *sb, int *flags, char *data) |
@@ -367,7 +378,6 @@ static int openprom_remount(struct super_block *sb, int *flags, char *data) | |||
367 | static const struct super_operations openprom_sops = { | 378 | static const struct super_operations openprom_sops = { |
368 | .alloc_inode = openprom_alloc_inode, | 379 | .alloc_inode = openprom_alloc_inode, |
369 | .destroy_inode = openprom_destroy_inode, | 380 | .destroy_inode = openprom_destroy_inode, |
370 | .read_inode = openprom_read_inode, | ||
371 | .statfs = simple_statfs, | 381 | .statfs = simple_statfs, |
372 | .remount_fs = openprom_remount, | 382 | .remount_fs = openprom_remount, |
373 | }; | 383 | }; |
@@ -376,6 +386,7 @@ static int openprom_fill_super(struct super_block *s, void *data, int silent) | |||
376 | { | 386 | { |
377 | struct inode *root_inode; | 387 | struct inode *root_inode; |
378 | struct op_inode_info *oi; | 388 | struct op_inode_info *oi; |
389 | int ret; | ||
379 | 390 | ||
380 | s->s_flags |= MS_NOATIME; | 391 | s->s_flags |= MS_NOATIME; |
381 | s->s_blocksize = 1024; | 392 | s->s_blocksize = 1024; |
@@ -383,9 +394,11 @@ static int openprom_fill_super(struct super_block *s, void *data, int silent) | |||
383 | s->s_magic = OPENPROM_SUPER_MAGIC; | 394 | s->s_magic = OPENPROM_SUPER_MAGIC; |
384 | s->s_op = &openprom_sops; | 395 | s->s_op = &openprom_sops; |
385 | s->s_time_gran = 1; | 396 | s->s_time_gran = 1; |
386 | root_inode = iget(s, OPENPROM_ROOT_INO); | 397 | root_inode = openprom_iget(s, OPENPROM_ROOT_INO); |
387 | if (!root_inode) | 398 | if (IS_ERR(root_inode)) { |
399 | ret = PTR_ERR(root_inode); | ||
388 | goto out_no_root; | 400 | goto out_no_root; |
401 | } | ||
389 | 402 | ||
390 | oi = OP_I(root_inode); | 403 | oi = OP_I(root_inode); |
391 | oi->type = op_inode_node; | 404 | oi->type = op_inode_node; |
@@ -393,13 +406,15 @@ static int openprom_fill_super(struct super_block *s, void *data, int silent) | |||
393 | 406 | ||
394 | s->s_root = d_alloc_root(root_inode); | 407 | s->s_root = d_alloc_root(root_inode); |
395 | if (!s->s_root) | 408 | if (!s->s_root) |
396 | goto out_no_root; | 409 | goto out_no_root_dentry; |
397 | return 0; | 410 | return 0; |
398 | 411 | ||
412 | out_no_root_dentry: | ||
413 | iput(root_inode); | ||
414 | ret = -ENOMEM; | ||
399 | out_no_root: | 415 | out_no_root: |
400 | printk("openprom_fill_super: get root inode failed\n"); | 416 | printk("openprom_fill_super: get root inode failed\n"); |
401 | iput(root_inode); | 417 | return ret; |
402 | return -ENOMEM; | ||
403 | } | 418 | } |
404 | 419 | ||
405 | static int openprom_get_sb(struct file_system_type *fs_type, | 420 | static int openprom_get_sb(struct file_system_type *fs_type, |