struct lu_object *tsi_corpus;
struct lu_fid tsi_fid;
+ struct lu_fid tsi_fid2;
struct ldlm_res_id tsi_resid;
/* object affected by VBR, for last_rcvd_update */
if (fid_seq_is_mdt0(ostid->oi.oi_seq))
return FID_SEQ_OST_MDT0;
- if (fid_seq_is_default(ostid->oi.oi_seq))
+ if (unlikely(fid_seq_is_default(ostid->oi.oi_seq)))
return FID_SEQ_LOV_DEFAULT;
if (fid_is_idif(&ostid->oi_fid))
/* extract OST objid from a wire ost_id (id/seq) pair */
static inline obd_id ostid_id(const struct ost_id *ostid)
{
- if (fid_seq_is_mdt0(ostid_seq(ostid)))
+ if (fid_seq_is_mdt0(ostid->oi.oi_seq))
return ostid->oi.oi_id & IDIF_OID_MASK;
+ if (unlikely(fid_seq_is_default(ostid->oi.oi_seq)))
+ return ostid->oi.oi_id;
+
if (fid_is_idif(&ostid->oi_fid))
return fid_idif_id(fid_seq(&ostid->oi_fid),
fid_oid(&ostid->oi_fid), 0);
*/
static inline void ostid_set_id(struct ost_id *oi, __u64 oid)
{
- if (fid_seq_is_mdt0(ostid_seq(oi))) {
+ if (fid_seq_is_mdt0(oi->oi.oi_seq)) {
if (oid >= IDIF_MAX_OID) {
CERROR("Bad "LPU64" to set "DOSTID"\n",
oid, POSTID(oi));
return;
}
oi->oi.oi_id = oid;
+ } else if (fid_is_idif(&oi->oi_fid)) {
+ if (oid >= IDIF_MAX_OID) {
+ CERROR("Bad "LPU64" to set "DOSTID"\n",
+ oid, POSTID(oi));
+ return;
+ }
+ oi->oi_fid.f_seq = fid_idif_seq(oid,
+ fid_idif_ost_idx(&oi->oi_fid));
+ oi->oi_fid.f_oid = oid;
+ oi->oi_fid.f_ver = oid >> 48;
} else {
if (oid > OBIF_MAX_OID) {
CERROR("Bad "LPU64" to set "DOSTID"\n",
}
}
-static inline void ostid_inc_id(struct ost_id *oi)
+static inline int fid_set_id(struct lu_fid *fid, __u64 oid)
{
- if (fid_seq_is_mdt0(ostid_seq(oi))) {
- if (unlikely(ostid_id(oi) + 1 > IDIF_MAX_OID)) {
- CERROR("Bad inc "DOSTID"\n", POSTID(oi));
- return;
+ if (unlikely(fid_seq_is_igif(fid->f_seq))) {
+ CERROR("bad IGIF, "DFID"\n", PFID(fid));
+ return -EBADF;
+ }
+
+ if (fid_is_idif(fid)) {
+ if (oid >= IDIF_MAX_OID) {
+ CERROR("Bad "LPU64" to set "DFID"\n",
+ oid, PFID(fid));
+ return -EBADF;
}
- oi->oi.oi_id++;
+ fid->f_seq = fid_idif_seq(oid, fid_idif_ost_idx(fid));
+ fid->f_oid = oid;
+ fid->f_ver = oid >> 48;
} else {
- oi->oi_fid.f_oid++;
+ if (oid > OBIF_MAX_OID) {
+ CERROR("Bad "LPU64" to set "DFID"\n",
+ oid, PFID(fid));
+ return -EBADF;
+ }
+ fid->f_oid = oid;
}
-}
-
-static inline void ostid_dec_id(struct ost_id *oi)
-{
- if (fid_seq_is_mdt0(ostid_seq(oi)))
- oi->oi.oi_id--;
- else
- oi->oi_fid.f_oid--;
+ return 0;
}
/**
* struct lu_fid fields without loss. For reference see:
* http://arch.lustre.org/index.php?title=Interoperability_fids_zfs
*/
-static inline int ostid_to_fid(struct lu_fid *fid, struct ost_id *ostid,
+static inline int ostid_to_fid(struct lu_fid *fid, const struct ost_id *ostid,
__u32 ost_idx)
{
+ obd_seq seq = ostid_seq(ostid);
+
if (ost_idx > 0xffff) {
CERROR("bad ost_idx, "DOSTID" ost_idx:%u\n", POSTID(ostid),
ost_idx);
return -EBADF;
}
- if (fid_seq_is_mdt0(ostid_seq(ostid))) {
+ if (fid_seq_is_mdt0(seq)) {
+ obd_id oid = ostid_id(ostid);
+
/* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
* that we map into the IDIF namespace. It allows up to 2^48
* objects per OST, as this is the object namespace that has
* been in production for years. This can handle create rates
* of 1M objects/s/OST for 9 years, or combinations thereof. */
- if (ostid_id(ostid) >= IDIF_MAX_OID) {
+ if (oid >= IDIF_MAX_OID) {
CERROR("bad MDT0 id, "DOSTID" ost_idx:%u\n",
POSTID(ostid), ost_idx);
return -EBADF;
}
- fid->f_seq = fid_idif_seq(ostid_id(ostid), ost_idx);
+ fid->f_seq = fid_idif_seq(oid, ost_idx);
/* truncate to 32 bits by assignment */
- fid->f_oid = ostid_id(ostid);
+ fid->f_oid = oid;
/* in theory, not currently used */
- fid->f_ver = ostid_id(ostid) >> 48;
- } else /* if (fid_seq_is_idif(seq) || fid_seq_is_norm(seq)) */ {
- /* This is either an IDIF object, which identifies objects across
- * all OSTs, or a regular FID. The IDIF namespace maps legacy
- * OST objects into the FID namespace. In both cases, we just
- * pass the FID through, no conversion needed. */
+ fid->f_ver = oid >> 48;
+ } else if (likely(!fid_seq_is_default(seq)))
+ /* if (fid_seq_is_idif(seq) || fid_seq_is_norm(seq)) */ {
+ /* This is either an IDIF object, which identifies objects across
+ * all OSTs, or a regular FID. The IDIF namespace maps legacy
+ * OST objects into the FID namespace. In both cases, we just
+ * pass the FID through, no conversion needed. */
if (ostid->oi_fid.f_ver != 0) {
CERROR("bad MDT0 id, "DOSTID" ost_idx:%u\n",
POSTID(ostid), ost_idx);
*fid = ostid->oi_fid;
}
- return 0;
+ return 0;
}
/* pack any OST FID into an ostid (id/seq) for the wire/disk */
oi->oi.oi_seq = seq;
}
+static inline void lmm_oi_set_id(struct ost_id *oi, __u64 oid)
+{
+ oi->oi.oi_id = oid;
+}
+
static inline __u64 lmm_oi_id(struct ost_id *oi)
{
return oi->oi.oi_id;
fid_seq_is_root(seq) || fid_seq_is_dot(seq);
}
-static inline void lu_last_id_fid(struct lu_fid *fid, __u64 seq)
+static inline void lu_last_id_fid(struct lu_fid *fid, __u64 seq, __u32 ost_idx)
{
if (fid_seq_is_mdt0(seq)) {
- fid->f_seq = fid_idif_seq(0, 0);
+ fid->f_seq = fid_idif_seq(0, ost_idx);
} else {
LASSERTF(fid_seq_is_norm(seq) || fid_seq_is_echo(seq) ||
fid_seq_is_idif(seq), LPX64"\n", seq);
}
}
-static inline void ostid_res_name_to_id(struct ost_id *oi,
- struct ldlm_res_id *name)
-{
- if (fid_seq_is_mdt0(name->name[LUSTRE_RES_ID_SEQ_OFF])) {
- /* old resid */
- ostid_set_seq(oi, name->name[LUSTRE_RES_ID_VER_OID_OFF]);
- ostid_set_id(oi, name->name[LUSTRE_RES_ID_SEQ_OFF]);
- } else {
- /* new resid */
- fid_extract_from_res_name(&oi->oi_fid, name);
- }
-}
-
/**
* Return true if the resource is for the object identified by this id & group.
*/
}
static inline void ost_fid_from_resid(struct lu_fid *fid,
- const struct ldlm_res_id *name)
+ const struct ldlm_res_id *name,
+ int ost_idx)
{
if (fid_seq_is_mdt0(name->name[LUSTRE_RES_ID_VER_OID_OFF])) {
/* old resid */
struct ost_id oi;
ostid_set_seq(&oi, name->name[LUSTRE_RES_ID_VER_OID_OFF]);
ostid_set_id(&oi, name->name[LUSTRE_RES_ID_SEQ_OFF]);
- ostid_to_fid(fid, &oi, 0);
+ ostid_to_fid(fid, &oi, ost_idx);
} else {
/* new resid */
fid_extract_from_res_name(fid, name);
lfsck_object_put(env, dir_obj);
}
+static int lfsck_update_lma(const struct lu_env *env,
+ struct lfsck_instance *lfsck, struct dt_object *obj)
+{
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
+ struct dt_device *dt = lfsck->li_bottom;
+ struct lustre_mdt_attrs *lma = &info->lti_lma;
+ struct lu_buf *buf;
+ struct thandle *th;
+ int fl;
+ int rc;
+ ENTRY;
+
+ if (bk->lb_param & LPF_DRYRUN)
+ RETURN(0);
+
+ buf = lfsck_buf_get(env, info->lti_lma_old, LMA_OLD_SIZE);
+ rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMA, BYPASS_CAPA);
+ if (rc < 0) {
+ if (rc != -ENODATA)
+ RETURN(rc);
+
+ fl = LU_XATTR_CREATE;
+ lustre_lma_init(lma, lfsck_dto2fid(obj), LMAC_FID_ON_OST, 0);
+ } else {
+ if (rc != LMA_OLD_SIZE && rc != sizeof(struct lustre_mdt_attrs))
+ RETURN(-EINVAL);
+
+ fl = LU_XATTR_REPLACE;
+ lustre_lma_swab(lma);
+ lustre_lma_init(lma, lfsck_dto2fid(obj),
+ lma->lma_compat | LMAC_FID_ON_OST,
+ lma->lma_incompat);
+ }
+ lustre_lma_swab(lma);
+
+ th = dt_trans_create(env, dt);
+ if (IS_ERR(th))
+ RETURN(PTR_ERR(th));
+
+ buf = lfsck_buf_get(env, lma, sizeof(*lma));
+ rc = dt_declare_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th);
+ if (rc != 0)
+ GOTO(stop, rc);
+
+ rc = dt_trans_start(env, dt, th);
+ if (rc != 0)
+ GOTO(stop, rc);
+
+ rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th, BYPASS_CAPA);
+
+ GOTO(stop, rc);
+
+stop:
+ dt_trans_stop(env, dt, th);
+ return rc;
+}
+
static int lfsck_master_dir_engine(const struct lu_env *env,
struct lfsck_instance *lfsck)
{
struct lu_fid *fid = &info->lti_fid;
struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
struct ptlrpc_thread *thread = &lfsck->li_thread;
+ __u32 idx =
+ lfsck_dev_idx(lfsck->li_bottom);
int rc;
ENTRY;
do {
struct dt_object *target;
+ bool update_lma = false;
if (lfsck->li_di_dir != NULL) {
rc = lfsck_master_dir_engine(env, lfsck);
rc = iops->rec(env, di, (struct dt_rec *)fid, 0);
if (rc != 0) {
lfsck_fail(env, lfsck, true);
- if (bk->lb_param & LPF_FAILOUT)
+ if (rc < 0 && bk->lb_param & LPF_FAILOUT)
RETURN(rc);
else
goto checkpoint;
}
+ if (fid_is_idif(fid)) {
+ __u32 idx1 = fid_idif_ost_idx(fid);
+
+ LASSERT(!lfsck->li_master);
+
+ /* It is an old format device, update the LMA. */
+ if (idx != idx1) {
+ struct ost_id *oi = &info->lti_oi;
+
+ fid_to_ostid(fid, oi);
+ ostid_to_fid(fid, oi, idx);
+ update_lma = true;
+ }
+ }
+
target = lfsck_object_find(env, lfsck, fid);
if (target == NULL) {
goto checkpoint;
/* XXX: Currently, skip remote object, the consistency for
* remote object will be processed in LFSCK phase III. */
- if (dt_object_exists(target) && !dt_object_remote(target))
- rc = lfsck_exec_oit(env, lfsck, target);
+ if (dt_object_exists(target) && !dt_object_remote(target)) {
+ if (update_lma)
+ rc = lfsck_update_lma(env, lfsck, target);
+ if (rc == 0)
+ rc = lfsck_exec_oit(env, lfsck, target);
+ }
lfsck_object_put(env, target);
if (rc != 0 && bk->lb_param & LPF_FAILOUT)
RETURN(rc);
#include <lustre_net.h>
#include <lustre_dlm.h>
#include <lustre_fid.h>
+#include <md_object.h>
#define HALF_SEC (HZ >> 1)
#define LFSCK_CHECKPOINT_INTERVAL 60
struct lu_fid lti_fid;
struct lu_fid lti_fid2;
struct lu_attr lti_la;
+ struct ost_id lti_oi;
+ union {
+ struct lustre_mdt_attrs lti_lma;
+ /* old LMA for compatibility */
+ char lti_lma_old[LMA_OLD_SIZE];
+ };
/* lti_ent and lti_key must be conjoint,
* then lti_ent::lde_name will be lti_key. */
struct lu_dirent lti_ent;
lu_object_put(env, &obj->do_lu);
}
+static inline mdsno_t lfsck_dev_idx(struct dt_device *dev)
+{
+ return dev->dd_lu_dev.ld_site->ld_seq_site->ss_node_id;
+}
+
#endif /* _LFSCK_INTERNAL_H */
NULL
};
-static inline mdsno_t lfsck_dev_idx(struct dt_device *dev)
-{
- return dev->dd_lu_dev.ld_site->ld_seq_site->ss_node_id;
-}
-
static inline void lfsck_component_get(struct lfsck_component *com)
{
atomic_inc(&com->lc_ref);
for (i = 0; i < lo->ldo_stripenr; i++) {
ostid_le_to_cpu(&objs[i].l_ost_oi, &info->lti_ostid);
- idx = le64_to_cpu(objs[i].l_ost_idx);
+ idx = le32_to_cpu(objs[i].l_ost_idx);
rc = ostid_to_fid(&info->lti_fid, &info->lti_ostid, idx);
if (rc != 0)
GOTO(out, rc);
} else if (buf->lb_len >= sizeof(*lum)) {
lum->lmm_magic = cpu_to_le32(LOV_USER_MAGIC_V1);
lmm_oi_set_seq(&lum->lmm_oi, FID_SEQ_LOV_DEFAULT);
+ lmm_oi_set_id(&lum->lmm_oi, 0);
lmm_oi_cpu_to_le(&lum->lmm_oi, &lum->lmm_oi);
lum->lmm_pattern = cpu_to_le32(desc->ld_pattern);
lum->lmm_stripe_size = cpu_to_le32(
void lustre_swab_ost_id(struct ost_id *oid)
{
- if (fid_seq_is_mdt0(oid->oi.oi_seq)) {
+ if (fid_seq_is_mdt0(oid->oi.oi_seq) ||
+ fid_seq_is_default(oid->oi.oi_seq)) {
__swab64s(&oid->oi.oi_id);
__swab64s(&oid->oi.oi_seq);
} else {
EXPORT_SYMBOL(lustre_swab_ost_id);
void lustre_swab_llog_id(struct llog_logid *log_id)
-{
+{
__swab64s(&log_id->lgl_oi.oi.oi_id);
__swab64s(&log_id->lgl_oi.oi.oi_seq);
__swab32s(&log_id->lgl_ogen);
if (rc)
RETURN(err_serious(rc));
+ *fid = fm_key->oa.o_oi.oi_fid;
+
+ CDEBUG(D_INODE, "get FIEMAP of object "DFID"\n", PFID(fid));
+
replylen = fiemap_count_to_size(fm_key->fiemap.fm_extent_count);
req_capsule_set_size(tsi->tsi_pill, &RMF_FIEMAP_VAL,
RCL_SERVER, replylen);
if (fiemap == NULL)
RETURN(-ENOMEM);
- rc = ostid_to_fid(fid, &fm_key->oa.o_oi, 0);
- if (rc != 0)
- RETURN(rc);
-
- CDEBUG(D_INODE, "get FIEMAP of object "DFID"\n", PFID(fid));
-
*fiemap = fm_key->fiemap;
rc = ofd_fiemap_get(tsi->tsi_env, ofd, fid, fiemap);
struct ost_body *repbody;
struct ofd_device *ofd = ofd_exp(tsi->tsi_exp);
struct ofd_thread_info *fti = tsi2ofd_info(tsi);
+ struct lu_fid *fid = &fti->fti_fid;
+ obd_id oid;
obd_count count;
int rc = 0;
ldlm_request_cancel(tgt_ses_req(tsi), dlm, 0);
}
+ *fid = body->oa.o_oi.oi_fid;
+ oid = ostid_id(&body->oa.o_oi);
+ LASSERT(oid != 0);
+
repbody = req_capsule_server_get(tsi->tsi_pill, &RMF_OST_BODY);
- repbody->oa.o_oi = body->oa.o_oi;
/* check that o_misc makes sense */
if (body->oa.o_valid & OBD_MD_FLOBJCOUNT)
CDEBUG(D_HA, "%s: Destroy object "DOSTID" count %d\n", ofd_name(ofd),
POSTID(&body->oa.o_oi), count);
+
while (count > 0) {
int lrc;
- lrc = ostid_to_fid(&fti->fti_fid, &repbody->oa.o_oi, 0);
- if (lrc != 0) {
- if (rc == 0)
- rc = lrc;
- GOTO(out, rc);
- }
- lrc = ofd_destroy_by_fid(tsi->tsi_env, ofd, &fti->fti_fid, 0);
+ lrc = ofd_destroy_by_fid(tsi->tsi_env, ofd, fid, 0);
if (lrc == -ENOENT) {
CDEBUG(D_INODE,
"%s: destroying non-existent object "DFID"\n",
- ofd_name(ofd), PFID(&fti->fti_fid));
+ ofd_name(ofd), PFID(fid));
/* rewrite rc with -ENOENT only if it is 0 */
if (rc == 0)
rc = lrc;
} else if (lrc != 0) {
CERROR("%s: error destroying object "DFID": %d\n",
- ofd_name(ofd), PFID(&fti->fti_fid),
- rc);
+ ofd_name(ofd), PFID(fid), lrc);
rc = lrc;
}
+
count--;
- ostid_inc_id(&repbody->oa.o_oi);
+ oid++;
+ lrc = fid_set_id(fid, oid);
+ if (unlikely(lrc != 0 && count > 0))
+ GOTO(out, rc = lrc);
}
ofd_counter_incr(tsi->tsi_exp, LPROC_OFD_STATS_DESTROY,
tsi->tsi_jobid, 1);
+
+ GOTO(out, rc);
+
out:
- RETURN(rc);
+ fid_to_ostid(fid, &repbody->oa.o_oi);
+ return rc;
}
static int ofd_statfs_hdl(struct tgt_session_info *tsi)
if (oseq == NULL)
RETURN(ERR_PTR(-ENOMEM));
- lu_last_id_fid(&info->fti_fid, seq);
+ lu_last_id_fid(&info->fti_fid, seq, ofd->ofd_lut.lut_lsd.lsd_osd_index);
memset(&info->fti_attr, 0, sizeof(info->fti_attr));
info->fti_attr.la_valid = LA_MODE;
info->fti_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
LASSERT(objcount == 1);
LASSERT(obj->ioo_bufcnt > 0);
- rc = ostid_to_fid(&info->fti_fid, &oa->o_oi, 0);
- if (unlikely(rc != 0))
- RETURN(rc);
-
+ info->fti_fid = oa->o_oi.oi_fid;
if (cmd == OBD_BRW_WRITE) {
rc = ofd_auth_capa(exp, &info->fti_fid, ostid_seq(&oa->o_oi),
capa, CAPA_OPC_OSS_WRITE);
LASSERT(npages > 0);
- rc = ostid_to_fid(&info->fti_fid, &oa->o_oi, 0);
- if (unlikely(rc != 0))
- RETURN(rc);
+ info->fti_fid = oa->o_oi.oi_fid;
if (cmd == OBD_BRW_WRITE) {
/* Don't update timestamps if this write is older than a
* setattr which modifies the timestamps. b=10150 */
res->lr_lvb_len = sizeof(*lvb);
info = ofd_info_init(&env, NULL);
- ost_fid_from_resid(&info->fti_fid, &res->lr_name);
+ 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));
disk_update:
/* Update the LVB from the disk inode */
- ost_fid_from_resid(&info->fti_fid, &res->lr_name);
+ 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_env, rc = PTR_ERR(fo));
GOTO(out, rc = 0);
}
- rc = ostid_to_fid(&fid, &fm_key->oa.o_oi, 0);
+ rc = ostid_to_fid(&fid, &fm_key->oa.o_oi,
+ ofd->ofd_lut.lut_lsd.lsd_osd_index);
if (rc != 0)
GOTO(out, rc);
CDEBUG(D_INODE, "get FIEMAP of object "DFID"\n",
GOTO(out, rc = PTR_ERR(oseq));
rc = ostid_to_fid(fid, &oseq->os_oi,
- ofd->ofd_lut.lut_lsd.lsd_osd_index);
+ ofd->ofd_lut.lut_lsd.lsd_osd_index);
if (rc != 0)
GOTO(out_put, rc);
info = ofd_info_init(env, exp);
ofd_oti2info(info, oti);
- rc = ostid_to_fid(&info->fti_fid, &oinfo->oi_oa->o_oi, 0);
- if (rc != 0)
- RETURN(rc);
-
+ info->fti_fid = oinfo->oi_oa->o_oi.oi_fid;
ost_fid_build_resid(&info->fti_fid, &info->fti_resid);
rc = ofd_auth_capa(exp, &info->fti_fid, ostid_seq(&oa->o_oi),
oinfo_capa(oinfo), CAPA_OPC_META_WRITE);
info = ofd_info_init(env, exp);
ofd_oti2info(info, oti);
- rc = ostid_to_fid(&info->fti_fid, &oinfo->oi_oa->o_oi, 0);
- if (rc != 0)
- RETURN(rc);
+ info->fti_fid = oinfo->oi_oa->o_oi.oi_fid;
ost_fid_build_resid(&info->fti_fid, &info->fti_resid);
CDEBUG(D_INODE, "calling punch for object "DFID", valid = "LPX64
{
struct ofd_device *ofd = ofd_exp(exp);
struct ofd_thread_info *info;
+ struct lu_fid *fid;
+ obd_id oid;
obd_count count;
int rc = 0;
info = ofd_info_init(env, exp);
ofd_oti2info(info, oti);
+ fid = &info->fti_fid;
if (!(oa->o_valid & OBD_MD_FLGROUP))
ostid_set_seq_mdt0(&oa->o_oi);
+ *fid = oa->o_oi.oi_fid;
+ oid = ostid_id(&oa->o_oi);
+ LASSERT(oid != 0);
+
/* check that o_misc makes sense */
if (oa->o_valid & OBD_MD_FLOBJCOUNT)
count = oa->o_misc;
CDEBUG(D_INODE, "%s: Destroy object "DOSTID" count %d\n", ofd_name(ofd),
POSTID(&oa->o_oi), count);
+
while (count > 0) {
int lrc;
- lrc = ostid_to_fid(&info->fti_fid, &oa->o_oi, 0);
- if (lrc != 0) {
- if (rc == 0)
- rc = lrc;
- GOTO(out, rc);
- }
- lrc = ofd_destroy_by_fid(env, ofd, &info->fti_fid, 0);
+ lrc = ofd_destroy_by_fid(env, ofd, fid, 0);
if (lrc == -ENOENT) {
CDEBUG(D_INODE,
"%s: destroying non-existent object "DFID"\n",
- ofd_obd(ofd)->obd_name, PFID(&info->fti_fid));
+ ofd_obd(ofd)->obd_name, PFID(fid));
/* rewrite rc with -ENOENT only if it is 0 */
if (rc == 0)
rc = lrc;
} else if (lrc != 0) {
CERROR("%s: error destroying object "DFID": %d\n",
- ofd_obd(ofd)->obd_name, PFID(&info->fti_fid),
+ ofd_obd(ofd)->obd_name, PFID(fid),
rc);
rc = lrc;
}
+
count--;
- ostid_inc_id(&oa->o_oi);
+ oid++;
+ lrc = fid_set_id(fid, oid);
+ if (unlikely(lrc != 0 && count > 0))
+ GOTO(out, rc = lrc);
}
- ofd_info2oti(info, oti);
+ GOTO(out, rc);
+
out:
- RETURN(rc);
+ ofd_info2oti(info, oti);
+ fid_to_ostid(fid, &oa->o_oi);
+ return rc;
}
int ofd_orphans_destroy(const struct lu_env *env, struct obd_export *exp,
struct ofd_device *ofd, struct obdo *oa)
{
- struct ofd_thread_info *info = ofd_info(env);
+ struct ofd_thread_info *info = ofd_info(env);
+ struct lu_fid *fid = &info->fti_fid;
+ struct ost_id *oi = &oa->o_oi;
+ struct ofd_seq *oseq;
+ obd_seq seq = ostid_seq(oi);
+ obd_id end_id = ostid_id(oi);
obd_id last;
+ obd_id oid;
int skip_orphan;
- int rc = 0;
- struct ost_id oi = oa->o_oi;
- __u64 end_id = ostid_id(&oa->o_oi);
- struct ofd_seq *oseq;
-
+ int rc = 0;
ENTRY;
- oseq = ofd_seq_get(ofd, ostid_seq(&oa->o_oi));
+ oseq = ofd_seq_get(ofd, seq);
if (oseq == NULL) {
CERROR("%s: Can not find seq for "DOSTID"\n",
- ofd_name(ofd), POSTID(&oa->o_oi));
+ ofd_name(ofd), POSTID(oi));
RETURN(-EINVAL);
}
+ *fid = oi->oi_fid;
+ last = ofd_seq_last_oid(oseq);
+ oid = last;
+
LASSERT(exp != NULL);
skip_orphan = !!(exp_connect_flags(exp) & OBD_CONNECT_SKIP_ORPHAN);
- last = ofd_seq_last_oid(oseq);
LCONSOLE(D_INFO, "%s: deleting orphan objects from "DOSTID
- " to "DOSTID"\n", ofd_name(ofd), ostid_seq(&oa->o_oi),
- end_id + 1, ostid_seq(&oa->o_oi), last);
+ " to "DOSTID"\n", ofd_name(ofd), seq, end_id + 1, seq, last);
- for (ostid_set_id(&oi, last); ostid_id(&oi) > end_id;
- ostid_dec_id(&oi)) {
- rc = ostid_to_fid(&info->fti_fid, &oi, 0);
- if (rc != 0)
+ while (oid > end_id) {
+ rc = fid_set_id(fid, oid);
+ if (unlikely(rc != 0))
GOTO(out_put, rc);
- rc = ofd_destroy_by_fid(env, ofd, &info->fti_fid, 1);
- if (rc && rc != -ENOENT) /* this is pretty fatal... */
- CEMERG("%s: error destroying precreated id "DOSTID
- ": rc = %d\n", ofd_name(ofd), POSTID(&oi), rc);
+
+ rc = ofd_destroy_by_fid(env, ofd, fid, 1);
+ if (rc != 0 && rc != -ENOENT) /* this is pretty fatal... */
+ CEMERG("%s: error destroying precreated id "DFID
+ ": rc = %d\n", ofd_name(ofd), PFID(fid), rc);
+
+ oid--;
if (!skip_orphan) {
- ofd_seq_last_oid_set(oseq, ostid_id(&oi) - 1);
+ ofd_seq_last_oid_set(oseq, oid);
/* update last_id on disk periodically so that if we
* restart * we don't need to re-scan all of the just
* deleted objects. */
- if ((ostid_id(&oi) & 511) == 0)
+ if ((oid & 511) == 0)
ofd_seq_last_oid_write(env, ofd, oseq);
}
}
+
CDEBUG(D_HA, "%s: after destroy: set last_id to "DOSTID"\n",
- ofd_obd(ofd)->obd_name, POSTID(&oa->o_oi));
+ ofd_obd(ofd)->obd_name, seq, oid);
+
if (!skip_orphan) {
rc = ofd_seq_last_oid_write(env, ofd, oseq);
} else {
/* don't reuse orphan object, return last used objid */
- ostid_set_id(&oa->o_oi, last);
+ ostid_set_id(oi, last);
rc = 0;
}
+
+ GOTO(out_put, rc);
+
out_put:
ofd_seq_put(env, oseq);
- RETURN(rc);
+ return rc;
}
int ofd_create(const struct lu_env *env, struct obd_export *exp,
info = ofd_info_init(env, exp);
- rc = ostid_to_fid(&info->fti_fid, &oinfo->oi_oa->o_oi, 0);
- if (rc != 0)
- GOTO(out, rc);
+ info->fti_fid = oinfo->oi_oa->o_oi.oi_fid;
rc = ofd_auth_capa(exp, &info->fti_fid, ostid_seq(&oinfo->oi_oa->o_oi),
oinfo_capa(oinfo), CAPA_OPC_META_READ);
if (rc)
}
info = ofd_info_init(env, exp);
- rc = ostid_to_fid(&info->fti_fid, &oinfo->oi_oa->o_oi, 0);
- if (rc != 0)
- GOTO(out, rc);
-
+ info->fti_fid = oinfo->oi_oa->o_oi.oi_fid;
rc = ofd_auth_capa(exp, &info->fti_fid, ostid_seq(&oinfo->oi_oa->o_oi),
oinfo_capa(oinfo), CAPA_OPC_OSS_TRUNC);
if (rc)
ostid_set_seq(&ostid, *(__u64 *)data->ioc_inlbuf4);
ostid_set_id(&ostid, *(__u64 *)data->ioc_inlbuf3);
- rc = ostid_to_fid(&fid, &ostid, 0);
+ rc = ostid_to_fid(&fid, &ostid,
+ ofd->ofd_lut.lut_lsd.lsd_osd_index);
if (rc != 0)
GOTO(out, rc);
} else {
struct dt_object *next;
struct thandle *th;
struct ofd_object **batch;
+ struct lu_fid *fid = &info->fti_fid;
obd_id tmp;
int rc;
int i;
info->fti_attr.la_mtime = 0;
info->fti_attr.la_ctime = 0;
+ LASSERT(id != 0);
+
/* prepare objects */
- ostid_set_seq(&info->fti_ostid, ostid_seq(&oseq->os_oi));
+ *fid = *lu_object_fid(&oseq->os_lastid_obj->do_lu);
for (i = 0; i < nr; i++) {
- ostid_set_id(&info->fti_ostid, id + i);
- rc = ostid_to_fid(&info->fti_fid, &info->fti_ostid, 0);
- if (rc) {
+ rc = fid_set_id(fid, id + i);
+ if (rc != 0) {
if (i == 0)
GOTO(out, rc);
break;
}
- fo = ofd_object_find(env, ofd, &info->fti_fid);
+ fo = ofd_object_find(env, ofd, fid);
if (IS_ERR(fo)) {
if (i == 0)
GOTO(out, rc = PTR_ERR(fo));
/* object may exist being re-created by write replay */
CDEBUG(D_INODE, "object "LPX64"/"LPX64" exists: "
DFID"\n", ostid_seq(&oseq->os_oi), id,
- PFID(&info->fti_fid));
+ PFID(lu_object_fid(&fo->ofo_obj.do_lu)));
continue;
}
GOTO(trans_stop, rc);
CDEBUG(D_OTHER, "%s: create new object "DFID" nr %d\n",
- ofd_name(ofd), PFID(&info->fti_fid), nr);
+ ofd_name(ofd), PFID(fid), nr);
for (i = 0; i < nr; i++) {
fo = batch[i];
return rc;
}
+static int osd_lma_self_repair(struct osd_thread_info *info,
+ struct osd_device *osd, struct inode *inode,
+ const struct lu_fid *fid, __u32 compat)
+{
+ handle_t *jh;
+ int rc;
+
+ LASSERT(current->journal_info == NULL);
+
+ jh = osd_journal_start_sb(osd_sb(osd), LDISKFS_HT_MISC,
+ osd_dto_credits_noquota[DTO_XATTR_SET]);
+ if (IS_ERR(jh)) {
+ rc = PTR_ERR(jh);
+ CWARN("%s: cannot start journal for lma_self_repair: rc = %d\n",
+ osd_name(osd), rc);
+ return rc;
+ }
+
+ rc = osd_ea_fid_set(info, inode, fid, compat, 0);
+ if (rc != 0)
+ CWARN("%s: cannot self repair the LMA: rc = %d\n",
+ osd_name(osd), rc);
+ ldiskfs_journal_stop(jh);
+ return rc;
+}
+
static int osd_check_lma(const struct lu_env *env, struct osd_object *obj)
{
struct osd_thread_info *info = osd_oti_get(env);
struct inode *inode = obj->oo_inode;
struct dentry *dentry = &info->oti_obj_dentry;
struct lu_fid *fid = NULL;
+ const struct lu_fid *rfid = lu_object_fid(&obj->oo_dt.do_lu);
int rc;
ENTRY;
CLASSERT(LMA_OLD_SIZE >= sizeof(*lma));
rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMA,
info->oti_mdt_attrs_old, LMA_OLD_SIZE);
- if (rc == -ENODATA && !fid_is_igif(lu_object_fid(&obj->oo_dt.do_lu)) &&
- osd->od_check_ff) {
+ if (rc == -ENODATA && !fid_is_igif(rfid) && osd->od_check_ff) {
fid = &lma->lma_self_fid;
rc = osd_get_idif(info, inode, dentry, fid);
if ((rc > 0) || (rc == -ENODATA && osd->od_lma_self_repair)) {
- handle_t *jh;
-
/* For the given OST-object, if it has neither LMA nor
* FID in XATTR_NAME_FID, then the given FID (which is
* contained in the @obj, from client RPC for locating
* the OST-object) is trusted. We use it to generate
* the LMA. */
-
- LASSERT(current->journal_info == NULL);
-
- jh = osd_journal_start_sb(osd_sb(osd), LDISKFS_HT_MISC,
- osd_dto_credits_noquota[DTO_XATTR_SET]);
- if (IS_ERR(jh)) {
- CWARN("%s: cannot start journal for "
- "lma_self_repair: rc = %ld\n",
- osd_name(osd), PTR_ERR(jh));
- RETURN(0);
- }
-
- rc = osd_ea_fid_set(info, inode,
- lu_object_fid(&obj->oo_dt.do_lu),
- fid_is_on_ost(info, osd,
- lu_object_fid(&obj->oo_dt.do_lu),
- OI_CHECK_FLD) ?
- LMAC_FID_ON_OST : 0, 0);
- if (rc != 0)
- CWARN("%s: cannot self repair the LMA: "
- "rc = %d\n", osd_name(osd), rc);
- ldiskfs_journal_stop(jh);
+ osd_lma_self_repair(info, osd, inode, rfid,
+ fid_is_on_ost(info, osd, fid, OI_CHECK_FLD) ?
+ LMAC_FID_ON_OST : 0);
RETURN(0);
}
}
CWARN("%s: unsupported incompat LMA feature(s) %#x for "
"fid = "DFID", ino = %lu\n", osd_name(osd),
lma->lma_incompat & ~LMA_INCOMPAT_SUPP,
- PFID(lu_object_fid(&obj->oo_dt.do_lu)),
- inode->i_ino);
+ PFID(rfid), inode->i_ino);
rc = -EOPNOTSUPP;
} else if (!(lma->lma_compat & LMAC_NOT_IN_OI)) {
fid = &lma->lma_self_fid;
}
}
- if (fid != NULL &&
- unlikely(!lu_fid_eq(lu_object_fid(&obj->oo_dt.do_lu), fid))) {
+ if (fid != NULL && unlikely(!lu_fid_eq(rfid, fid))) {
+ if (fid_is_idif(rfid) && fid_is_idif(fid)) {
+ struct ost_id *oi = &info->oti_ostid;
+ struct lu_fid *fid1 = &info->oti_fid3;
+ __u32 idx = fid_idif_ost_idx(rfid);
+
+ /* For old IDIF, the OST index is not part of the IDIF,
+ * Means that different OSTs may have the same IDIFs.
+ * Under such case, we need to make some compatible
+ * check to make sure to trigger OI scrub properly. */
+ if (idx != 0 && fid_idif_ost_idx(fid) == 0) {
+ /* Given @rfid is new, LMA is old. */
+ fid_to_ostid(fid, oi);
+ ostid_to_fid(fid1, oi, idx);
+ if (lu_fid_eq(fid1, rfid)) {
+ if (osd->od_lma_self_repair)
+ osd_lma_self_repair(info, osd,
+ inode, rfid,
+ LMAC_FID_ON_OST);
+ RETURN(0);
+ }
+ }
+ }
+
CDEBUG(D_INODE, "%s: FID "DFID" != self_fid "DFID"\n",
- osd_name(osd), PFID(lu_object_fid(&obj->oo_dt.do_lu)),
- PFID(&lma->lma_self_fid));
+ osd_name(osd), PFID(rfid), PFID(fid));
rc = -EREMCHG;
}
#include <obd.h>
#include <obd_class.h>
#include <obd_cksum.h>
+#include <md_object.h>
#include "tgt_internal.h"
*/
int tgt_validate_obdo(struct tgt_session_info *tsi, struct obdo *oa)
{
- int rc;
-
+ struct ost_id *oi = &oa->o_oi;
+ obd_seq seq = ostid_seq(oi);
+ obd_id id = ostid_id(oi);
+ int rc;
ENTRY;
if (unlikely(!(exp_connect_flags(tsi->tsi_exp) & OBD_CONNECT_FID) &&
- fid_seq_is_echo(oa->o_oi.oi.oi_seq))) {
+ fid_seq_is_echo(seq))) {
/* Sigh 2.[123] client still sends echo req with oi_id = 0
* during create, and we will reset this to 1, since this
* oi_id is basically useless in the following create process,
* but oi_id == 0 will make it difficult to tell whether it is
* real FID or ost_id. */
- oa->o_oi.oi_fid.f_oid = oa->o_oi.oi.oi_id ?: 1;
- oa->o_oi.oi_fid.f_seq = FID_SEQ_ECHO;
- oa->o_oi.oi_fid.f_ver = 0;
+ oi->oi_fid.f_seq = FID_SEQ_ECHO;
+ oi->oi_fid.f_oid = id ?: 1;
+ oi->oi_fid.f_ver = 0;
} else {
- if (unlikely((oa->o_valid & OBD_MD_FLID &&
- ostid_id(&oa->o_oi) == 0)))
+ struct lu_fid *fid = &tsi->tsi_fid2;
+
+ if (unlikely((oa->o_valid & OBD_MD_FLID) && id == 0))
GOTO(out, rc = -EPROTO);
/* Note: this check might be forced in 2.5 or 2.6, i.e.
* all of the requests are required to setup FLGROUP */
if (unlikely(!(oa->o_valid & OBD_MD_FLGROUP))) {
- ostid_set_seq_mdt0(&oa->o_oi);
+ ostid_set_seq_mdt0(oi);
oa->o_valid |= OBD_MD_FLGROUP;
+ seq = ostid_seq(oi);
}
- if (unlikely(!(fid_seq_is_idif(ostid_seq(&oa->o_oi)) ||
- fid_seq_is_mdt0(ostid_seq(&oa->o_oi)) ||
- fid_seq_is_norm(ostid_seq(&oa->o_oi)) ||
- fid_seq_is_echo(ostid_seq(&oa->o_oi)))))
+ if (unlikely(!(fid_seq_is_idif(seq) || fid_seq_is_mdt0(seq) ||
+ fid_seq_is_norm(seq) || fid_seq_is_echo(seq))))
GOTO(out, rc = -EPROTO);
+
+ rc = ostid_to_fid(fid, oi, tsi->tsi_tgt->lut_lsd.lsd_osd_index);
+ if (unlikely(rc != 0))
+ GOTO(out, rc);
+
+ oi->oi_fid = *fid;
}
+
RETURN(0);
+
out:
CERROR("%s: client %s sent bad object "DOSTID": rc = %d\n",
tgt_name(tsi->tsi_tgt), obd_export_nid2str(tsi->tsi_exp),
- ostid_seq(&oa->o_oi), ostid_id(&oa->o_oi), rc);
+ seq, id, rc);
return rc;
}
EXPORT_SYMBOL(tgt_validate_obdo);
}
tsi->tsi_ost_body = body;
+ tsi->tsi_fid = body->oa.o_oi.oi_fid;
if (req_capsule_has_field(pill, &RMF_OBD_IOOBJ, RCL_CLIENT)) {
rc = tgt_io_data_unpack(tsi, &body->oa.o_oi);
}
}
- rc = ostid_to_fid(&tsi->tsi_fid, &body->oa.o_oi, 0);
- if (rc != 0)
- RETURN(rc);
-
- if (!fid_is_sane(&tsi->tsi_fid)) {
- CERROR("%s: invalid FID: "DFID"\n", tgt_name(tsi->tsi_tgt),
- PFID(&tsi->tsi_fid));
- RETURN(-EINVAL);
- }
-
ost_fid_build_resid(&tsi->tsi_fid, &tsi->tsi_resid);
/*
if (unlikely(rc != 0))
RETURN(rc);
- ost_fid_from_resid(&fid, &lock->l_resource->lr_name);
+ ost_fid_from_resid(&fid, &lock->l_resource->lr_name,
+ tgt->lut_lsd.lsd_osd_index);
obj = dt_locate(&env, tgt->lut_bottom, &fid);
if (IS_ERR(obj))
GOTO(err_env, rc = PTR_ERR(obj));