Commit 5451f79f authored by David Howells's avatar David Howells Committed by Linus Torvalds

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: default avatarDavid Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c4386c83
...@@ -101,10 +101,10 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, ...@@ -101,10 +101,10 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
ino = fd->ino; ino = fd->ino;
up(&dir_f->sem); up(&dir_f->sem);
if (ino) { if (ino) {
inode = iget(dir_i->i_sb, ino); inode = jffs2_iget(dir_i->i_sb, ino);
if (!inode) { if (IS_ERR(inode)) {
printk(KERN_WARNING "iget() failed for ino #%u\n", ino); printk(KERN_WARNING "iget() failed for ino #%u\n", ino);
return (ERR_PTR(-EIO)); return ERR_CAST(inode);
} }
} }
......
...@@ -230,16 +230,23 @@ void jffs2_clear_inode (struct inode *inode) ...@@ -230,16 +230,23 @@ void jffs2_clear_inode (struct inode *inode)
jffs2_do_clear_inode(c, f); jffs2_do_clear_inode(c, f);
} }
void jffs2_read_inode (struct inode *inode) struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
{ {
struct jffs2_inode_info *f; struct jffs2_inode_info *f;
struct jffs2_sb_info *c; struct jffs2_sb_info *c;
struct jffs2_raw_inode latest_node; struct jffs2_raw_inode latest_node;
union jffs2_device_node jdev; union jffs2_device_node jdev;
struct inode *inode;
dev_t rdev = 0; dev_t rdev = 0;
int ret; int ret;
D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino));
inode = iget_locked(sb, ino);
if (!inode)
return ERR_PTR(-ENOMEM);
if (!(inode->i_state & I_NEW))
return inode;
f = JFFS2_INODE_INFO(inode); f = JFFS2_INODE_INFO(inode);
c = JFFS2_SB_INFO(inode->i_sb); c = JFFS2_SB_INFO(inode->i_sb);
...@@ -250,9 +257,9 @@ void jffs2_read_inode (struct inode *inode) ...@@ -250,9 +257,9 @@ void jffs2_read_inode (struct inode *inode)
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
if (ret) { if (ret) {
make_bad_inode(inode);
up(&f->sem); up(&f->sem);
return; iget_failed(inode);
return ERR_PTR(ret);
} }
inode->i_mode = jemode_to_cpu(latest_node.mode); inode->i_mode = jemode_to_cpu(latest_node.mode);
inode->i_uid = je16_to_cpu(latest_node.uid); inode->i_uid = je16_to_cpu(latest_node.uid);
...@@ -303,19 +310,14 @@ void jffs2_read_inode (struct inode *inode) ...@@ -303,19 +310,14 @@ void jffs2_read_inode (struct inode *inode)
if (f->metadata->size != sizeof(jdev.old) && if (f->metadata->size != sizeof(jdev.old) &&
f->metadata->size != sizeof(jdev.new)) { f->metadata->size != sizeof(jdev.new)) {
printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size); printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
up(&f->sem); goto error_io;
jffs2_do_clear_inode(c, f);
make_bad_inode(inode);
return;
} }
D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) { ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size);
if (ret < 0) {
/* Eep */ /* Eep */
printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
up(&f->sem); goto error;
jffs2_do_clear_inode(c, f);
make_bad_inode(inode);
return;
} }
if (f->metadata->size == sizeof(jdev.old)) if (f->metadata->size == sizeof(jdev.old))
rdev = old_decode_dev(je16_to_cpu(jdev.old)); rdev = old_decode_dev(je16_to_cpu(jdev.old));
...@@ -335,6 +337,16 @@ void jffs2_read_inode (struct inode *inode) ...@@ -335,6 +337,16 @@ void jffs2_read_inode (struct inode *inode)
up(&f->sem); up(&f->sem);
D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
unlock_new_inode(inode);
return inode;
error_io:
ret = -EIO;
error:
up(&f->sem);
jffs2_do_clear_inode(c, f);
iget_failed(inode);
return ERR_PTR(ret);
} }
void jffs2_dirty_inode(struct inode *inode) 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,15 +534,16 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
if ((ret = jffs2_do_mount_fs(c))) if ((ret = jffs2_do_mount_fs(c)))
goto out_inohash; goto out_inohash;
ret = -EINVAL;
D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
root_i = iget(sb, 1); root_i = jffs2_iget(sb, 1);
if (is_bad_inode(root_i)) { if (IS_ERR(root_i)) {
D1(printk(KERN_WARNING "get root inode failed\n")); D1(printk(KERN_WARNING "get root inode failed\n"));
goto out_root_i; ret = PTR_ERR(root_i);
goto out_root;
} }
ret = -ENOMEM;
D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
sb->s_root = d_alloc_root(root_i); sb->s_root = d_alloc_root(root_i);
if (!sb->s_root) if (!sb->s_root)
...@@ -546,6 +559,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) ...@@ -546,6 +559,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
out_root_i: out_root_i:
iput(root_i); iput(root_i);
out_root:
jffs2_free_ino_caches(c); jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c); jffs2_free_raw_node_refs(c);
if (jffs2_blocks_use_vmalloc(c)) if (jffs2_blocks_use_vmalloc(c))
...@@ -615,9 +629,9 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, ...@@ -615,9 +629,9 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
jffs2_do_unlink() would need the alloc_sem and we have it. jffs2_do_unlink() would need the alloc_sem and we have it.
Just iget() it, and if read_inode() is necessary that's OK. Just iget() it, and if read_inode() is necessary that's OK.
*/ */
inode = iget(OFNI_BS_2SFFJ(c), inum); inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum);
if (!inode) if (IS_ERR(inode))
return ERR_PTR(-ENOMEM); return ERR_CAST(inode);
} }
if (is_bad_inode(inode)) { if (is_bad_inode(inode)) {
printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
......
...@@ -175,7 +175,7 @@ extern const struct inode_operations jffs2_symlink_inode_operations; ...@@ -175,7 +175,7 @@ extern const struct inode_operations jffs2_symlink_inode_operations;
/* fs.c */ /* fs.c */
int jffs2_setattr (struct dentry *, struct iattr *); int jffs2_setattr (struct dentry *, struct iattr *);
int jffs2_do_setattr (struct inode *, struct iattr *); int jffs2_do_setattr (struct inode *, struct iattr *);
void jffs2_read_inode (struct inode *); struct inode *jffs2_iget(struct super_block *, unsigned long);
void jffs2_clear_inode (struct inode *); void jffs2_clear_inode (struct inode *);
void jffs2_dirty_inode(struct inode *inode); void jffs2_dirty_inode(struct inode *inode);
struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
......
...@@ -65,7 +65,6 @@ static const struct super_operations jffs2_super_operations = ...@@ -65,7 +65,6 @@ static const struct super_operations jffs2_super_operations =
{ {
.alloc_inode = jffs2_alloc_inode, .alloc_inode = jffs2_alloc_inode,
.destroy_inode =jffs2_destroy_inode, .destroy_inode =jffs2_destroy_inode,
.read_inode = jffs2_read_inode,
.put_super = jffs2_put_super, .put_super = jffs2_put_super,
.write_super = jffs2_write_super, .write_super = jffs2_write_super,
.statfs = jffs2_statfs, .statfs = jffs2_statfs,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment