struct mdt_lock_handle *child_lh;
struct lu_name *lname;
int rc;
- ENTRY;
+ int no_name = 0;
+ ENTRY;
DEBUG_REQ(D_INODE, req, "unlink "DFID"/%s", PFID(rr->rr_fid1),
rr->rr_name);
/* lookup child object along with version checking */
fid_zero(child_fid);
rc = mdt_lookup_version_check(info, mp, lname, child_fid, 1);
- if (rc != 0)
- GOTO(unlock_parent, rc);
+ if (rc != 0) {
+ /* Name might not be able to find during resend of
+ * remote unlink, considering following case.
+ * dir_A is a remote directory, the name entry of
+ * dir_A is on MDT0, the directory is on MDT1,
+ *
+ * 1. client sends unlink req to MDT1.
+ * 2. MDT1 sends name delete update to MDT0.
+ * 3. name entry is being deleted in MDT0 synchronously.
+ * 4. MDT1 is restarted.
+ * 5. client resends unlink req to MDT1. So it can not
+ * find the name entry on MDT0 anymore.
+ * In this case, MDT1 only needs to destory the local
+ * directory.
+ * */
+ if (mdt_object_remote(mp) && rc == -ENOENT &&
+ !fid_is_zero(rr->rr_fid2) &&
+ lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
+ no_name = 1;
+ *child_fid = *rr->rr_fid2;
+ } else {
+ GOTO(unlock_parent, rc);
+ }
+ }
if (fid_is_obf(child_fid) || fid_is_dot_lustre(child_fid))
GOTO(unlock_parent, rc = -EPERM);
ma->ma_valid = 0;
mdt_set_capainfo(info, 1, child_fid, BYPASS_CAPA);
rc = mdo_unlink(info->mti_env, mdt_object_child(mp),
- NULL, lname, ma);
+ NULL, lname, ma, no_name);
GOTO(put_child, rc);
}
/* Revoke the LOOKUP lock of the remote object granted by
GOTO(put_child, rc = -EPERM);
}
- rc = mdt_object_lock(info, mc, child_lh, MDS_INODELOCK_FULL,
+ rc = mdt_object_lock(info, mc, child_lh, MDS_INODELOCK_FULL,
MDT_CROSS_LOCK);
if (rc != 0) {
GOTO(put_child, rc);
ma->ma_need = MA_INODE;
ma->ma_valid = 0;
mdt_set_capainfo(info, 1, child_fid, BYPASS_CAPA);
- rc = mdo_unlink(info->mti_env, mdt_object_child(mp),
- mdt_object_child(mc), lname, ma);
+
+ rc = mdo_unlink(info->mti_env, mdt_object_child(mp),
+ mdt_object_child(mc), lname, ma, no_name);
if (rc == 0 && !lu_object_is_dying(&mc->mot_header))
rc = mdt_attr_get_complex(info, mc, ma);
- if (rc == 0)
- mdt_handle_last_unlink(info, mc, ma);
+ if (rc == 0)
+ mdt_handle_last_unlink(info, mc, ma);
if (ma->ma_valid & MA_INODE) {
switch (ma->ma_attr.la_mode & S_IFMT) {