extern void                     affs_drop_inode(struct inode *inode);
 extern void                     affs_delete_inode(struct inode *inode);
 extern void                     affs_clear_inode(struct inode *inode);
-extern void                     affs_read_inode(struct inode *inode);
+extern struct inode            *affs_iget(struct super_block *sb,
+                                       unsigned long ino);
 extern int                      affs_write_inode(struct inode *inode, int);
 extern int                      affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);
 
 
                if (!link_bh)
                        goto done;
 
-               dir = iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent));
-               if (!dir)
+               dir = affs_iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent));
+               if (IS_ERR(dir)) {
+                       retval = PTR_ERR(dir);
                        goto done;
+               }
 
                affs_lock_dir(dir);
                affs_fix_dcache(dentry, link_ino);
 
 extern const struct inode_operations affs_symlink_inode_operations;
 extern struct timezone sys_tz;
 
-void
-affs_read_inode(struct inode *inode)
+struct inode *affs_iget(struct super_block *sb, unsigned long ino)
 {
-       struct super_block      *sb = inode->i_sb;
        struct affs_sb_info     *sbi = AFFS_SB(sb);
        struct buffer_head      *bh;
        struct affs_head        *head;
        struct affs_tail        *tail;
+       struct inode            *inode;
        u32                      block;
        u32                      size;
        u32                      prot;
        u16                      id;
 
-       pr_debug("AFFS: read_inode(%lu)\n",inode->i_ino);
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
+       pr_debug("AFFS: affs_iget(%lu)\n", inode->i_ino);
 
        block = inode->i_ino;
        bh = affs_bread(sb, block);
                         sys_tz.tz_minuteswest * 60;
        inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
        affs_brelse(bh);
-       return;
+       unlock_new_inode(inode);
+       return inode;
 
 bad_inode:
-       make_bad_inode(inode);
        affs_brelse(bh);
-       return;
+       iget_failed(inode);
+       return ERR_PTR(-EIO);
 }
 
 int
 
        affs_lock_dir(dir);
        bh = affs_find_entry(dir, dentry);
        affs_unlock_dir(dir);
-       if (IS_ERR(bh)) {
+       if (IS_ERR(bh))
                return ERR_CAST(bh);
-       }
        if (bh) {
                u32 ino = bh->b_blocknr;
 
                        ino = be32_to_cpu(AFFS_TAIL(sb, bh)->original);
                }
                affs_brelse(bh);
-               inode = iget(sb, ino);
-               if (!inode) {
-                       return ERR_PTR(-EACCES);
-               }
+               inode = affs_iget(sb, ino);
+               if (IS_ERR(inode))
+                       return ERR_PTR(PTR_ERR(inode));
        }
        dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations;
        d_add(dentry, inode);
 
 static const struct super_operations affs_sops = {
        .alloc_inode    = affs_alloc_inode,
        .destroy_inode  = affs_destroy_inode,
-       .read_inode     = affs_read_inode,
        .write_inode    = affs_write_inode,
        .put_inode      = affs_put_inode,
        .drop_inode     = affs_drop_inode,
        unsigned long            mount_flags;
        int                      tmp_flags;     /* fix remount prototype... */
        u8                       sig[4];
+       int                      ret = -EINVAL;
 
        pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");
 
 
        /* set up enough so that it can read an inode */
 
-       root_inode = iget(sb, root_block);
+       root_inode = affs_iget(sb, root_block);
+       if (IS_ERR(root_inode)) {
+               ret = PTR_ERR(root_inode);
+               goto out_error_noinode;
+       }
+
        sb->s_root = d_alloc_root(root_inode);
        if (!sb->s_root) {
                printk(KERN_ERR "AFFS: Get root inode failed\n");
 out_error:
        if (root_inode)
                iput(root_inode);
+out_error_noinode:
        kfree(sbi->s_bitmap);
        affs_brelse(root_bh);
        kfree(sbi->s_prefix);
        kfree(sbi);
        sb->s_fs_info = NULL;
-       return -EINVAL;
+       return ret;
 }
 
 static int