lkml.org 
[lkml]   [2007]   [Oct]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 20/31] IGET: Stop JFFS2 from using iget() and read_inode() [try #5]
    Date
    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>
    ---

    fs/jffs2/dir.c | 6 +++--
    fs/jffs2/fs.c | 56 ++++++++++++++++++++++++++++++++-------------------
    fs/jffs2/os-linux.h | 2 +-
    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 787e392..f948f7e 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,
    ino = fd->ino;
    up(&dir_f->sem);
    if (ino) {
    - inode = iget(dir_i->i_sb, ino);
    - if (!inode) {
    + inode = jffs2_iget(dir_i->i_sb, ino);
    + if (IS_ERR(inode)) {
    printk(KERN_WARNING "iget() failed for ino #%u\n", ino);
    - return (ERR_PTR(-EIO));
    + return ERR_CAST(inode);
    }
    }

    diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
    index d2e06f7..6d1eadd 100644
    --- a/fs/jffs2/fs.c
    +++ b/fs/jffs2/fs.c
    @@ -230,16 +230,23 @@ void jffs2_clear_inode (struct inode *inode)
    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_sb_info *c;
    struct jffs2_raw_inode latest_node;
    union jffs2_device_node jdev;
    + struct inode *inode;
    dev_t rdev = 0;
    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);
    c = JFFS2_SB_INFO(inode->i_sb);
    @@ -250,9 +257,9 @@ void jffs2_read_inode (struct inode *inode)
    ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);

    if (ret) {
    - make_bad_inode(inode);
    up(&f->sem);
    - return;
    + iget_failed(inode);
    + return ERR_PTR(ret);
    }
    inode->i_mode = jemode_to_cpu(latest_node.mode);
    inode->i_uid = je16_to_cpu(latest_node.uid);
    @@ -303,19 +310,14 @@ void jffs2_read_inode (struct inode *inode)
    if (f->metadata->size != sizeof(jdev.old) &&
    f->metadata->size != sizeof(jdev.new)) {
    printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
    - up(&f->sem);
    - jffs2_do_clear_inode(c, f);
    - make_bad_inode(inode);
    - return;
    + goto error_io;
    }
    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 */
    printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
    - up(&f->sem);
    - jffs2_do_clear_inode(c, f);
    - make_bad_inode(inode);
    - return;
    + goto error;
    }
    if (f->metadata->size == sizeof(jdev.old))
    rdev = old_decode_dev(je16_to_cpu(jdev.old));
    @@ -335,6 +337,16 @@ void jffs2_read_inode (struct inode *inode)
    up(&f->sem);

    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)
    @@ -522,15 +534,16 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
    if ((ret = jffs2_do_mount_fs(c)))
    goto out_inohash;

    - ret = -EINVAL;
    -
    D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
    - root_i = iget(sb, 1);
    - if (is_bad_inode(root_i)) {
    + root_i = jffs2_iget(sb, 1);
    + if (IS_ERR(root_i)) {
    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"));
    sb->s_root = d_alloc_root(root_i);
    if (!sb->s_root)
    @@ -546,6 +559,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)

    out_root_i:
    iput(root_i);
    +out_root:
    jffs2_free_ino_caches(c);
    jffs2_free_raw_node_refs(c);
    if (jffs2_blocks_use_vmalloc(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.
    Just iget() it, and if read_inode() is necessary that's OK.
    */
    - inode = iget(OFNI_BS_2SFFJ(c), inum);
    - if (!inode)
    - return ERR_PTR(-ENOMEM);
    + inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum);
    + if (IS_ERR(inode))
    + return ERR_CAST(inode);
    }
    if (is_bad_inode(inode)) {
    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 bf64686..1b10d25 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;
    /* fs.c */
    int jffs2_setattr (struct dentry *, 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_dirty_inode(struct inode *inode);
    struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
    diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
    index ffa4475..4677355 100644
    --- a/fs/jffs2/super.c
    +++ b/fs/jffs2/super.c
    @@ -65,7 +65,6 @@ static const struct super_operations jffs2_super_operations =
    {
    .alloc_inode = jffs2_alloc_inode,
    .destroy_inode =jffs2_destroy_inode,
    - .read_inode = jffs2_read_inode,
    .put_super = jffs2_put_super,
    .write_super = jffs2_write_super,
    .statfs = jffs2_statfs,
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-10-25 18:47    [W:4.217 / U:0.200 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site