diff options
-rw-r--r-- | fs/jffs2/dir.c | 6 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 56 | ||||
-rw-r--r-- | fs/jffs2/os-linux.h | 2 | ||||
-rw-r--r-- | fs/jffs2/super.c | 1 |
4 files changed, 39 insertions, 26 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 787e392ffd41..f948f7e6ec82 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -101,10 +101,10 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | |||
101 | ino = fd->ino; | 101 | ino = fd->ino; |
102 | up(&dir_f->sem); | 102 | up(&dir_f->sem); |
103 | if (ino) { | 103 | if (ino) { |
104 | inode = iget(dir_i->i_sb, ino); | 104 | inode = jffs2_iget(dir_i->i_sb, ino); |
105 | if (!inode) { | 105 | if (IS_ERR(inode)) { |
106 | printk(KERN_WARNING "iget() failed for ino #%u\n", ino); | 106 | printk(KERN_WARNING "iget() failed for ino #%u\n", ino); |
107 | return (ERR_PTR(-EIO)); | 107 | return ERR_CAST(inode); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index d2e06f7ea96f..6d1eaddde0ec 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -230,16 +230,23 @@ void jffs2_clear_inode (struct inode *inode) | |||
230 | jffs2_do_clear_inode(c, f); | 230 | jffs2_do_clear_inode(c, f); |
231 | } | 231 | } |
232 | 232 | ||
233 | void jffs2_read_inode (struct inode *inode) | 233 | struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) |
234 | { | 234 | { |
235 | struct jffs2_inode_info *f; | 235 | struct jffs2_inode_info *f; |
236 | struct jffs2_sb_info *c; | 236 | struct jffs2_sb_info *c; |
237 | struct jffs2_raw_inode latest_node; | 237 | struct jffs2_raw_inode latest_node; |
238 | union jffs2_device_node jdev; | 238 | union jffs2_device_node jdev; |
239 | struct inode *inode; | ||
239 | dev_t rdev = 0; | 240 | dev_t rdev = 0; |
240 | int ret; | 241 | int ret; |
241 | 242 | ||
242 | D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); | 243 | D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino)); |
244 | |||
245 | inode = iget_locked(sb, ino); | ||
246 | if (!inode) | ||
247 | return ERR_PTR(-ENOMEM); | ||
248 | if (!(inode->i_state & I_NEW)) | ||
249 | return inode; | ||
243 | 250 | ||
244 | f = JFFS2_INODE_INFO(inode); | 251 | f = JFFS2_INODE_INFO(inode); |
245 | c = JFFS2_SB_INFO(inode->i_sb); | 252 | c = JFFS2_SB_INFO(inode->i_sb); |
@@ -250,9 +257,9 @@ void jffs2_read_inode (struct inode *inode) | |||
250 | ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); | 257 | ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); |
251 | 258 | ||
252 | if (ret) { | 259 | if (ret) { |
253 | make_bad_inode(inode); | ||
254 | up(&f->sem); | 260 | up(&f->sem); |
255 | return; | 261 | iget_failed(inode); |
262 | return ERR_PTR(ret); | ||
256 | } | 263 | } |
257 | inode->i_mode = jemode_to_cpu(latest_node.mode); | 264 | inode->i_mode = jemode_to_cpu(latest_node.mode); |
258 | inode->i_uid = je16_to_cpu(latest_node.uid); | 265 | inode->i_uid = je16_to_cpu(latest_node.uid); |
@@ -303,19 +310,14 @@ void jffs2_read_inode (struct inode *inode) | |||
303 | if (f->metadata->size != sizeof(jdev.old) && | 310 | if (f->metadata->size != sizeof(jdev.old) && |
304 | f->metadata->size != sizeof(jdev.new)) { | 311 | f->metadata->size != sizeof(jdev.new)) { |
305 | printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size); | 312 | printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size); |
306 | up(&f->sem); | 313 | goto error_io; |
307 | jffs2_do_clear_inode(c, f); | ||
308 | make_bad_inode(inode); | ||
309 | return; | ||
310 | } | 314 | } |
311 | D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); | 315 | D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); |
312 | if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) { | 316 | ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size); |
317 | if (ret < 0) { | ||
313 | /* Eep */ | 318 | /* Eep */ |
314 | printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); | 319 | printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); |
315 | up(&f->sem); | 320 | goto error; |
316 | jffs2_do_clear_inode(c, f); | ||
317 | make_bad_inode(inode); | ||
318 | return; | ||
319 | } | 321 | } |
320 | if (f->metadata->size == sizeof(jdev.old)) | 322 | if (f->metadata->size == sizeof(jdev.old)) |
321 | rdev = old_decode_dev(je16_to_cpu(jdev.old)); | 323 | rdev = old_decode_dev(je16_to_cpu(jdev.old)); |
@@ -335,6 +337,16 @@ void jffs2_read_inode (struct inode *inode) | |||
335 | up(&f->sem); | 337 | up(&f->sem); |
336 | 338 | ||
337 | D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); | 339 | D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); |
340 | unlock_new_inode(inode); | ||
341 | return inode; | ||
342 | |||
343 | error_io: | ||
344 | ret = -EIO; | ||
345 | error: | ||
346 | up(&f->sem); | ||
347 | jffs2_do_clear_inode(c, f); | ||
348 | iget_failed(inode); | ||
349 | return ERR_PTR(ret); | ||
338 | } | 350 | } |
339 | 351 | ||
340 | void jffs2_dirty_inode(struct inode *inode) | 352 | void jffs2_dirty_inode(struct inode *inode) |
@@ -522,15 +534,16 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | |||
522 | if ((ret = jffs2_do_mount_fs(c))) | 534 | if ((ret = jffs2_do_mount_fs(c))) |
523 | goto out_inohash; | 535 | goto out_inohash; |
524 | 536 | ||
525 | ret = -EINVAL; | ||
526 | |||
527 | D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); | 537 | D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); |
528 | root_i = iget(sb, 1); | 538 | root_i = jffs2_iget(sb, 1); |
529 | if (is_bad_inode(root_i)) { | 539 | if (IS_ERR(root_i)) { |
530 | D1(printk(KERN_WARNING "get root inode failed\n")); | 540 | D1(printk(KERN_WARNING "get root inode failed\n")); |
531 | goto out_root_i; | 541 | ret = PTR_ERR(root_i); |
542 | goto out_root; | ||
532 | } | 543 | } |
533 | 544 | ||
545 | ret = -ENOMEM; | ||
546 | |||
534 | D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); | 547 | D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); |
535 | sb->s_root = d_alloc_root(root_i); | 548 | sb->s_root = d_alloc_root(root_i); |
536 | if (!sb->s_root) | 549 | if (!sb->s_root) |
@@ -546,6 +559,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | |||
546 | 559 | ||
547 | out_root_i: | 560 | out_root_i: |
548 | iput(root_i); | 561 | iput(root_i); |
562 | out_root: | ||
549 | jffs2_free_ino_caches(c); | 563 | jffs2_free_ino_caches(c); |
550 | jffs2_free_raw_node_refs(c); | 564 | jffs2_free_raw_node_refs(c); |
551 | if (jffs2_blocks_use_vmalloc(c)) | 565 | if (jffs2_blocks_use_vmalloc(c)) |
@@ -615,9 +629,9 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, | |||
615 | jffs2_do_unlink() would need the alloc_sem and we have it. | 629 | jffs2_do_unlink() would need the alloc_sem and we have it. |
616 | Just iget() it, and if read_inode() is necessary that's OK. | 630 | Just iget() it, and if read_inode() is necessary that's OK. |
617 | */ | 631 | */ |
618 | inode = iget(OFNI_BS_2SFFJ(c), inum); | 632 | inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum); |
619 | if (!inode) | 633 | if (IS_ERR(inode)) |
620 | return ERR_PTR(-ENOMEM); | 634 | return ERR_CAST(inode); |
621 | } | 635 | } |
622 | if (is_bad_inode(inode)) { | 636 | if (is_bad_inode(inode)) { |
623 | printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", | 637 | printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", |
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index bf64686cf098..1b10d2594092 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -175,7 +175,7 @@ extern const struct inode_operations jffs2_symlink_inode_operations; | |||
175 | /* fs.c */ | 175 | /* fs.c */ |
176 | int jffs2_setattr (struct dentry *, struct iattr *); | 176 | int jffs2_setattr (struct dentry *, struct iattr *); |
177 | int jffs2_do_setattr (struct inode *, struct iattr *); | 177 | int jffs2_do_setattr (struct inode *, struct iattr *); |
178 | void jffs2_read_inode (struct inode *); | 178 | struct inode *jffs2_iget(struct super_block *, unsigned long); |
179 | void jffs2_clear_inode (struct inode *); | 179 | void jffs2_clear_inode (struct inode *); |
180 | void jffs2_dirty_inode(struct inode *inode); | 180 | void jffs2_dirty_inode(struct inode *inode); |
181 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, | 181 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index ffa447511e6a..4677355996cc 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -65,7 +65,6 @@ static const struct super_operations jffs2_super_operations = | |||
65 | { | 65 | { |
66 | .alloc_inode = jffs2_alloc_inode, | 66 | .alloc_inode = jffs2_alloc_inode, |
67 | .destroy_inode =jffs2_destroy_inode, | 67 | .destroy_inode =jffs2_destroy_inode, |
68 | .read_inode = jffs2_read_inode, | ||
69 | .put_super = jffs2_put_super, | 68 | .put_super = jffs2_put_super, |
70 | .write_super = jffs2_write_super, | 69 | .write_super = jffs2_write_super, |
71 | .statfs = jffs2_statfs, | 70 | .statfs = jffs2_statfs, |