/** * Delete unused orphan with FID \a lf from PENDING directory * * \param mdd MDD device finishing recovery * \param lf FID of file or directory to delete * \param key cookie for this entry in index iterator * * \retval 0 success * \retval -ve error */ static int orph_key_test_and_del(const struct lu_env *env, struct mdd_device *mdd, struct lu_fid *lf, struct dt_key *key) { struct mdd_object *mdo; int rc; mdo = mdd_object_find(env, mdd, lf); if (IS_ERR(mdo)) return PTR_ERR(mdo); rc = -EBUSY; if (mdo->mod_count == 0) { CDEBUG(D_HA, "Found orphan "DFID", delete it\n", PFID(lf)); rc = orphan_object_destroy(env, mdo, key); if (rc) /* so replay-single.sh test_37 works */ CERROR("%s: error unlinking orphan "DFID" from " "PENDING: rc = %d\n", mdd2obd_dev(mdd)->obd_name, PFID(lf), rc); } else { mdd_write_lock(env, mdo, MOR_TGT_CHILD); if (likely(mdo->mod_count > 0)) { CDEBUG(D_HA, "Found orphan "DFID" count %d, skip it\n", PFID(lf), mdo->mod_count); mdo->mod_flags |= ORPHAN_OBJ; } mdd_write_unlock(env, mdo); } mdd_object_put(env, mdo); return rc; }
static int orph_key_test_and_del(const struct lu_env *env, struct mdd_device *mdd, struct lu_fid *lf, struct dt_key *key) { struct mdd_object *mdo; int rc; mdo = mdd_object_find(env, mdd, lf); if (IS_ERR(mdo)) return PTR_ERR(mdo); rc = -EBUSY; if (mdo->mod_count == 0) { CWARN("Found orphan! Delete it\n"); rc = orphan_object_destroy(env, mdo, key); } else { mdd_write_lock(env, mdo, MOR_TGT_CHILD); if (likely(mdo->mod_count > 0)) { CDEBUG(D_HA, "Found orphan, open count = %d\n", mdo->mod_count); mdo->mod_flags |= ORPHAN_OBJ; } mdd_write_unlock(env, mdo); } mdd_object_put(env, mdo); return rc; }
/** * Lookup method for "fid" object. Only filenames with correct SEQ:OID format * are valid. We also check if object with passed fid exists or not. */ static int obf_lookup(const struct lu_env *env, struct md_object *p, const struct lu_name *lname, struct lu_fid *f, struct md_op_spec *spec) { char *name = (char *)lname->ln_name; struct mdd_device *mdd = mdo2mdd(p); struct mdd_object *child; int rc = 0; while (*name == '[') name++; sscanf(name, SFID, RFID(f)); if (!fid_is_sane(f)) { CWARN("%s: Trying to lookup invalid FID [%s] in %s/%s, FID " "format should be "DFID"\n", mdd2obd_dev(mdd)->obd_name, lname->ln_name, dot_lustre_name, mdd_obf_dir_name, (__u64)FID_SEQ_NORMAL, 1, 0); GOTO(out, rc = -EINVAL); } if (!fid_is_norm(f) && !fid_is_igif(f) && !fid_is_root(f) && !fid_seq_is_dot(f->f_seq)) { CWARN("%s: Trying to lookup invalid FID "DFID" in %s/%s, " "sequence should be >= "LPX64" or within ["LPX64"," ""LPX64"].\n", mdd2obd_dev(mdd)->obd_name, PFID(f), dot_lustre_name, mdd_obf_dir_name, (__u64)FID_SEQ_NORMAL, (__u64)FID_SEQ_IGIF, (__u64)FID_SEQ_IGIF_MAX); GOTO(out, rc = -EINVAL); } /* Check if object with this fid exists */ child = mdd_object_find(env, mdd, f); if (child == NULL) GOTO(out, rc = 0); if (IS_ERR(child)) GOTO(out, rc = PTR_ERR(child)); if (mdd_object_exists(child) == 0) rc = -ENOENT; mdd_object_put(env, child); out: return rc; }
static int mdd_convert_object(const struct lu_env *env, struct mdd_device *mdd, const struct lu_fid *fid, const struct lu_name *name) { struct mdd_object *o; struct lu_attr *la = MDD_ENV_VAR(env, cattr); int rc; ENTRY; o = mdd_object_find(env, mdd, fid); if (IS_ERR(o)) { CERROR("%s: can't access the object: rc = %d\n", mdd2obd_dev(mdd)->obd_name, (int)PTR_ERR(o)); RETURN(PTR_ERR(o)); } rc = mdo_attr_get(env, o, la, BYPASS_CAPA); if (rc) GOTO(out, rc); if (S_ISDIR(la->la_mode)) { /* remove "." and ".." if a directory */ rc = mdd_convert_remove_dots(env, mdd, o); if (rc) GOTO(out, rc); } /* update linkEA */ rc = mdd_convert_linkea(env, mdd, o, name); if (rc) CERROR("%s: can't convert: rc = %d\n", mdd2obd_dev(mdd)->obd_name, rc); out: mdd_object_put(env, o); RETURN(0); }
int mdd_compat_fixes(const struct lu_env *env, struct mdd_device *mdd) { struct mdd_thread_info *info = mdd_env_info(env); struct mdd_object *root; struct dt_object *o; struct lustre_mdt_attrs *lma; struct lu_buf buf; int rc; ENTRY; /* IGIF FIDS are valid for old 1.8 and 2.[123] ROOT and are kept. * Normal FIDs used by Xyratex 1.8->2.1 upgrade tool are also kept. */ if (fid_is_igif(&mdd->mdd_root_fid) || fid_is_norm(&mdd->mdd_root_fid)) RETURN(0); /* * FID is supposed to be FID_SEQ_ROOT for: * - new ldiskfs fs * - new ZFS fs * - old ZFS fs, by now processed with osd_convert_root_to_new_seq() */ if (fid_seq(&mdd->mdd_root_fid) != FID_SEQ_ROOT) { CERROR("%s: wrong FID "DFID" is used for /ROOT\n", mdd2obd_dev(mdd)->obd_name, PFID(&mdd->mdd_root_fid)); RETURN(-EINVAL); } root = mdd_object_find(env, mdd, &mdd->mdd_root_fid); if (IS_ERR(root)) RETURN(PTR_ERR(root)); o = mdd_object_child(root); CDEBUG(D_OTHER, "/ROOT = "DFID"\n", PFID(&mdd->mdd_root_fid)); if (dt_try_as_dir(env, o) == 0) { CERROR("%s: not a directory\n", mdd2obd_dev(mdd)->obd_name); GOTO(out, rc = -ENOTDIR); } lma = (struct lustre_mdt_attrs *)&info->mti_xattr_buf; CLASSERT(sizeof(info->mti_xattr_buf) >= LMA_OLD_SIZE); buf.lb_len = LMA_OLD_SIZE; buf.lb_buf = lma; rc = mdo_xattr_get(env, root, &buf, XATTR_NAME_LMA, BYPASS_CAPA); if (rc < 0 && rc != -ENODATA) { CERROR("%s: can't fetch LMA: rc = %d\n", mdd2obd_dev(mdd)->obd_name, rc); GOTO(out, rc); } lustre_lma_swab(lma); if (lu_fid_eq(&lma->lma_self_fid, &mdd->mdd_root_fid)) { /* /ROOT has been converted already * or was correct from the beginning */ CDEBUG(D_OTHER, "%s: converted already\n", mdd2obd_dev(mdd)->obd_name); GOTO(out, rc = 0); } /* this is supposed to happen only on pre-production ZFS backend */ if (strcmp(mdd->mdd_bottom->dd_lu_dev.ld_type->ldt_name, LUSTRE_OSD_ZFS_NAME) != 0) { CERROR("%s: "DFID" is used on ldiskfs?!\n", mdd2obd_dev(mdd)->obd_name, PFID(&mdd->mdd_root_fid)); GOTO(out, rc = -ENOTSUPP); } LCONSOLE_INFO("%s: FID of /ROOT has been changed. " "Please remount the clients.\n", mdd2obd_dev(mdd)->obd_name); /* Fill FLDB first */ rc = mdd_fill_fldb(env, mdd); if (rc) GOTO(out, rc); /* remove ./.. from /ROOT */ rc = mdd_convert_remove_dots(env, mdd, root); if (rc) GOTO(out, rc); /* go over the directory, fix all the objects */ rc = mdd_fix_children(env, mdd, o); if (rc) GOTO(out, rc); /* Update LMA on /ROOT. Done for simplicity in MDD, not in osd-zfs. * Correct LMA will imply the whole directory has been coverted * successfully, otherwise it will be retried on next mount. */ rc = mdd_convert_lma(env, mdd, root); out: mdd_object_put(env, root); RETURN(rc); }