aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-02-07 03:15:42 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:28 -0500
commit5451f79f5f817880958ed063864ad268d94ccd1f (patch)
treea1b2a80902be0c83e81c8bcca2e6bf58d824ea98 /fs/jffs2
parentc4386c83bf849c56b1f49951595aeb7c9a719d21 (diff)
iget: stop JFFS2 from using iget() and read_inode()
Stop the JFFS2 filesystem from using iget() and read_inode(). Replace jffs2_read_inode() with jffs2_iget(), and call that instead of iget(). jffs2_iget() then uses iget_locked() directly and returns a proper error code instead of an inode in the event of an error. jffs2_do_fill_super() returns any error incurred when getting the root inode instead of EINVAL. Signed-off-by: David Howells <dhowells@redhat.com> Cc: David Woodhouse <dwmw2@infradead.org> Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/dir.c6
-rw-r--r--fs/jffs2/fs.c56
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jffs2/super.c1
4 files changed, 39 insertions, 26 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 787e392ffd4..f948f7e6ec8 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 d2e06f7ea96..6d1eaddde0e 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
233void jffs2_read_inode (struct inode *inode) 233struct 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
343error_io:
344 ret = -EIO;
345error:
346 up(&f->sem);
347 jffs2_do_clear_inode(c, f);
348 iget_failed(inode);
349 return ERR_PTR(ret);
338} 350}
339 351
340void jffs2_dirty_inode(struct inode *inode) 352void 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);
562out_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 bf64686cf09..1b10d259409 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 */
176int jffs2_setattr (struct dentry *, struct iattr *); 176int jffs2_setattr (struct dentry *, struct iattr *);
177int jffs2_do_setattr (struct inode *, struct iattr *); 177int jffs2_do_setattr (struct inode *, struct iattr *);
178void jffs2_read_inode (struct inode *); 178struct inode *jffs2_iget(struct super_block *, unsigned long);
179void jffs2_clear_inode (struct inode *); 179void jffs2_clear_inode (struct inode *);
180void jffs2_dirty_inode(struct inode *inode); 180void jffs2_dirty_inode(struct inode *inode);
181struct inode *jffs2_new_inode (struct inode *dir_i, int mode, 181struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index ffa447511e6..4677355996c 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,