int osd_compat_spec_insert(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, const struct osd_inode_id *id, struct thandle *th) { struct osd_compat_objid *map = osd->od_ost_map; struct dentry *root = osd_sb(osd)->s_root; char *name; int rc = 0; int seq; ENTRY; if (fid_oid(fid) >= OFD_GROUP0_LAST_OID && fid_oid(fid) < OFD_GROUP4K_LAST_OID) { /* on creation of LAST_ID we create O/<group> hierarchy */ LASSERT(map); seq = fid_oid(fid) - OFD_GROUP0_LAST_OID; LASSERT(seq < MAX_OBJID_GROUP); LASSERT(map->groups[seq].groot); } else { name = oid2name(fid_oid(fid)); if (name == NULL) CWARN("UNKNOWN COMPAT FID "DFID"\n", PFID(fid)); else if (name[0]) rc = osd_compat_add_entry(info, osd, root, name, id, th); } RETURN(rc); }
int osd_compat_spec_lookup(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, struct osd_inode_id *id) { struct dentry *dentry; char *name; int rc = -ERESTART; ENTRY; name = oid2name(fid_oid(fid)); if (name == NULL || strlen(name) == 0) return -ERESTART; dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); if (!IS_ERR(dentry)) { if (dentry->d_inode) { if (is_bad_inode(dentry->d_inode)) { rc = -EIO; } else { id->oii_ino = dentry->d_inode->i_ino; id->oii_gen = dentry->d_inode->i_generation; rc = 0; } } dput(dentry); } RETURN(rc); }
void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent) { dst->o_parent_oid = fid_oid(parent); dst->o_parent_seq = fid_seq(parent); dst->o_parent_ver = fid_ver(parent); dst->o_valid |= OBD_MD_FLGENER | OBD_MD_FLFID; }
/** * Helper function to retrieve DMU object id from fid for accounting object */ uint64_t osd_quota_fid2dmu(const struct lu_fid *fid) { LASSERT(fid_is_acct(fid)); if (fid_oid(fid) == ACCT_GROUP_OID) return DMU_GROUPUSED_OBJECT; return DMU_USERUSED_OBJECT; }
/* Allocate new fid on passed client @seq and save it to @fid. */ int seq_client_alloc_fid(const struct lu_env *env, struct lu_client_seq *seq, struct lu_fid *fid) { cfs_waitlink_t link; int rc; ENTRY; LASSERT(seq != NULL); LASSERT(fid != NULL); cfs_waitlink_init(&link); cfs_mutex_lock(&seq->lcs_mutex); while (1) { seqno_t seqnr; if (!fid_is_zero(&seq->lcs_fid) && fid_oid(&seq->lcs_fid) < seq->lcs_width) { /* Just bump last allocated fid and return to caller. */ seq->lcs_fid.f_oid += 1; rc = 0; break; } rc = seq_fid_alloc_prep(seq, &link); if (rc) continue; rc = seq_client_alloc_seq(env, seq, &seqnr); if (rc) { CERROR("%s: Can't allocate new sequence, " "rc %d\n", seq->lcs_name, rc); seq_fid_alloc_fini(seq); cfs_mutex_unlock(&seq->lcs_mutex); RETURN(rc); } CDEBUG(D_INFO, "%s: Switch to sequence " "[0x%16.16"LPF64"x]\n", seq->lcs_name, seqnr); seq->lcs_fid.f_oid = LUSTRE_FID_INIT_OID; seq->lcs_fid.f_seq = seqnr; seq->lcs_fid.f_ver = 0; /* * Inform caller that sequence switch is performed to allow it * to setup FLD for it. */ rc = 1; seq_fid_alloc_fini(seq); break; } *fid = seq->lcs_fid; cfs_mutex_unlock(&seq->lcs_mutex); CDEBUG(D_INFO, "%s: Allocated FID "DFID"\n", seq->lcs_name, PFID(fid)); RETURN(rc); }
/** * Allocate new fid on passed client @seq and save it to @fid. * * \param[in] env pointer to the thread context * \param[in,out] seq pointer to the client sequence manager * \param[out] fid to hold the new allocated fid * * \retval 1 for notify the caller that sequence switch * is performed to allow it to setup FLD for it. * \retval 0 for new FID allocated in current sequence. * \retval Negative error number on failure. */ int seq_client_alloc_fid(const struct lu_env *env, struct lu_client_seq *seq, struct lu_fid *fid) { wait_queue_t link; int rc; ENTRY; LASSERT(seq != NULL); LASSERT(fid != NULL); init_waitqueue_entry(&link, current); mutex_lock(&seq->lcs_mutex); if (OBD_FAIL_CHECK(OBD_FAIL_SEQ_EXHAUST)) seq->lcs_fid.f_oid = seq->lcs_width; while (1) { u64 seqnr; if (unlikely(!fid_is_zero(&seq->lcs_fid) && fid_oid(&seq->lcs_fid) < seq->lcs_width)) { /* Just bump last allocated fid and return to caller. */ seq->lcs_fid.f_oid++; rc = 0; break; } /* Release seq::lcs_mutex via seq_fid_alloc_prep() to avoid * deadlock during seq_client_alloc_seq(). */ rc = seq_fid_alloc_prep(seq, &link); if (rc) continue; rc = seq_client_alloc_seq(env, seq, &seqnr); /* Re-take seq::lcs_mutex via seq_fid_alloc_fini(). */ seq_fid_alloc_fini(seq, rc ? 0 : seqnr, false); if (rc) { CERROR("%s: Can't allocate new sequence: rc = %d\n", seq->lcs_name, rc); mutex_unlock(&seq->lcs_mutex); RETURN(rc); } rc = 1; break; } *fid = seq->lcs_fid; mutex_unlock(&seq->lcs_mutex); CDEBUG(D_INFO, "%s: Allocated FID "DFID"\n", seq->lcs_name, PFID(fid)); RETURN(rc); }
static int osp_rd_prealloc_last_id(char *page, char **start, off_t off, int count, int *eof, void *data) { struct obd_device *obd = data; struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev); if (osp == NULL) return 0; return snprintf(page, count, "%u\n", fid_oid(&osp->opd_pre_last_created_fid)); }
/* compatibility with orphan files created in versions before 2.11 */ static struct dt_key *mdd_orphan_key_fill_20(const struct lu_env *env, const struct lu_fid *lf) { char *key = mdd_env_info(env)->mti_key; LASSERT(key); snprintf(key, sizeof(mdd_env_info(env)->mti_key), ORPHAN_FILE_NAME_FORMAT_20, fid_seq(lf), fid_oid(lf), fid_ver(lf), ORPH_OP_UNLINK); return (struct dt_key *)key; }
static inline int osp_objs_precreated(const struct lu_env *env, struct osp_device *osp) { struct lu_fid *fid1 = &osp->opd_pre_last_created_fid; struct lu_fid *fid2 = &osp->opd_pre_used_fid; LASSERTF(fid_seq(fid1) == fid_seq(fid2), "Created fid"DFID" Next fid "DFID"\n", PFID(fid1), PFID(fid2)); if (fid_is_idif(fid1)) { struct ost_id *oi1 = &osp_env_info(env)->osi_oi; struct ost_id *oi2 = &osp_env_info(env)->osi_oi2; LASSERT(fid_is_idif(fid1) && fid_is_idif(fid2)); fid_to_ostid(fid1, oi1); fid_to_ostid(fid2, oi2); LASSERT(ostid_id(oi1) >= ostid_id(oi2)); return ostid_id(oi1) - ostid_id(oi2); } return fid_oid(fid1) - fid_oid(fid2); }
static struct dt_key* orph_key_fill_18(const struct lu_env *env, const struct lu_fid *lf) { char *key = mdd_env_info(env)->mti_key; int rc; LASSERT(key); rc = snprintf(key, NAME_MAX + 1, ORPHAN_FILE_NAME_FORMAT_18, (unsigned long long)fid_seq(lf), fid_oid(lf)); if (rc > 0) return (struct dt_key*) key; else return ERR_PTR(rc); }
/** * asks OST to clean precreate orphans * and gets next id for new objects */ static int osp_precreate_cleanup_orphans(struct lu_env *env, struct osp_device *d) { struct osp_thread_info *osi = osp_env_info(env); struct lu_fid *last_fid = &osi->osi_fid; struct ptlrpc_request *req = NULL; struct obd_import *imp; struct ost_body *body; struct l_wait_info lwi = { 0 }; int update_status = 0; int rc; int diff; ENTRY; /* * wait for local recovery to finish, so we can cleanup orphans * orphans are all objects since "last used" (assigned), but * there might be objects reserved and in some cases they won't * be used. we can't cleanup them till we're sure they won't be * used. also can't we allow new reservations because they may * end up getting orphans being cleaned up below. so we block * new reservations and wait till all reserved objects either * user or released. */ spin_lock(&d->opd_pre_lock); d->opd_pre_recovering = 1; spin_unlock(&d->opd_pre_lock); /* * The locking above makes sure the opd_pre_reserved check below will * catch all osp_precreate_reserve() calls who find * "!opd_pre_recovering". */ l_wait_event(d->opd_pre_waitq, (!d->opd_pre_reserved && d->opd_recovery_completed) || !osp_precreate_running(d) || d->opd_got_disconnected, &lwi); if (!osp_precreate_running(d) || d->opd_got_disconnected) GOTO(out, rc = -EAGAIN); CDEBUG(D_HA, "%s: going to cleanup orphans since "DFID"\n", d->opd_obd->obd_name, PFID(&d->opd_last_used_fid)); *last_fid = d->opd_last_used_fid; /* The OSP should already get the valid seq now */ LASSERT(!fid_is_zero(last_fid)); if (fid_oid(&d->opd_last_used_fid) < 2) { /* lastfid looks strange... ask OST */ rc = osp_get_lastfid_from_ost(env, d); if (rc) GOTO(out, rc); } imp = d->opd_obd->u.cli.cl_import; LASSERT(imp); req = ptlrpc_request_alloc(imp, &RQF_OST_CREATE); if (req == NULL) GOTO(out, rc = -ENOMEM); rc = ptlrpc_request_pack(req, LUSTRE_OST_VERSION, OST_CREATE); if (rc) { ptlrpc_request_free(req); req = NULL; GOTO(out, rc); } body = req_capsule_client_get(&req->rq_pill, &RMF_OST_BODY); if (body == NULL) GOTO(out, rc = -EPROTO); body->oa.o_flags = OBD_FL_DELORPHAN; body->oa.o_valid = OBD_MD_FLFLAGS | OBD_MD_FLGROUP; fid_to_ostid(&d->opd_last_used_fid, &body->oa.o_oi); ptlrpc_request_set_replen(req); /* Don't resend the delorphan req */ req->rq_no_resend = req->rq_no_delay = 1; rc = ptlrpc_queue_wait(req); if (rc) { update_status = 1; GOTO(out, rc); } body = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY); if (body == NULL) GOTO(out, rc = -EPROTO); /* * OST provides us with id new pool starts from in body->oa.o_id */ ostid_to_fid(last_fid, &body->oa.o_oi, d->opd_index); spin_lock(&d->opd_pre_lock); diff = lu_fid_diff(&d->opd_last_used_fid, last_fid); if (diff > 0) { d->opd_pre_grow_count = OST_MIN_PRECREATE + diff; d->opd_pre_last_created_fid = d->opd_last_used_fid; } else { d->opd_pre_grow_count = OST_MIN_PRECREATE; d->opd_pre_last_created_fid = *last_fid; } /* * This empties the pre-creation pool and effectively blocks any new * reservations. */ LASSERT(fid_oid(&d->opd_pre_last_created_fid) <= LUSTRE_DATA_SEQ_MAX_WIDTH); d->opd_pre_used_fid = d->opd_pre_last_created_fid; d->opd_pre_grow_slow = 0; spin_unlock(&d->opd_pre_lock); CDEBUG(D_HA, "%s: Got last_id "DFID" from OST, last_created "DFID "last_used is "DFID"\n", d->opd_obd->obd_name, PFID(last_fid), PFID(&d->opd_pre_last_created_fid), PFID(&d->opd_last_used_fid)); out: if (req) ptlrpc_req_finished(req); spin_lock(&d->opd_pre_lock); d->opd_pre_recovering = 0; spin_unlock(&d->opd_pre_lock); /* * If rc is zero, the pre-creation window should have been emptied. * Since waking up the herd would be useless without pre-created * objects, we defer the signal to osp_precreate_send() in that case. */ if (rc != 0) { if (update_status) { CERROR("%s: cannot cleanup orphans: rc = %d\n", d->opd_obd->obd_name, rc); /* we can't proceed from here, OST seem to * be in a bad shape, better to wait for * a new instance of the server and repeat * from the beginning. notify possible waiters * this OSP isn't quite functional yet */ osp_pre_update_status(d, rc); } else { wake_up(&d->opd_pre_user_waitq); } } RETURN(rc); }
static int osp_get_lastfid_from_ost(const struct lu_env *env, struct osp_device *d) { struct ptlrpc_request *req = NULL; struct obd_import *imp; struct lu_fid *last_fid; char *tmp; int rc; ENTRY; imp = d->opd_obd->u.cli.cl_import; LASSERT(imp); req = ptlrpc_request_alloc(imp, &RQF_OST_GET_INFO_LAST_FID); if (req == NULL) RETURN(-ENOMEM); req_capsule_set_size(&req->rq_pill, &RMF_GETINFO_KEY, RCL_CLIENT, sizeof(KEY_LAST_FID)); rc = ptlrpc_request_pack(req, LUSTRE_OST_VERSION, OST_GET_INFO); if (rc) { ptlrpc_request_free(req); RETURN(rc); } tmp = req_capsule_client_get(&req->rq_pill, &RMF_GETINFO_KEY); memcpy(tmp, KEY_LAST_FID, sizeof(KEY_LAST_FID)); req->rq_no_delay = req->rq_no_resend = 1; last_fid = req_capsule_client_get(&req->rq_pill, &RMF_FID); fid_cpu_to_le(last_fid, &d->opd_last_used_fid); ptlrpc_request_set_replen(req); rc = ptlrpc_queue_wait(req); if (rc) { /* bad-bad OST.. let sysadm sort this out */ if (rc == -ENOTSUPP) { CERROR("%s: server does not support FID: rc = %d\n", d->opd_obd->obd_name, -ENOTSUPP); } ptlrpc_set_import_active(imp, 0); GOTO(out, rc); } last_fid = req_capsule_server_get(&req->rq_pill, &RMF_FID); if (last_fid == NULL) { CERROR("%s: Got last_fid failed.\n", d->opd_obd->obd_name); GOTO(out, rc = -EPROTO); } if (!fid_is_sane(last_fid)) { CERROR("%s: Got insane last_fid "DFID"\n", d->opd_obd->obd_name, PFID(last_fid)); GOTO(out, rc = -EPROTO); } /* Only update the last used fid, if the OST has objects for * this sequence, i.e. fid_oid > 0 */ if (fid_oid(last_fid) > 0) d->opd_last_used_fid = *last_fid; CDEBUG(D_HA, "%s: Got last_fid "DFID"\n", d->opd_obd->obd_name, PFID(last_fid)); out: ptlrpc_req_finished(req); RETURN(rc); }
/** * Prepare buffers for write request processing. * * This function converts remote buffers from client to local buffers * and prepares the latter. If there is recovery in progress and required * object is missing then it can be re-created before write. * * \param[in] env execution environment * \param[in] exp OBD export of client * \param[in] ofd OFD device * \param[in] fid FID of object * \param[in] la object attributes * \param[in] oa OBDO structure from client * \param[in] objcount always 1 * \param[in] obj object data * \param[in] rnb remote buffers * \param[in] nr_local number of local buffers * \param[in] lnb local buffers * \param[in] jobid job ID name * * \retval 0 on successful prepare * \retval negative value on error */ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp, struct ofd_device *ofd, const struct lu_fid *fid, struct lu_attr *la, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, struct niobuf_local *lnb, char *jobid) { struct ofd_object *fo; int i, j, k, rc = 0, tot_bytes = 0; ENTRY; LASSERT(env != NULL); LASSERT(objcount == 1); if (unlikely(exp->exp_obd->obd_recovering)) { u64 seq = fid_seq(fid); u64 oid = fid_oid(fid); struct ofd_seq *oseq; oseq = ofd_seq_load(env, ofd, seq); if (IS_ERR(oseq)) { CERROR("%s: Can't find FID Sequence "LPX64": rc = %d\n", ofd_name(ofd), seq, (int)PTR_ERR(oseq)); GOTO(out, rc = -EINVAL); } if (oid > ofd_seq_last_oid(oseq)) { int sync = 0; int diff; mutex_lock(&oseq->os_create_lock); diff = oid - ofd_seq_last_oid(oseq); /* Do sync create if the seq is about to used up */ if (fid_seq_is_idif(seq) || fid_seq_is_mdt0(seq)) { if (unlikely(oid >= IDIF_MAX_OID - 1)) sync = 1; } else if (fid_seq_is_norm(seq)) { if (unlikely(oid >= LUSTRE_DATA_SEQ_MAX_WIDTH - 1)) sync = 1; } else { CERROR("%s : invalid o_seq "DOSTID"\n", ofd_name(ofd), POSTID(&oa->o_oi)); mutex_unlock(&oseq->os_create_lock); ofd_seq_put(env, oseq); GOTO(out, rc = -EINVAL); } while (diff > 0) { u64 next_id = ofd_seq_last_oid(oseq) + 1; int count = ofd_precreate_batch(ofd, diff); rc = ofd_precreate_objects(env, ofd, next_id, oseq, count, sync); if (rc < 0) { mutex_unlock(&oseq->os_create_lock); ofd_seq_put(env, oseq); GOTO(out, rc); } diff -= rc; } mutex_unlock(&oseq->os_create_lock); } ofd_seq_put(env, oseq); } fo = ofd_object_find(env, ofd, fid); if (IS_ERR(fo)) GOTO(out, rc = PTR_ERR(fo)); LASSERT(fo != NULL); ofd_read_lock(env, fo); if (!ofd_object_exists(fo)) { CERROR("%s: BRW to missing obj "DOSTID"\n", exp->exp_obd->obd_name, POSTID(&obj->ioo_oid)); ofd_read_unlock(env, fo); ofd_object_put(env, fo); GOTO(out, rc = -ENOENT); } if (ofd->ofd_lfsck_verify_pfid && oa->o_valid & OBD_MD_FLFID) { rc = ofd_verify_ff(env, fo, oa); if (rc != 0) { ofd_read_unlock(env, fo); ofd_object_put(env, fo); GOTO(out, rc); } } /* Process incoming grant info, set OBD_BRW_GRANTED flag and grant some * space back if possible */ ofd_grant_prepare_write(env, exp, oa, rnb, obj->ioo_bufcnt); /* parse remote buffers to local buffers and prepare the latter */ *nr_local = 0; for (i = 0, j = 0; i < obj->ioo_bufcnt; i++) { rc = dt_bufs_get(env, ofd_object_child(fo), rnb + i, lnb + j, 1); if (unlikely(rc < 0)) GOTO(err, rc); LASSERT(rc <= PTLRPC_MAX_BRW_PAGES); /* correct index for local buffers to continue with */ for (k = 0; k < rc; k++) { lnb[j+k].lnb_flags = rnb[i].rnb_flags; if (!(rnb[i].rnb_flags & OBD_BRW_GRANTED)) lnb[j+k].lnb_rc = -ENOSPC; } j += rc; *nr_local += rc; LASSERT(j <= PTLRPC_MAX_BRW_PAGES); tot_bytes += rnb[i].rnb_len; } LASSERT(*nr_local > 0 && *nr_local <= PTLRPC_MAX_BRW_PAGES); rc = dt_write_prep(env, ofd_object_child(fo), lnb, *nr_local); if (unlikely(rc != 0)) GOTO(err, rc); ofd_counter_incr(exp, LPROC_OFD_STATS_WRITE, jobid, tot_bytes); RETURN(0); err: dt_bufs_put(env, ofd_object_child(fo), lnb, *nr_local); ofd_read_unlock(env, fo); ofd_object_put(env, fo); /* ofd_grant_prepare_write() was called, so we must commit */ ofd_grant_commit(exp, oa->o_grant_used, rc); out: /* let's still process incoming grant information packed in the oa, * but without enforcing grant since we won't proceed with the write. * Just like a read request actually. */ ofd_grant_prepare_read(env, exp, oa); return rc; }
static inline int fid_is_fs_root(const struct lu_fid *fid) { /* Map root inode to special local object FID */ return (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE && fid_oid(fid) == OSD_FS_ROOT_OID)); }
/* Allocate new fid on passed client @seq and save it to @fid. */ int seq_client_alloc_fid(const struct lu_env *env, struct lu_client_seq *seq, struct lu_fid *fid) { wait_queue_entry_t link; int rc; LASSERT(seq); LASSERT(fid); init_waitqueue_entry(&link, current); mutex_lock(&seq->lcs_mutex); if (OBD_FAIL_CHECK(OBD_FAIL_SEQ_EXHAUST)) seq->lcs_fid.f_oid = seq->lcs_width; while (1) { u64 seqnr; if (!fid_is_zero(&seq->lcs_fid) && fid_oid(&seq->lcs_fid) < seq->lcs_width) { /* Just bump last allocated fid and return to caller. */ seq->lcs_fid.f_oid += 1; rc = 0; break; } rc = seq_fid_alloc_prep(seq, &link); if (rc) continue; rc = seq_client_alloc_seq(env, seq, &seqnr); if (rc) { CERROR("%s: Can't allocate new sequence, rc %d\n", seq->lcs_name, rc); seq_fid_alloc_fini(seq); mutex_unlock(&seq->lcs_mutex); return rc; } CDEBUG(D_INFO, "%s: Switch to sequence [0x%16.16llx]\n", seq->lcs_name, seqnr); seq->lcs_fid.f_oid = LUSTRE_FID_INIT_OID; seq->lcs_fid.f_seq = seqnr; seq->lcs_fid.f_ver = 0; /* * Inform caller that sequence switch is performed to allow it * to setup FLD for it. */ rc = 1; seq_fid_alloc_fini(seq); break; } *fid = seq->lcs_fid; mutex_unlock(&seq->lcs_mutex); CDEBUG(D_INFO, "%s: Allocated FID " DFID "\n", seq->lcs_name, PFID(fid)); return rc; }
static int osp_object_create(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, struct dt_allocation_hint *hint, struct dt_object_format *dof, struct thandle *th) { struct osp_thread_info *osi = osp_env_info(env); struct osp_device *d = lu2osp_dev(dt->do_lu.lo_dev); struct osp_object *o = dt2osp_obj(dt); int rc = 0; struct lu_fid *fid = &osi->osi_fid; ENTRY; if (o->opo_reserved) { /* regular case, fid is assigned holding trunsaction open */ osp_object_assign_fid(env, d, o); } memcpy(fid, lu_object_fid(&dt->do_lu), sizeof(*fid)); LASSERTF(fid_is_sane(fid), "fid for osp_obj %p is insane"DFID"!\n", osp_obj, PFID(fid)); if (!o->opo_reserved) { /* special case, id was assigned outside of transaction * see comments in osp_declare_attr_set */ spin_lock(&d->opd_pre_lock); osp_update_last_fid(d, fid); spin_unlock(&d->opd_pre_lock); } CDEBUG(D_INODE, "fid for osp_obj %p is "DFID"!\n", osp_obj, PFID(fid)); /* If the precreate ends, it means it will be ready to rollover to * the new sequence soon, all the creation should be synchronized, * otherwise during replay, the replay fid will be inconsistent with * last_used/create fid */ if (osp_precreate_end_seq(env, d) && osp_is_fid_client(d)) th->th_sync = 1; /* * it's OK if the import is inactive by this moment - id was created * by OST earlier, we just need to maintain it consistently on the disk * once import is reconnected, OSP will claim this and other objects * used and OST either keep them, if they exist or recreate */ /* we might have lost precreated objects */ if (unlikely(d->opd_gap_count) > 0) { spin_lock(&d->opd_pre_lock); if (d->opd_gap_count > 0) { int count = d->opd_gap_count; ostid_set_id(&osi->osi_oi, fid_oid(&d->opd_gap_start_fid)); d->opd_gap_count = 0; spin_unlock(&d->opd_pre_lock); CDEBUG(D_HA, "Writting gap "DFID"+%d in llog\n", PFID(&d->opd_gap_start_fid), count); /* real gap handling is disabled intil ORI-692 will be * fixed, now we only report gaps */ } else { spin_unlock(&d->opd_pre_lock); } } /* new object, the very first ->attr_set() * initializing attributes needs no logging */ o->opo_new = 1; /* Only need update last_used oid file, seq file will only be update * during seq rollover */ osp_objid_buf_prep(&osi->osi_lb, &osi->osi_off, &d->opd_last_used_fid.f_oid, d->opd_index); rc = dt_record_write(env, d->opd_last_used_oid_file, &osi->osi_lb, &osi->osi_off, th); CDEBUG(D_HA, "%s: Wrote last used FID: "DFID", index %d: %d\n", d->opd_obd->obd_name, PFID(fid), d->opd_index, rc); RETURN(rc); }