md_free_lustre_md(sbi->ll_md_exp, &lmd);
        ptlrpc_req_finished(request);
 
-       if (!(root)) {
+       if (IS_ERR(root)) {
                if (lmd.lsm)
                        obd_free_memmd(sbi->ll_dt_exp, &lmd.lsm);
 #ifdef CONFIG_FS_POSIX_ACL
                       lsm_md2->lsm_md_pool_name);
 }
 
-static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
+static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
 {
        struct ll_inode_info *lli = ll_i2info(inode);
        struct lmv_stripe_md *lsm = md->lmv;
-       int idx;
+       int idx, rc;
 
        LASSERT(S_ISDIR(inode->i_mode));
        CDEBUG(D_INODE, "update lsm %p of "DFID"\n", lli->lli_lsm_md,
        /* no striped information from request. */
        if (!lsm) {
                if (!lli->lli_lsm_md) {
-                       return;
+                       return 0;
                } else if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_MIGRATE) {
                        /*
                         * migration is done, the temporay MIGRATE layout has
                               PFID(ll_inode2fid(inode)));
                        lmv_free_memmd(lli->lli_lsm_md);
                        lli->lli_lsm_md = NULL;
-                       return;
+                       return 0;
                } else {
                        /*
                         * The lustre_md from req does not include stripeEA,
                         * see ll_md_setattr
                         */
-                       return;
+                       return 0;
                }
        }
 
        /* set the directory layout */
        if (!lli->lli_lsm_md) {
-               int rc;
-
                rc = ll_init_lsm_md(inode, md);
-               if (rc) {
-                       CERROR("%s: init "DFID" failed: rc = %d\n",
-                              ll_get_fsname(inode->i_sb, NULL, 0),
-                              PFID(&lli->lli_fid), rc);
-                       return;
-               }
+               if (rc)
+                       return rc;
+
                lli->lli_lsm_md = lsm;
                /*
                 * set lsm_md to NULL, so the following free lustre_md
                md->lmv = NULL;
                CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
                       lsm->lsm_md_magic, PFID(ll_inode2fid(inode)));
-               return;
+               return 0;
        }
 
        /* Compare the old and new stripe information */
                       lli->lli_lsm_md->lsm_md_layout_version,
                       lsm->lsm_md_pool_name,
                       lli->lli_lsm_md->lsm_md_pool_name);
-               return;
+               return -EIO;
        }
 
        for (idx = 0; idx < lli->lli_lsm_md->lsm_md_stripe_count; idx++) {
                               ll_get_fsname(inode->i_sb, NULL, 0), idx,
                               PFID(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid),
                               PFID(&lsm->lsm_md_oinfo[idx].lmo_fid));
-                       return;
+                       return -EIO;
                }
        }
 
-       md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
-                        md->body, ll_md_blocking_ast);
+       rc = md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
+                             md->body, ll_md_blocking_ast);
+       return rc;
 }
 
 void ll_clear_inode(struct inode *inode)
 
        if (S_ISDIR(inode->i_mode))
                ll_dir_clear_lsm_md(inode);
-       else
+       if (S_ISREG(inode->i_mode) && !is_bad_inode(inode))
                LASSERT(list_empty(&lli->lli_agl_list));
 
        /*
        op_data->op_handle = md.body->handle;
        op_data->op_ioepoch = md.body->ioepoch;
 
-       ll_update_inode(inode, &md);
+       rc = ll_update_inode(inode, &md);
        ptlrpc_req_finished(request);
 
        return rc;
        mutex_unlock(&lli->lli_size_mutex);
 }
 
-void ll_update_inode(struct inode *inode, struct lustre_md *md)
+int ll_update_inode(struct inode *inode, struct lustre_md *md)
 {
        struct ll_inode_info *lli = ll_i2info(inode);
        struct mdt_body *body = md->body;
                        lli->lli_maxbytes = MAX_LFS_FILESIZE;
        }
 
-       if (S_ISDIR(inode->i_mode))
-               ll_update_lsm_md(inode, md);
+       if (S_ISDIR(inode->i_mode)) {
+               int rc;
+
+               rc = ll_update_lsm_md(inode, md);
+               if (rc)
+                       return rc;
+       }
 
 #ifdef CONFIG_FS_POSIX_ACL
        if (body->valid & OBD_MD_FLACL) {
                if (body->t_state & MS_RESTORE)
                        lli->lli_flags |= LLIF_FILE_RESTORING;
        }
+
+       return 0;
 }
 
-void ll_read_inode2(struct inode *inode, void *opaque)
+int ll_read_inode2(struct inode *inode, void *opaque)
 {
        struct lustre_md *md = opaque;
        struct ll_inode_info *lli = ll_i2info(inode);
+       int rc;
 
        CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
               PFID(&lli->lli_fid), inode);
        LTIME_S(inode->i_atime) = 0;
        LTIME_S(inode->i_ctime) = 0;
        inode->i_rdev = 0;
-       ll_update_inode(inode, md);
+       rc = ll_update_inode(inode, md);
+       if (rc)
+               return rc;
 
        /* OIDEBUG(inode); */
 
                init_special_inode(inode, inode->i_mode,
                                   inode->i_rdev);
        }
+
+       return 0;
 }
 
 void ll_delete_inode(struct inode *inode)
                goto cleanup;
 
        if (*inode) {
-               ll_update_inode(*inode, &md);
+               rc = ll_update_inode(*inode, &md);
+               if (rc)
+                       goto out;
        } else {
                LASSERT(sb);
 
                *inode = ll_iget(sb, cl_fid_build_ino(&md.body->fid1,
                                             sbi->ll_flags & LL_SBI_32BIT_API),
                                 &md);
-               if (!*inode) {
+               if (IS_ERR(*inode)) {
 #ifdef CONFIG_FS_POSIX_ACL
                        if (md.posix_acl) {
                                posix_acl_release(md.posix_acl);
 
        return 0;
 }
 
-/*
- * Get an inode by inode number (already instantiated by the intent lookup).
- * Returns inode or NULL
+/**
+ * Get an inode by inode number(@hash), which is already instantiated by
+ * the intent lookup).
  */
 struct inode *ll_iget(struct super_block *sb, ino_t hash,
                      struct lustre_md *md)
 {
        struct inode     *inode;
+       int rc = 0;
 
        LASSERT(hash != 0);
        inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
-
-       if (inode) {
-               if (inode->i_state & I_NEW) {
-                       int rc = 0;
-
-                       ll_read_inode2(inode, md);
-                       if (S_ISREG(inode->i_mode) &&
-                           !ll_i2info(inode)->lli_clob) {
-                               CDEBUG(D_INODE,
-                                      "%s: apply lsm %p to inode " DFID ".\n",
-                                      ll_get_fsname(sb, NULL, 0), md->lsm,
-                                      PFID(ll_inode2fid(inode)));
-                               rc = cl_file_inode_init(inode, md);
-                       }
-                       if (rc != 0) {
-                               iget_failed(inode);
-                               inode = NULL;
-                       } else {
-                               unlock_new_inode(inode);
-                       }
-               } else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
-                       ll_update_inode(inode, md);
-                       CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p)\n",
-                              PFID(&md->body->fid1), inode);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+
+       if (inode->i_state & I_NEW) {
+               rc = ll_read_inode2(inode, md);
+               if (!rc && S_ISREG(inode->i_mode) &&
+                   !ll_i2info(inode)->lli_clob) {
+                       CDEBUG(D_INODE, "%s: apply lsm %p to inode "DFID"\n",
+                              ll_get_fsname(sb, NULL, 0), md->lsm,
+                              PFID(ll_inode2fid(inode)));
+                       rc = cl_file_inode_init(inode, md);
+               }
+               if (rc) {
+                       make_bad_inode(inode);
+                       unlock_new_inode(inode);
+                       iput(inode);
+                       inode = ERR_PTR(rc);
+               } else {
+                       unlock_new_inode(inode);
+               }
+       } else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
+               rc = ll_update_inode(inode, md);
+               CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p): rc = %d\n",
+                      PFID(&md->body->fid1), inode, rc);
+               if (rc) {
+                       make_bad_inode(inode);
+                       iput(inode);
+                       inode = ERR_PTR(rc);
                }
        }
        return inode;