From 65319af8d2d9b6df6264a41e3a6dd5368c55f3cc Mon Sep 17 00:00:00 2001 From: wang di Date: Sun, 14 Apr 2013 00:57:10 -0700 Subject: [PATCH] LU-3129 osd: Get FID from LMA if not in directory entry 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 Change-Id: I082c330f2b12258e996bdd9820db56a8659540f1 Reviewed-on: http://review.whamcloud.com/5997 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Mike Pershin Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev --- lustre/include/lustre/lustre_idl.h | 6 +++--- lustre/obdecho/echo_client.c | 2 +- lustre/osd-ldiskfs/osd_handler.c | 32 ++++++++++++++++++++++++-------- lustre/tests/conf-sanity.sh | 26 ++++++++++++++++---------- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 6e285bf..0704f12 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -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 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 - * + * * 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) diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index dfe1cee..0bfab5d 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -1114,7 +1114,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d, } 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)); diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 7c52ddc..3501a46 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -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); } - bh = osd_ldiskfs_find_entry(dir, dentry, &de, hlock); + bh = ldiskfs_find_entry(dir, &dentry->d_name, &de, hlock); 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 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 */ diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 1117718..e346b52 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -1356,7 +1356,7 @@ t32_test_cleanup() { $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=$? @@ -1507,7 +1507,6 @@ t32_test() { 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 @@ -1568,21 +1567,28 @@ t32_test() { 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 } - $r2 $TUNEFS --dryrun $(mdsdevname 2) || { + $r $TUNEFS --dryrun $fs2mdsdev || { 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 } @@ -1804,7 +1810,7 @@ t32_test() { 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 } -- 1.8.3.1