get a free request

 

/**
 * __get_request - get a free request
 * @rl: request list to allocate from
 * @op: REQ_OP_READ/REQ_OP_WRITE
 * @op_flags: rq_flag_bits
 * @bio: bio to allocate request for (can be %NULL)
 * @gfp_mask: allocation mask
 *
 * Get a free request from @q.  This function may fail under memory
 * pressure or if @q is dead.
 *
 * Must be called with @q->queue_lock held and,
 * Returns ERR_PTR on failure, with @q->queue_lock held.
 * Returns request pointer on success, with @q->queue_lock *not held*.
 */
static struct request *__get_request(struct request_list *rl, int op,
				     int op_flags, struct bio *bio,
				     gfp_t gfp_mask)
{
	struct request_queue *q = rl->q;
	struct request *rq;
	struct elevator_type *et = q->elevator->type;
	struct io_context *ioc = rq_ioc(bio);
	struct io_cq *icq = NULL;
	const bool is_sync = rw_is_sync(op, op_flags) != 0;
	int may_queue;


	if (unlikely(blk_queue_dying(q)))
		return ERR_PTR(-ENODEV);


	may_queue = elv_may_queue(q, op, op_flags);
	if (may_queue == ELV_MQUEUE_NO)
		goto rq_starved;


	if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
		if (rl->count[is_sync]+1 >= q->nr_requests) {
			if (!blk_rl_full(rl, is_sync)) {
				ioc_set_batching(q, ioc);
				blk_set_rl_full(rl, is_sync);
			} else {
				if (may_queue != ELV_MQUEUE_MUST
						&& !ioc_batching(q, ioc)) {
					return ERR_PTR(-ENOMEM);
				}
			}
		}
		blk_set_congested(rl, is_sync);
	}

	if (rl->count[is_sync] >= (3 * q->nr_requests / 2))
		return ERR_PTR(-ENOMEM);


	q->nr_rqs[is_sync]++;
	rl->count[is_sync]++;
	rl->starved[is_sync] = 0;


	if (blk_rq_should_init_elevator(bio) && !blk_queue_bypass(q)) {
		op_flags |= REQ_ELVPRIV;
		q->nr_rqs_elvpriv++;
		if (et->icq_cache && ioc)
			icq = ioc_lookup_icq(ioc, q);
	}


	if (blk_queue_io_stat(q))
		op_flags |= REQ_IO_STAT;
	spin_unlock_irq(q->queue_lock);


	/* allocate and init request */
	rq = mempool_alloc(rl->rq_pool, gfp_mask);
	if (!rq)
		goto fail_alloc;


	blk_rq_init(q, rq);
	blk_rq_set_rl(rq, rl);
	req_set_op_attrs(rq, op, op_flags | REQ_ALLOCED);


	/* init elvpriv */
	if (op_flags & REQ_ELVPRIV) {
		if (unlikely(et->icq_cache && !icq)) {
			if (ioc)
				icq = ioc_create_icq(ioc, q, gfp_mask);
			if (!icq)
				goto fail_elvpriv;
		}


		rq->elv.icq = icq;
		if (unlikely(elv_set_request(q, rq, bio, gfp_mask)))
			goto fail_elvpriv;


		/* @rq->elv.icq holds io_context until @rq is freed */
		if (icq)
			get_io_context(icq->ioc);
	}
out:
	if (ioc_batching(q, ioc))
		ioc->nr_batch_requests--;


	trace_block_getrq(q, bio, op);
      return rq;


fail_elvpriv:
	printk_ratelimited(KERN_WARNING "%s: dev %s: request aux data allocation failed, iosched may be disturbed\n",
			   __func__, dev_name(q->backing_dev_info.dev));


	rq->cmd_flags &= ~REQ_ELVPRIV;
	rq->elv.icq = NULL;


	spin_lock_irq(q->queue_lock);
	q->nr_rqs_elvpriv--;
	spin_unlock_irq(q->queue_lock);
	goto out;


fail_alloc:
	spin_lock_irq(q->queue_lock);
	freed_request(rl, op, op_flags);

rq_starved:
	if (unlikely(rl->count[is_sync] == 0))
		rl->starved[is_sync] = 1;
	return ERR_PTR(-ENOMEM);
}
static struct io_context *rq_ioc(struct bio *bio)
{
#ifdef CONFIG_BLK_CGROUP
	if (bio && bio->bi_ioc)
		return bio->bi_ioc;
#endif
	return current->io_context;
}
 
bio_associate_current:blk_throtl_bio<-- blkcg_bio_issue_check<-- generic_make_request_checks
bio_disassociate_task: __bio_free  < bio_free, bio_reset>

 
 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi中的Request方法提供了一种发送请求到服务器的方式。在这种方法中,Options是一种特殊的请求方法。 Options请求方法用于获取特定URL的支持的各种请求方法。它不会对服务器上的资源做出任何修改,只是用于查询服务器所支持的请求方法。 在Delphi中,可以使用Request方法发送Options请求。通过设置请求的Method属性为Options,可以向服务器发送这个特殊的Options请求。在发送之后,服务器会返回一个包含允许该URL使用的请求方法的列表。 使用Options请求方法的一个常见场景是在使用Restful API时,客户端需要查找特定URL所支持的请求方法,以便能够进行适当的操作。通过发送Options请求,客户端可以得到服务器返回的请求方法列表,并据此决定使用哪种方法进行操作。 示例代码如下: ``` var http: TIdHTTP; response: TStringStream; begin http := TIdHTTP.Create; response := TStringStream.Create; try http.Request.Method := 'Options'; http.Get('http://example.com/api', response); // 以Get方式发送Options请求 ShowMessage(response.DataString); finally http.Free; response.Free; end; end; ``` 以上代码向"http://example.com/api"发送一个Options请求,并将服务器返回的信息存储在response中。可以根据服务器返回的信息做出相应的处理。 通过使用Delphi中的Request方法发送Options请求,可以方便地获取服务器支持的请求方法列表。这样可以在客户端代码中针对不同的URL进行相应的操作,实现更加灵活和自定义的请求处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值