Пример #1
0
/* 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);
}
Пример #2
0
/**
 * 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);
}
Пример #3
0
/**
 * Allocate the whole seq to the caller.
 **/
int seq_client_get_seq(const struct lu_env *env,
		       struct lu_client_seq *seq, u64 *seqnr)
{
	wait_queue_t link;
	int rc;

	LASSERT(seqnr != NULL);
	mutex_lock(&seq->lcs_mutex);
	init_waitqueue_entry_current(&link);

        while (1) {
                rc = seq_fid_alloc_prep(seq, &link);
                if (rc == 0)
                        break;
        }

        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: allocate sequence "
               "[0x%16.16"LPF64"x]\n", seq->lcs_name, *seqnr);

	/* Since the caller require the whole seq,
	 * so marked this seq to be used */
	if (seq->lcs_type == LUSTRE_SEQ_METADATA)
		seq->lcs_fid.f_oid = LUSTRE_METADATA_SEQ_MAX_WIDTH;
	else
		seq->lcs_fid.f_oid = LUSTRE_DATA_SEQ_MAX_WIDTH;

	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.
         */
        seq_fid_alloc_fini(seq);
	mutex_unlock(&seq->lcs_mutex);

        return rc;
}
Пример #4
0
/**
 * Allocate the whole non-used seq to the caller.
 *
 * \param[in] env	pointer to the thread context
 * \param[in,out] seq	pointer to the client sequence manager
 * \param[out] seqnr	to hold the new allocated sequence
 *
 * \retval		0 for new sequence allocated.
 * \retval		Negative error number on failure.
 */
int seq_client_get_seq(const struct lu_env *env,
		       struct lu_client_seq *seq, u64 *seqnr)
{
	wait_queue_t link;
	int rc;

	LASSERT(seqnr != NULL);

	mutex_lock(&seq->lcs_mutex);
	init_waitqueue_entry(&link, current);

	/* To guarantee that we can get a whole non-used sequence. */
	while (seq_fid_alloc_prep(seq, &link) != 0);

	rc = seq_client_alloc_seq(env, seq, seqnr);
	seq_fid_alloc_fini(seq, rc ? 0 : *seqnr, true);
	if (rc)
		CERROR("%s: Can't allocate new sequence: rc = %d\n",
		       seq->lcs_name, rc);
	mutex_unlock(&seq->lcs_mutex);

	return rc;
}
Пример #5
0
/* 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;
}