aboutsummaryrefslogtreecommitdiffstats
path: root/fs/openpromfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/openpromfs')
-rw-r--r--fs/openpromfs/inode.c45
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
41static struct inode *openprom_iget(struct super_block *sb, ino_t ino);
42
41static inline struct op_inode_info *OP_I(struct inode *inode) 43static 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
228found: 230found:
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
351static void openprom_read_inode(struct inode * inode) 353static 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
361static int openprom_remount(struct super_block *sb, int *flags, char *data) 372static 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)
367static const struct super_operations openprom_sops = { 378static 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
412out_no_root_dentry:
413 iput(root_inode);
414 ret = -ENOMEM;
399out_no_root: 415out_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
405static int openprom_get_sb(struct file_system_type *fs_type, 420static int openprom_get_sb(struct file_system_type *fs_type,