Whamcloud - gitweb
LU-3190 mdd: not return linkEA for dead obj
authorwang di <di.wang@intel.com>
Thu, 2 May 2013 13:23:59 +0000 (06:23 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 8 May 2013 17:57:42 +0000 (13:57 -0400)
1. Not return linkEA for dead object.
2. Check lma_self_fid to match object FID after get
real LMA from the object.
3. clear oi cache during oi delete.
4. correct error value if ldlm_handle_enqueue return
some value other than ldlm_err_t(for example -ESTALE).

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: I1d2345eb01ff58584ffba31f86bb408396780aeb
Reviewed-on: http://review.whamcloud.com/6252
Tested-by: Hudson
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
lustre/ldlm/ldlm_lockd.c
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_object.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_oi.c

index 211380a..998c463 100644 (file)
@@ -1346,8 +1346,11 @@ existing_lock:
                 lock->l_req_extent = lock->l_policy_data.l_extent;
 
        err = ldlm_lock_enqueue(ns, &lock, cookie, &flags);
-        if (err)
-                GOTO(out, err);
+       if (err) {
+               if ((int)err < 0)
+                       rc = (int)err;
+               GOTO(out, err);
+       }
 
         dlm_rep = req_capsule_server_get(&req->rq_pill, &RMF_DLM_REP);
        dlm_rep->lock_flags = ldlm_flags_to_wire(flags);
index e8b2f6d..b835757 100644 (file)
@@ -1287,7 +1287,7 @@ int mdd_finish_unlink(const struct lu_env *env,
 
         LASSERT(mdd_write_locked(env, obj) != 0);
 
-       if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_dir)) {
+       if (ma->ma_attr.la_nlink == 0 || is_dir) {
                 obj->mod_flags |= DEAD_OBJ;
                 /* add new orphan and the object
                  * will be deleted during mdd_close() */
index 1ffc2d8..42f514d 100644 (file)
@@ -273,6 +273,12 @@ static int mdd_xattr_get(const struct lu_env *env,
                 return -ENOENT;
         }
 
+       /* If the object has been delete from the namespace, then
+        * get linkEA should return -ENOENT as well */
+       if (unlikely((mdd_obj->mod_flags & (DEAD_OBJ | ORPHAN_OBJ)) &&
+                     strcmp(name, XATTR_NAME_LINK) == 0))
+               RETURN(-ENOENT);
+
         mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
         rc = mdo_xattr_get(env, mdd_obj, buf, name,
                            mdd_object_capa(env, mdd_obj));
index f5d5718..a9b1c7e 100644 (file)
@@ -463,13 +463,25 @@ static int osd_check_lma(const struct lu_env *env, struct osd_object *obj)
                lustre_lma_swab(lma);
                if (unlikely((lma->lma_incompat & ~LMA_INCOMPAT_SUPP) ||
                             CFS_FAIL_CHECK(OBD_FAIL_OSD_LMA_INCOMPAT))) {
+                       rc = -EOPNOTSUPP;
                        CWARN("%s: unsupported incompat LMA feature(s) %#x for "
-                             "fid = "DFID", ino = %lu\n",
+                             "fid = "DFID", ino = %lu: rc = %d\n",
                              osd_obj2dev(obj)->od_svname,
                              lma->lma_incompat & ~LMA_INCOMPAT_SUPP,
                              PFID(lu_object_fid(&obj->oo_dt.do_lu)),
-                             obj->oo_inode->i_ino);
-                       rc = -EOPNOTSUPP;
+                             obj->oo_inode->i_ino, rc);
+               }
+               if (unlikely(!lu_fid_eq(lu_object_fid(&obj->oo_dt.do_lu),
+                                       &lma->lma_self_fid))) {
+                       CDEBUG(D_INODE, "%s: FID "DFID" != self_fid "DFID"\n",
+                              osd_obj2dev(obj)->od_svname,
+                              PFID(lu_object_fid(&obj->oo_dt.do_lu)),
+                              PFID(&lma->lma_self_fid));
+                       if (obj->oo_inode != NULL) {
+                               iput(obj->oo_inode);
+                               obj->oo_inode = NULL;
+                       }
+                       rc = -ESTALE;
                }
        } else if (rc == -ENODATA) {
                /* haven't initialize LMA xattr */
@@ -500,8 +512,11 @@ static int osd_object_init(const struct lu_env *env, struct lu_object *l,
        result = osd_fid_lookup(env, obj, lu_object_fid(l), conf);
        obj->oo_dt.do_body_ops = &osd_body_ops_new;
        if (result == 0 && obj->oo_inode != NULL) {
-               osd_object_init0(obj);
                result = osd_check_lma(env, obj);
+               if (result != 0)
+                       return result;
+
+               osd_object_init0(obj);
        }
 
        LINVRNT(osd_invariant(obj));
@@ -3773,6 +3788,19 @@ static int osd_fail_fid_lookup(struct osd_thread_info *oti,
        return rc;
 }
 
+static int osd_add_oi_cache(struct osd_thread_info *info,
+                           struct osd_device *osd,
+                           struct osd_inode_id *id,
+                           struct lu_fid *fid)
+{
+       CDEBUG(D_INODE, "add "DFID" %u:%u to info %p\n", PFID(fid),
+              id->oii_ino, id->oii_gen, info);
+       info->oti_cache.oic_lid = *id;
+       info->oti_cache.oic_fid = *fid;
+
+       return 0;
+}
+
 /**
  * Calls ->lookup() to find dentry. From dentry get inode and
  * read inode's ea to get fid. This is required for  interoperability
@@ -3836,8 +3864,10 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
                        GOTO(out, rc);
                }
 
-               oic->oic_lid = *id;
-               oic->oic_fid = *fid;
+               rc = osd_add_oi_cache(osd_oti_get(env), osd_obj2dev(obj), id,
+                                     fid);
+               if (rc != 0)
+                       GOTO(out, rc);
                if ((scrub->os_pos_current <= ino) &&
                    ((sf->sf_flags & SF_INCONSISTENT) ||
                     (sf->sf_flags & SF_UPGRADE && fid_is_igif(fid)) ||
@@ -5038,10 +5068,8 @@ pack:
        if (osd_remote_fid(env, dev, fid))
                RETURN(0);
 
-       if (likely(!(attr & LUDA_IGNORE))) {
-               oic->oic_lid = *id;
-               oic->oic_fid = *fid;
-       }
+       if (likely(!(attr & LUDA_IGNORE)))
+               rc = osd_add_oi_cache(oti, dev, id, fid);
 
        if (!(attr & LUDA_VERIFY) &&
            (scrub->os_pos_current <= ino) &&
index f90e518..9194672 100644 (file)
@@ -679,6 +679,10 @@ int osd_oi_delete(struct osd_thread_info *info,
 {
        struct lu_fid *oi_fid = &info->oti_fid2;
 
+       /* clear idmap cache */
+       if (lu_fid_eq(fid, &info->oti_cache.oic_fid))
+               fid_zero(&info->oti_cache.oic_fid);
+
        if (fid_is_last_id(fid))
                return 0;