Example #1
0
int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
		  const struct lu_fid *fid, struct osd_inode_id *id,
		  enum oi_check_flags flags)
{
	if (unlikely(fid_is_last_id(fid)))
		return osd_obj_spec_lookup(info, osd, fid, id);

	if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
		return osd_obj_map_lookup(info, osd, fid, id);


	if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) {
		int rc;
		if (fid_is_fs_root(fid)) {
			osd_id_gen(id, osd_sb(osd)->s_root->d_inode->i_ino,
				   osd_sb(osd)->s_root->d_inode->i_generation);
			return 0;
		}
		if (unlikely(fid_is_acct(fid)))
			return osd_acct_obj_lookup(info, osd, fid, id);

		/* For other special FIDs, try OI first, then do spec lookup */
		rc = __osd_oi_lookup(info, osd, fid, id);
		if (rc == -ENOENT)
			return osd_obj_spec_lookup(info, osd, fid, id);
		return rc;
	}

	if (!osd->od_igif_inoi && fid_is_igif(fid)) {
		osd_id_gen(id, lu_igif_ino(fid), lu_igif_gen(fid));
		return 0;
	}

	return __osd_oi_lookup(info, osd, fid, id);
}
Example #2
0
int fid_is_on_ost(struct osd_thread_info *info, struct osd_device *osd,
		  const struct lu_fid *fid, enum oi_check_flags flags)
{
	struct lu_seq_range	*range = &info->oti_seq_range;
	int			rc;
	ENTRY;

	if (flags & OI_KNOWN_ON_OST)
		RETURN(1);

	if (unlikely(fid_is_local_file(fid) || fid_is_igif(fid) ||
		     fid_is_llog(fid)) || fid_is_name_llog(fid) ||
		     fid_is_quota(fid))
		RETURN(0);

	if (fid_is_idif(fid) || fid_is_last_id(fid))
		RETURN(1);

	if (!(flags & OI_CHECK_FLD))
		RETURN(0);

	rc = osd_fld_lookup(info->oti_env, osd, fid_seq(fid), range);
	if (rc != 0) {
		if (rc != -ENOENT)
			CERROR("%s: lookup FLD "DFID": rc = %d\n",
			       osd_name(osd), PFID(fid), rc);
		RETURN(0);
	}

	if (fld_range_is_ost(range))
		RETURN(1);

	RETURN(0);
}
Example #3
0
int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
		  const struct lu_fid *fid, struct osd_inode_id *id,
		  enum oi_check_flags flags)
{
	if (unlikely(fid_is_last_id(fid)))
		return osd_obj_spec_lookup(info, osd, fid, id);

	if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
		return osd_obj_map_lookup(info, osd, fid, id);

	if (fid_is_fs_root(fid)) {
		osd_id_gen(id, osd_sb(osd)->s_root->d_inode->i_ino,
			   osd_sb(osd)->s_root->d_inode->i_generation);
		return 0;
	}

	if (unlikely(fid_is_acct(fid)))
		return osd_acct_obj_lookup(info, osd, fid, id);

	if (!osd->od_igif_inoi && fid_is_igif(fid)) {
		osd_id_gen(id, lu_igif_ino(fid), lu_igif_gen(fid));
		return 0;
	}

	return __osd_oi_lookup(info, osd, fid, id);
}
Example #4
0
/**
 * 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;
}
Example #5
0
static int lfsck_master_oit_engine(const struct lu_env *env,
				   struct lfsck_instance *lfsck)
{
	struct lfsck_thread_info	*info	= lfsck_env_info(env);
	const struct dt_it_ops		*iops	=
				&lfsck->li_obj_oit->do_index_ops->dio_it;
	struct dt_it			*di	= lfsck->li_di_oit;
	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);
			if (rc <= 0)
				RETURN(rc);
		}

		if (unlikely(lfsck->li_oit_over))
			RETURN(1);

		if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY1) &&
		    cfs_fail_val > 0) {
			struct l_wait_info lwi;

			lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val),
					  NULL, NULL);
			l_wait_event(thread->t_ctl_waitq,
				     !thread_is_running(thread),
				     &lwi);
		}

		if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_CRASH))
			RETURN(0);

		lfsck->li_current_oit_processed = 1;
		lfsck->li_new_scanned++;
		rc = iops->rec(env, di, (struct dt_rec *)fid, 0);
		if (rc != 0) {
			lfsck_fail(env, lfsck, true);
			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;
			}
		} else if (!fid_is_norm(fid) && !fid_is_igif(fid) &&
			   !fid_is_last_id(fid) && !fid_is_root(fid) &&
			   !fid_seq_is_dot(fid_seq(fid))) {
			/* If the FID/object is only used locally and invisible
			 * to external nodes, then LFSCK will not handle it. */
			goto checkpoint;
		}

		target = lfsck_object_find(env, lfsck, fid);
		if (target == NULL) {
			goto checkpoint;
		} else if (IS_ERR(target)) {
			lfsck_fail(env, lfsck, true);
			if (bk->lb_param & LPF_FAILOUT)
				RETURN(PTR_ERR(target));
			else
				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)) {
			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);

checkpoint:
		rc = lfsck_checkpoint(env, lfsck);
		if (rc != 0 && bk->lb_param & LPF_FAILOUT)
			RETURN(rc);

		/* Rate control. */
		lfsck_control_speed(lfsck);

		if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_FATAL1)) {
			spin_lock(&lfsck->li_lock);
			thread_set_flags(thread, SVC_STOPPING);
			spin_unlock(&lfsck->li_lock);
			RETURN(-EINVAL);
		}

		rc = iops->next(env, di);
		if (unlikely(rc > 0))
			lfsck->li_oit_over = 1;
		else if (likely(rc == 0))
			lfsck->li_current_oit_processed = 0;

		if (unlikely(!thread_is_running(thread)))
			RETURN(0);
	} while (rc == 0 || lfsck->li_di_dir != NULL);

	RETURN(rc);
}
Example #6
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);
}