/** * Implementation of ldlm_valblock_ops::lvbo_init for OFD. * * This function allocates and initializes new LVB data for the given * LDLM resource if it is not allocated yet. New LVB is filled with attributes * of the object associated with that resource. Function does nothing if LVB * for the given LDLM resource is allocated already. * * Called with res->lr_lvb_sem held. * * \param[in] res LDLM resource * * \retval 0 on successful setup * \retval negative value on error */ static int ofd_lvbo_init(struct ldlm_resource *res) { struct ost_lvb *lvb; struct ofd_device *ofd; struct ofd_object *fo; struct ofd_thread_info *info; struct lu_env env; int rc = 0; ENTRY; LASSERT(res); LASSERT(mutex_is_locked(&res->lr_lvb_mutex)); if (res->lr_lvb_data != NULL) RETURN(0); ofd = ldlm_res_to_ns(res)->ns_lvbp; LASSERT(ofd != NULL); if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_OST_LVB)) RETURN(-ENOMEM); rc = lu_env_init(&env, LCT_DT_THREAD); if (rc) RETURN(rc); OBD_ALLOC_PTR(lvb); if (lvb == NULL) GOTO(out_env, rc = -ENOMEM); res->lr_lvb_data = lvb; res->lr_lvb_len = sizeof(*lvb); info = ofd_info_init(&env, NULL); ost_fid_from_resid(&info->fti_fid, &res->lr_name, ofd->ofd_lut.lut_lsd.lsd_osd_index); fo = ofd_object_find(&env, ofd, &info->fti_fid); if (IS_ERR(fo)) GOTO(out_lvb, rc = PTR_ERR(fo)); rc = ofd_attr_get(&env, fo, &info->fti_attr); if (rc) GOTO(out_obj, rc); lvb->lvb_size = info->fti_attr.la_size; lvb->lvb_blocks = info->fti_attr.la_blocks; lvb->lvb_mtime = info->fti_attr.la_mtime; lvb->lvb_atime = info->fti_attr.la_atime; lvb->lvb_ctime = info->fti_attr.la_ctime; CDEBUG(D_DLMTRACE, "res: "DFID" initial lvb size: "LPU64", " "mtime: "LPX64", blocks: "LPX64"\n", PFID(&info->fti_fid), lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_blocks); EXIT; out_obj: ofd_object_put(&env, fo); out_lvb: if (rc != 0) OST_LVB_SET_ERR(lvb->lvb_blocks, rc); out_env: lu_env_fini(&env); /* Don't free lvb data on lookup error */ return rc; }
/** * Implementation of ldlm_valblock_ops::lvbo_init for OFD. * * This function allocates and initializes new LVB data for the given * LDLM resource if it is not allocated yet. New LVB is filled with attributes * of the object associated with that resource. Function does nothing if LVB * for the given LDLM resource is allocated already. * * Called with res->lr_lvb_sem held. * * \param[in] lock LDLM lock on resource * * \retval 0 on successful setup * \retval negative value on error */ static int ofd_lvbo_init(const struct lu_env *env, struct ldlm_resource *res) { struct ost_lvb *lvb; struct ofd_device *ofd; struct ofd_object *fo; struct ofd_thread_info *info; struct lu_env _env; int rc = 0; ENTRY; LASSERT(res); LASSERT(mutex_is_locked(&res->lr_lvb_mutex)); if (res->lr_lvb_data != NULL) RETURN(0); ofd = ldlm_res_to_ns(res)->ns_lvbp; LASSERT(ofd != NULL); if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_OST_LVB)) RETURN(-ENOMEM); if (!env) { rc = lu_env_init(&_env, LCT_DT_THREAD); if (rc) RETURN(rc); env = &_env; } OBD_ALLOC_PTR(lvb); if (lvb == NULL) GOTO(out, rc = -ENOMEM); info = ofd_info(env); res->lr_lvb_data = lvb; res->lr_lvb_len = sizeof(*lvb); ost_fid_from_resid(&info->fti_fid, &res->lr_name, ofd->ofd_lut.lut_lsd.lsd_osd_index); fo = ofd_object_find(env, ofd, &info->fti_fid); if (IS_ERR(fo)) GOTO(out_lvb, rc = PTR_ERR(fo)); rc = ofd_attr_get(env, fo, &info->fti_attr); if (rc) { struct ofd_seq *oseq; __u64 seq; /* Object could be recreated during the first * CLEANUP_ORPHAN request. */ if (rc == -ENOENT) { seq = fid_seq(&info->fti_fid); oseq = ofd_seq_load(env, ofd, fid_seq_is_idif(seq) ? FID_SEQ_OST_MDT0 : seq); if (!IS_ERR_OR_NULL(oseq)) { if (!oseq->os_last_id_synced) rc = -EAGAIN; ofd_seq_put(env, oseq); } } GOTO(out_obj, rc); } lvb->lvb_size = info->fti_attr.la_size; lvb->lvb_blocks = info->fti_attr.la_blocks; lvb->lvb_mtime = info->fti_attr.la_mtime; lvb->lvb_atime = info->fti_attr.la_atime; lvb->lvb_ctime = info->fti_attr.la_ctime; CDEBUG(D_DLMTRACE, "res: "DFID" initial lvb size: %llu, " "mtime: %#llx, blocks: %#llx\n", PFID(&info->fti_fid), lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_blocks); info->fti_attr.la_valid = 0; EXIT; out_obj: ofd_object_put(env, fo); out_lvb: if (rc != 0) OST_LVB_SET_ERR(lvb->lvb_blocks, rc); out: /* Don't free lvb data on lookup error */ if (env && env == &_env) lu_env_fini(&_env); return rc; }