Whamcloud - gitweb
LU-3138 osd: ignore unlink inode in index delete
authorwang di <di.wang@intel.com>
Tue, 16 Apr 2013 07:01:39 +0000 (00:01 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 22 Apr 2013 16:14:35 +0000 (12:14 -0400)
We should ignore unlink inode during index delete, otherwise
inode will be become bad inode, which cause unclean delete.

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: Ie3c99cd3bfa71876b34007bb5754360c73fc6f86
Reviewed-on: http://review.whamcloud.com/6072
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/osd-ldiskfs/osd_handler.c
lustre/tests/conf-sanity.sh

index 6ce1f34..6d86a0c 100644 (file)
@@ -3309,11 +3309,38 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
                        /* If Fid is not in dentry, try to get it from LMA */
                        if (rc == -ENODATA) {
                                struct osd_inode_id *id;
                        /* If Fid is not in dentry, try to get it from LMA */
                        if (rc == -ENODATA) {
                                struct osd_inode_id *id;
-
-                               id = &osd_oti_get(env)->oti_id;
-                               rc = osd_ea_fid_get(env, obj,
-                                                   le32_to_cpu(de->inode),
-                                                   fid, id);
+                               struct inode *inode;
+
+                               /* Before trying to get fid from the inode,
+                                * check whether the inode is valid.
+                                *
+                                * If the inode has been deleted, do not go
+                                * ahead to do osd_ea_fid_get, which will set
+                                * the inode to bad inode, which might cause
+                                * the inode to be deleted uncorrectly */
+                               inode = ldiskfs_iget(osd_sb(osd),
+                                                    le32_to_cpu(de->inode));
+                               if (IS_ERR(inode)) {
+                                       CDEBUG(D_INODE, "%s: "DFID"get inode"
+                                              "error.\n", osd_name(osd),
+                                              PFID(fid));
+                                       rc = PTR_ERR(inode);
+                               } else {
+                                       if (likely(inode->i_nlink != 0)) {
+                                               id = &osd_oti_get(env)->oti_id;
+                                               rc = osd_ea_fid_get(env, obj,
+                                                       le32_to_cpu(de->inode),
+                                                                   fid, id);
+                                       } else {
+                                               CDEBUG(D_INFO, "%s: %u "DFID
+                                                      "deleted.\n",
+                                                      osd_name(osd),
+                                                      le32_to_cpu(de->inode),
+                                                      PFID(fid));
+                                               rc = -ESTALE;
+                                       }
+                                       iput(inode);
+                               }
                        }
                        if (rc == 0 &&
                            unlikely(osd_remote_fid(env, osd, fid)))
                        }
                        if (rc == 0 &&
                            unlikely(osd_remote_fid(env, osd, fid)))
index edf5b24..39eb501 100644 (file)
@@ -1822,6 +1822,7 @@ t32_test() {
                        return 1
                }
                shall_cleanup_mdt=false
                        return 1
                }
                shall_cleanup_mdt=false
+
                $r umount -d $tmp/mnt/ost || {
                        error_noexit "Unmounting the OST"
                        return 1
                $r umount -d $tmp/mnt/ost || {
                        error_noexit "Unmounting the OST"
                        return 1