static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags) { struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; struct ptlrpc_service *svc = svcpt->scp_service; int service_time = max_t(int, cfs_time_current_sec() - req->rq_arrival_time.tv_sec, 1); if (!(flags & PTLRPC_REPLY_EARLY) && (req->rq_type != PTL_RPC_MSG_ERR) && (req->rq_reqmsg != NULL) && !(lustre_msg_get_flags(req->rq_reqmsg) & (MSG_RESENT | MSG_REPLAY | MSG_REQ_REPLAY_DONE | MSG_LOCK_REPLAY_DONE))) { /* early replies, errors and recovery requests don't count * toward our service time estimate */ int oldse = at_measured(&svcpt->scp_at_estimate, service_time); if (oldse != 0) { DEBUG_REQ(D_ADAPTTO, req, "svc %s changed estimate from %d to %d", svc->srv_name, oldse, at_get(&svcpt->scp_at_estimate)); } } /* Report actual service time for client latency calc */ lustre_msg_set_service_time(req->rq_repmsg, service_time); /* Report service time estimate for future client reqs, but report 0 * (to be ignored by client) if it's a error reply during recovery. * (bz15815) */ if (req->rq_type == PTL_RPC_MSG_ERR && (req->rq_export == NULL || req->rq_export->exp_obd->obd_recovering)) lustre_msg_set_timeout(req->rq_repmsg, 0); else lustre_msg_set_timeout(req->rq_repmsg, at_get(&svcpt->scp_at_estimate)); if (req->rq_reqmsg && !(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { CDEBUG(D_ADAPTTO, "No early reply support: flags=%#x " "req_flags=%#x magic=%d:%x/%x len=%d\n", flags, lustre_msg_get_flags(req->rq_reqmsg), lustre_msg_is_v1(req->rq_reqmsg), lustre_msg_get_magic(req->rq_reqmsg), lustre_msg_get_magic(req->rq_repmsg), req->rq_replen); } }
/* * Handle quota request from slave. * * \param env - is the environment passed by the caller * \param ld - is the lu device associated with the qmt * \param req - is the quota acquire request */ static int qmt_dqacq(const struct lu_env *env, struct lu_device *ld, struct ptlrpc_request *req) { struct qmt_device *qmt = lu2qmt_dev(ld); struct quota_body *qbody, *repbody; struct obd_uuid *uuid; struct ldlm_lock *lock; struct lquota_entry *lqe; int pool_id, pool_type, qtype; int rc; ENTRY; qbody = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_BODY); if (qbody == NULL) RETURN(err_serious(-EPROTO)); repbody = req_capsule_server_get(&req->rq_pill, &RMF_QUOTA_BODY); if (repbody == NULL) RETURN(err_serious(-EFAULT)); /* verify if global lock is stale */ if (!lustre_handle_is_used(&qbody->qb_glb_lockh)) RETURN(-ENOLCK); lock = ldlm_handle2lock(&qbody->qb_glb_lockh); if (lock == NULL) RETURN(-ENOLCK); LDLM_LOCK_PUT(lock); uuid = &req->rq_export->exp_client_uuid; if (req_is_rel(qbody->qb_flags) + req_is_acq(qbody->qb_flags) + req_is_preacq(qbody->qb_flags) > 1) { CERROR("%s: malformed quota request with conflicting flags set " "(%x) from slave %s\n", qmt->qmt_svname, qbody->qb_flags, obd_uuid2str(uuid)); RETURN(-EPROTO); } if (req_is_acq(qbody->qb_flags) || req_is_preacq(qbody->qb_flags)) { /* acquire and pre-acquire should use a valid ID lock */ if (!lustre_handle_is_used(&qbody->qb_lockh)) RETURN(-ENOLCK); lock = ldlm_handle2lock(&qbody->qb_lockh); if (lock == NULL) /* no lock associated with this handle */ RETURN(-ENOLCK); LDLM_DEBUG(lock, "%sacquire request", req_is_preacq(qbody->qb_flags) ? "pre" : ""); if (!obd_uuid_equals(&lock->l_export->exp_client_uuid, uuid)) { /* sorry, no way to cheat ... */ LDLM_LOCK_PUT(lock); RETURN(-ENOLCK); } if ((lock->l_flags & LDLM_FL_AST_SENT) != 0) { struct ptlrpc_service_part *svc; unsigned int timeout; svc = req->rq_rqbd->rqbd_svcpt; timeout = at_est2timeout(at_get(&svc->scp_at_estimate)); timeout = max(timeout, ldlm_timeout); /* lock is being cancelled, prolong timeout */ ldlm_refresh_waiting_lock(lock, timeout); } LDLM_LOCK_PUT(lock); } /* extract pool & quota information from global index FID packed in the * request */ rc = lquota_extract_fid(&qbody->qb_fid, &pool_id, &pool_type, &qtype); if (rc) RETURN(-EINVAL); /* Find the quota entry associated with the quota id */ lqe = qmt_pool_lqe_lookup(env, qmt, pool_id, pool_type, qtype, &qbody->qb_id); if (IS_ERR(lqe)) RETURN(PTR_ERR(lqe)); /* process quota request */ rc = qmt_dqacq0(env, lqe, qmt, uuid, qbody->qb_flags, qbody->qb_count, qbody->qb_usage, repbody); if (lustre_handle_is_used(&qbody->qb_lockh)) /* return current qunit value only to slaves owning an per-ID * quota lock. For enqueue, the qunit value will be returned in * the LVB */ repbody->qb_qunit = lqe->lqe_qunit; lqe_putref(lqe); RETURN(rc); }
int main(int argc, char** argv) { ATOMIC_TYPE var; VALUE_TYPE r; ATOMIC_TYPE* v; v=&var; #ifdef MEMBAR_USES_LOCK __membar_lock=&dummy_membar_lock; if (lock_init(__membar_lock)==0){ fprintf(stderr, "ERROR: failed to initialize membar_lock\n"); __membar_lock=0; goto error; } _membar_lock; /* start with the lock "taken" so that we can safely use unlock/lock sequences on it later */ #endif #ifdef ATOMIC_OPS_USE_LOCK /* init the lock (emulate atomic_ops.c) */ _atomic_lock=&dummy_atomic_lock; if (lock_init(_atomic_lock)==0){ fprintf(stderr, "ERROR: failed to initialize atomic_lock\n"); _atomic_lock=0; goto error; } #endif printf("%s\n", flags); printf("starting memory barrier opcode tests...\n"); membar(); printf(" membar() .............................. ok\n"); membar_write(); printf(" membar_write() ........................ ok\n"); membar_read(); printf(" membar_read() ......................... ok\n"); printf("\nstarting atomic ops basic tests...\n"); VERIFY(at_set(v, 1), 1); printf(" atomic_set, v should be 1 ............. %2d\n", (int)at_get(v)); VERIFY(at_inc(v), 2); printf(" atomic_inc, v should be 2 ............. %2d\n", (int)at_get(v)); VERIFY(r=at_inc_and_test(v), 3); printf(" atomic_inc_and_test, v should be 3 ... %2d\n", (int)at_get(v)); printf(" r should be 0 ... %2d\n", (int)r); VERIFY(at_dec(v), 2); printf(" atomic_dec, v should be 2 ............. %2d\n", (int)at_get(v)); VERIFY(r=at_dec_and_test(v), 1); printf(" atomic_dec_and_test, v should be 1 ... %2d\n", (int)at_get(v)); printf(" r should be 0 ... %2d\n", (int)r); VERIFY(r=at_dec_and_test(v), 0); printf(" atomic_dec_and_test, v should be 0 ... %2d\n", (int)at_get(v)); printf(" r should be 1 ... %2d\n", (int)r); VERIFY(r=at_dec_and_test(v), -1); printf(" atomic_dec_and_test, v should be -1 ... %2d\n", (int)at_get(v)); printf(" r should be 0 ... %2d\n", (int)r); VERIFY(at_and(v, 2), 2); printf(" atomic_and, v should be 2 ............. %2d\n", (int)at_get(v)); VERIFY(at_or(v, 5), 7); VERIFY(r=at_get_and_set(v, 0), 0); printf(" atomic_or, v should be 7 ............. %2d\n", (int)r); printf(" atomic_get_and_set, v should be 0 ..... %2d\n", (int)at_get(v)); printf("\ndone.\n"); #ifdef MEMBAR_USES_LOCK lock_destroy(__membar_lock); #endif #ifdef ATOMIC_OPS_USE_LOCK lock_destroy(_atomic_lock); #endif return 0; error: #ifdef MEMBAR_USES_LOCK if (__membar_lock) lock_destroy(__membar_lock); #endif #ifdef ATOMIC_OPS_USE_LOCK if (_atomic_lock) lock_destroy(_atomic_lock); #endif return -1; }