- RETURN(rc);
-}
-
-static int ofd_punch(const struct lu_env *env, struct obd_export *exp,
- struct obd_info *oinfo, struct obd_trans_info *oti,
- struct ptlrpc_request_set *rqset)
-{
- struct ofd_thread_info *info;
- struct ofd_device *ofd = ofd_exp(exp);
- struct ldlm_namespace *ns = ofd->ofd_namespace;
- struct ldlm_resource *res;
- struct ofd_object *fo;
- struct filter_fid *ff = NULL;
- int rc = 0;
-
- ENTRY;
-
- info = ofd_info_init(env, exp);
- ofd_oti2info(info, oti);
-
- fid_ostid_unpack(&info->fti_fid, &oinfo->oi_oa->o_oi, 0);
- ofd_build_resid(&info->fti_fid, &info->fti_resid);
-
- CDEBUG(D_INODE, "calling punch for object "DFID", valid = "LPX64
- ", start = "LPD64", end = "LPD64"\n", PFID(&info->fti_fid),
- oinfo->oi_oa->o_valid, oinfo->oi_policy.l_extent.start,
- oinfo->oi_policy.l_extent.end);
-
- rc = ofd_auth_capa(exp, &info->fti_fid, oinfo->oi_oa->o_seq,
- oinfo_capa(oinfo), CAPA_OPC_OSS_TRUNC);
- if (rc)
- GOTO(out_env, rc);
-
- fo = ofd_object_find(env, ofd, &info->fti_fid);
- if (IS_ERR(fo)) {
- CERROR("%s: error finding object "DFID": rc = %ld\n",
- exp->exp_obd->obd_name, PFID(&info->fti_fid),
- PTR_ERR(fo));
- GOTO(out_env, rc = PTR_ERR(fo));
- }
-
- LASSERT(oinfo->oi_policy.l_extent.end == OBD_OBJECT_EOF);
- if (oinfo->oi_policy.l_extent.end == OBD_OBJECT_EOF) {
- /* Truncate case */
- oinfo->oi_oa->o_size = oinfo->oi_policy.l_extent.start;
- } else if (oinfo->oi_policy.l_extent.end >= oinfo->oi_oa->o_size) {
- oinfo->oi_oa->o_size = oinfo->oi_policy.l_extent.end;
- }
-
- la_from_obdo(&info->fti_attr, oinfo->oi_oa,
- OBD_MD_FLMTIME | OBD_MD_FLATIME | OBD_MD_FLCTIME);
- info->fti_attr.la_valid &= ~LA_TYPE;
- info->fti_attr.la_size = oinfo->oi_policy.l_extent.start;
- info->fti_attr.la_valid |= LA_SIZE;
-
- if (oinfo->oi_oa->o_valid & OBD_MD_FLFID) {
- ff = &info->fti_mds_fid;
- ofd_prepare_fidea(ff, oinfo->oi_oa);
- }
-
- rc = ofd_object_punch(env, fo, oinfo->oi_policy.l_extent.start,
- oinfo->oi_policy.l_extent.end, &info->fti_attr,
- ff);
- if (rc)
- GOTO(out, rc);
-
- res = ldlm_resource_get(ns, NULL, &info->fti_resid, LDLM_EXTENT, 0);
- if (res != NULL) {
- ldlm_res_lvbo_update(res, NULL, 0);
- ldlm_resource_putref(res);
+ if (rc == 0) {
+ /* we do not call this before to avoid lu_object_find() in
+ * ->lvbo_update() holding another reference on the object.
+ * otherwise concurrent destroy can make the object unavailable
+ * for 2nd lu_object_find() waiting for the first reference
+ * to go... deadlock! */
+ res = ldlm_resource_get(ns, NULL, &info->fti_resid, LDLM_EXTENT, 0);
+ if (!IS_ERR(res)) {
+ ldlm_res_lvbo_update(res, NULL, 0);
+ ldlm_resource_putref(res);
+ }