Whamcloud - gitweb
LU-3129 osd: Get FID from LMA if not in directory entry
authorwang di <di.wang@intel.com>
Sun, 14 Apr 2013 07:57:10 +0000 (00:57 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 17 Apr 2013 05:25:49 +0000 (01:25 -0400)
During deleting agent inode, if the FID can not be found in
directory entries, for example FS upgraded from 1.8 or restored
FS, it should try to get the FID from LMA.

Fix DNE upgrade tests to use a temporary loop device for adding
new MDT, instead of MDTDEV2, which might affect other tests.

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: I082c330f2b12258e996bdd9820db56a8659540f1
Reviewed-on: http://review.whamcloud.com/5997
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
lustre/include/lustre/lustre_idl.h
lustre/obdecho/echo_client.c
lustre/osd-ldiskfs/osd_handler.c
lustre/tests/conf-sanity.sh

index 6e285bf..0704f12 100644 (file)
@@ -1579,19 +1579,19 @@ struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
  *      }
  * to identify the LOV(MDT) object, and lmm_object_seq will
  * be normal_fid, which make it hard to combine these conversion
  *      }
  * to identify the LOV(MDT) object, and lmm_object_seq will
  * be normal_fid, which make it hard to combine these conversion
- * to ostid_to FID. so we will do lmm_oi/fid conversion separately 
+ * to ostid_to FID. so we will do lmm_oi/fid conversion separately
  *
  * We can tell the lmm_oi by this way,
  * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
  * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
  * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
  *      lmm_oi.f_ver = 0
  *
  * We can tell the lmm_oi by this way,
  * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
  * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
  * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
  *      lmm_oi.f_ver = 0
- * 
+ *
  * But currently lmm_oi/lsm_oi does not have any "real" usages,
  * except for printing some information, and the user can always
  * get the real FID from LMA, besides this multiple case check might
  * make swab more complicate. So we will keep using id/seq for lmm_oi.
  * But currently lmm_oi/lsm_oi does not have any "real" usages,
  * except for printing some information, and the user can always
  * get the real FID from LMA, besides this multiple case check might
  * make swab more complicate. So we will keep using id/seq for lmm_oi.
- */ 
+ */
 
 static inline void fid_to_lmm_oi(const struct lu_fid *fid,
                                 struct ost_id *oi)
 
 static inline void fid_to_lmm_oi(const struct lu_fid *fid,
                                 struct ost_id *oi)
index dfe1cee..0bfab5d 100644 (file)
@@ -1114,7 +1114,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d,
         }
         conf->eoc_md = lsmp;
 
         }
         conf->eoc_md = lsmp;
 
-        fid  = &info->eti_fid;
+       fid  = &info->eti_fid;
        rc = ostid_to_fid(fid, &lsm->lsm_oi, 0);
        if (rc != 0)
                GOTO(out, eco = ERR_PTR(rc));
        rc = ostid_to_fid(fid, &lsm->lsm_oi, 0);
        if (rc != 0)
                GOTO(out, eco = ERR_PTR(rc));
index 7c52ddc..3501a46 100644 (file)
@@ -3254,20 +3254,36 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
                down_write(&obj->oo_ext_idx_sem);
         }
 
                down_write(&obj->oo_ext_idx_sem);
         }
 
-        bh = osd_ldiskfs_find_entry(dir, dentry, &de, hlock);
+        bh = ldiskfs_find_entry(dir, &dentry->d_name, &de, hlock);
         if (bh) {
                __u32 ino = 0;
 
         if (bh) {
                __u32 ino = 0;
 
-               /* Tried to delete local agent inode for the entries,
-                * If it tries to delete .., which only happens during
-                * rename or move the dir to /ORPHAN, even .. might
-                * point to the remote parent, but it do not have
-                * local agent inode, so we do not need check .. at all,
-                * Note: we need delete entry first, then inode to keep
-                * lfsck safe. */
+               /* If this is not the ".." entry, it might be a remote DNE
+                * entry and  we need to check if the FID is for a remote
+                * MDT.  If the FID is  not in the directory entry (e.g.
+                * upgraded 1.8 filesystem without dirdata enabled) then
+                * we need to get the FID from the LMA. For a remote directory
+                * there HAS to be an LMA, it cannot be an IGIF inode in this
+                * case.
+                *
+                * Delete the entry before the agent inode in order to
+                * simplify error handling.  At worst an error after deleting
+                * the entry first might leak the agent inode afterward. The
+                * reverse would need filesystem abort in case of error deleting
+                * the entry after the agent had been removed, or leave a
+                * dangling entry pointing at a random inode. */
                if (strcmp((char *)key, dotdot) != 0) {
                        LASSERT(de != NULL);
                        rc = osd_get_fid_from_dentry(de, (struct dt_rec *)fid);
                if (strcmp((char *)key, dotdot) != 0) {
                        LASSERT(de != NULL);
                        rc = osd_get_fid_from_dentry(de, (struct dt_rec *)fid);
+                       /* 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);
+                       }
                        if (rc == 0 &&
                            unlikely(osd_remote_fid(env, osd, fid)))
                                /* Need to delete agent inode */
                        if (rc == 0 &&
                            unlikely(osd_remote_fid(env, osd, fid)))
                                /* Need to delete agent inode */
index 1117718..e346b52 100644 (file)
@@ -1356,7 +1356,7 @@ t32_test_cleanup() {
                $r umount -d $tmp/mnt/mdt || rc=$?
        fi
        if $shall_cleanup_mdt1; then
                $r umount -d $tmp/mnt/mdt || rc=$?
        fi
        if $shall_cleanup_mdt1; then
-               $r2 umount -d $tmp/mnt/mdt1 || rc=$?
+               $r umount -d $tmp/mnt/mdt1 || rc=$?
        fi
        if $shall_cleanup_ost; then
                $r umount -d $tmp/mnt/ost || rc=$?
        fi
        if $shall_cleanup_ost; then
                $r umount -d $tmp/mnt/ost || rc=$?
@@ -1507,7 +1507,6 @@ t32_test() {
        local node=$(facet_active_host $SINGLEMDS)
        local r="do_node $node"
        local node2=$(facet_active_host mds2)
        local node=$(facet_active_host $SINGLEMDS)
        local r="do_node $node"
        local node2=$(facet_active_host mds2)
-       local r2="do_node $node2"
        local tmp=$TMP/t32
        local img_commit
        local img_kernel
        local tmp=$TMP/t32
        local img_commit
        local img_kernel
@@ -1568,21 +1567,28 @@ t32_test() {
        shall_cleanup_mdt=true
 
        if [ "$dne_upgrade" != "no" ]; then
        shall_cleanup_mdt=true
 
        if [ "$dne_upgrade" != "no" ]; then
-               echo "mkfs new MDT...."
-               add mds2 $(mkfs_opts mds2 $(mdsdevname 2) $fsname) --reformat \
-                       $(mdsdevname 2) $(mdsvdevname 2) > /dev/null || {
+               local fs2mdsdev=$(mdsdevname 1_2)
+               local fs2mdsvdev=$(mdsvdevname 1_2)
+
+               echo "mkfs new MDT on ${fs2mdsdev}...."
+               if [ $(facet_fstype mds1) == ldiskfs ]; then
+                       mkfsoptions="--mkfsoptions=\\\"-J size=8\\\""
+               fi
+
+               add fs2mds $(mkfs_opts mds2 $fs2mdsdev $fsname) --reformat \
+                          $mkfsoptions $fs2mdsdev $fs2mdsvdev > /dev/null || {
                        error_noexit "Mkfs new MDT failed"
                        return 1
                }
 
                        error_noexit "Mkfs new MDT failed"
                        return 1
                }
 
-               $r2 $TUNEFS --dryrun $(mdsdevname 2) || {
+               $r $TUNEFS --dryrun $fs2mdsdev || {
                        error_noexit "tunefs.lustre before mounting the MDT"
                        return 1
                }
 
                        error_noexit "tunefs.lustre before mounting the MDT"
                        return 1
                }
 
-               echo "mount new MDT...."
-               $r2 mkdir -p $tmp/mnt/mdt1
-               $r2 mount -t lustre -o $mopts $(mdsdevname 2) $tmp/mnt/mdt1 || {
+               echo "mount new MDT....$fs2mdsdev"
+               $r mkdir -p $tmp/mnt/mdt1
+               $r mount -t lustre -o $mopts $fs2mdsdev $tmp/mnt/mdt1 || {
                        error_noexit "mount mdt1 failed"
                        return 1
                }
                        error_noexit "mount mdt1 failed"
                        return 1
                }
@@ -1804,7 +1810,7 @@ t32_test() {
                shall_cleanup_lustre=false
        else
                if [ "$dne_upgrade" != "no" ]; then
                shall_cleanup_lustre=false
        else
                if [ "$dne_upgrade" != "no" ]; then
-                       $r2 umount -d $tmp/mnt/mdt1 || {
+                       $r umount -d $tmp/mnt/mdt1 || {
                                error_noexit "Unmounting the MDT2"
                                return 1
                        }
                                error_noexit "Unmounting the MDT2"
                                return 1
                        }