LASSERT(!(child_bits & MDS_INODELOCK_LAYOUT));
if (S_ISREG(lu_object_attr(&child->mot_obj)) &&
!mdt_object_remote(child) && ldlm_rep != NULL) {
+ /*
+ * For the old client without PCC-RO support, it needs
+ * to clear the LCM_FL_PCC_RDONLY layout flag to avoid
+ * the inconsistent data access for the purpose of
+ * compatibility and interoperability.
+ * Thus it does not grant layout lock to the client
+ * here.
+ */
if (!OBD_FAIL_CHECK(OBD_FAIL_MDS_NO_LL_GETATTR) &&
- exp_connect_layout(info->mti_exp)) {
+ exp_connect_layout(info->mti_exp) &&
+ exp_connect_pccro(info->mti_exp)) {
/* try to grant layout lock for regular file. */
try_bits = MDS_INODELOCK_LAYOUT;
}
child_bits &= ~MDS_INODELOCK_UPDATE;
rc = mdt_object_lock(info, child, lhc, child_bits);
}
+
if (unlikely(rc != 0))
GOTO(out_child, rc);
}
mdt_object_unlock(info, obj, lhc, 1);
rc = mdt_layout_change(info, obj, lhc, layout);
+
+ RETURN(rc);
+}
+
+static int mdt_layout_clear_pccro(struct mdt_thread_info *info,
+ struct mdt_object *obj)
+{
+ struct mdt_lock_handle *lhc = &info->mti_lh[MDT_LH_RMT];
+ struct md_layout_change layout = { .mlc_opc = MD_LAYOUT_WRITE };
+ struct layout_intent intent = {
+ .li_opc = LAYOUT_INTENT_PCCRO_CLEAR,
+ .li_extent.e_start = 0,
+ .li_extent.e_end = LUSTRE_EOF,
+ };
+ int rc;
+
+ ENTRY;
+
+ layout.mlc_intent = &intent;
+ mdt_lock_handle_init(lhc);
+ mdt_lock_reg_init(lhc, LCK_EX);
+ rc = mdt_reint_object_lock(info, obj, lhc,
+ MDS_INODELOCK_LAYOUT, false);
+ if (rc)
+ RETURN(rc);
+
+ mutex_lock(&obj->mot_som_mutex);
+ rc = mo_layout_change(info->mti_env, mdt_object_child(obj), &layout);
+ mutex_unlock(&obj->mot_som_mutex);
+ mdt_object_unlock(info, obj, lhc, rc);
+
RETURN(rc);
}
if (layout_size > info->mti_mdt->mdt_max_mdsize)
info->mti_mdt->mdt_max_mdsize = layout_size;
+
+ /*
+ * For the old client without PCC-RO support, it needs
+ * to clear LCM_FL_PCC_RDONLY flag first to avoid
+ * inconsistent data access.
+ */
+ if (!exp_connect_pccro(info->mti_exp))
+ rc = mdt_layout_clear_pccro(info, obj);
+
}
CDEBUG(D_INFO, "%s: layout_size %d\n",
mdt_obd_name(info->mti_mdt), layout_size);
/* take lock in ldlm_lock_enqueue() for LAYOUT_INTENT_ACCESS */
if (layout.mlc_opc == MD_LAYOUT_NOP)
- GOTO(out, rc = 0);
+ GOTO(out, rc);
rc = mdt_check_resent(info, mdt_reconstruct_generic, lhc);
if (rc < 0)