|  | @@ -80,3 +80,156 @@ static void drive_stat_acct(struct request *rq, int new_io)
 | 
	
		
			
				|  |  |  			 * The partition is already being removed,
 | 
	
		
			
				|  |  |  			 * the request will be accounted on the disk only
 | 
	
		
			
				|  |  |  			 *
 | 
	
		
			
				|  |  | +			 * We take a reference on disk->part0 although that
 | 
	
		
			
				|  |  | +			 * partition will never be deleted, so we can treat
 | 
	
		
			
				|  |  | +			 * it as any other partition.
 | 
	
		
			
				|  |  | +			 */
 | 
	
		
			
				|  |  | +			part = &rq->rq_disk->part0;
 | 
	
		
			
				|  |  | +			hd_struct_get(part);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		part_round_stats(cpu, part);
 | 
	
		
			
				|  |  | +		part_inc_in_flight(part, rw);
 | 
	
		
			
				|  |  | +		rq->part = part;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	part_stat_unlock();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void blk_queue_congestion_threshold(struct request_queue *q)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int nr;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	nr = q->nr_requests - (q->nr_requests / 8) + 1;
 | 
	
		
			
				|  |  | +	if (nr > q->nr_requests)
 | 
	
		
			
				|  |  | +		nr = q->nr_requests;
 | 
	
		
			
				|  |  | +	q->nr_congestion_on = nr;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	nr = q->nr_requests - (q->nr_requests / 8) - (q->nr_requests / 16) - 1;
 | 
	
		
			
				|  |  | +	if (nr < 1)
 | 
	
		
			
				|  |  | +		nr = 1;
 | 
	
		
			
				|  |  | +	q->nr_congestion_off = nr;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * blk_get_backing_dev_info - get the address of a queue's backing_dev_info
 | 
	
		
			
				|  |  | + * @bdev:	device
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Locates the passed device's request queue and returns the address of its
 | 
	
		
			
				|  |  | + * backing_dev_info
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Will return NULL if the request queue cannot be located.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct backing_dev_info *ret = NULL;
 | 
	
		
			
				|  |  | +	struct request_queue *q = bdev_get_queue(bdev);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (q)
 | 
	
		
			
				|  |  | +		ret = &q->backing_dev_info;
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +EXPORT_SYMBOL(blk_get_backing_dev_info);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void blk_rq_init(struct request_queue *q, struct request *rq)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	memset(rq, 0, sizeof(*rq));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	INIT_LIST_HEAD(&rq->queuelist);
 | 
	
		
			
				|  |  | +	INIT_LIST_HEAD(&rq->timeout_list);
 | 
	
		
			
				|  |  | +	rq->cpu = -1;
 | 
	
		
			
				|  |  | +	rq->q = q;
 | 
	
		
			
				|  |  | +	rq->__sector = (sector_t) -1;
 | 
	
		
			
				|  |  | +	INIT_HLIST_NODE(&rq->hash);
 | 
	
		
			
				|  |  | +	RB_CLEAR_NODE(&rq->rb_node);
 | 
	
		
			
				|  |  | +	rq->cmd = rq->__cmd;
 | 
	
		
			
				|  |  | +	rq->cmd_len = BLK_MAX_CDB;
 | 
	
		
			
				|  |  | +	rq->tag = -1;
 | 
	
		
			
				|  |  | +	rq->ref_count = 1;
 | 
	
		
			
				|  |  | +	rq->start_time = jiffies;
 | 
	
		
			
				|  |  | +	set_start_time_ns(rq);
 | 
	
		
			
				|  |  | +	rq->part = NULL;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +EXPORT_SYMBOL(blk_rq_init);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void req_bio_endio(struct request *rq, struct bio *bio,
 | 
	
		
			
				|  |  | +			  unsigned int nbytes, int error)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	if (error)
 | 
	
		
			
				|  |  | +		clear_bit(BIO_UPTODATE, &bio->bi_flags);
 | 
	
		
			
				|  |  | +	else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
 | 
	
		
			
				|  |  | +		error = -EIO;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (unlikely(nbytes > bio->bi_size)) {
 | 
	
		
			
				|  |  | +		printk(KERN_ERR "%s: want %u bytes done, %u left\n",
 | 
	
		
			
				|  |  | +		       __func__, nbytes, bio->bi_size);
 | 
	
		
			
				|  |  | +		nbytes = bio->bi_size;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (unlikely(rq->cmd_flags & REQ_QUIET))
 | 
	
		
			
				|  |  | +		set_bit(BIO_QUIET, &bio->bi_flags);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	bio->bi_size -= nbytes;
 | 
	
		
			
				|  |  | +	bio->bi_sector += (nbytes >> 9);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (bio_integrity(bio))
 | 
	
		
			
				|  |  | +		bio_integrity_advance(bio, nbytes);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* don't actually finish bio if it's part of flush sequence */
 | 
	
		
			
				|  |  | +	if (bio->bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
 | 
	
		
			
				|  |  | +		bio_endio(bio, error);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void blk_dump_rq_flags(struct request *rq, char *msg)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int bit;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	printk(KERN_INFO "%s: dev %s: type=%x, flags=%x\n", msg,
 | 
	
		
			
				|  |  | +		rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type,
 | 
	
		
			
				|  |  | +		rq->cmd_flags);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	printk(KERN_INFO "  sector %llu, nr/cnr %u/%u\n",
 | 
	
		
			
				|  |  | +	       (unsigned long long)blk_rq_pos(rq),
 | 
	
		
			
				|  |  | +	       blk_rq_sectors(rq), blk_rq_cur_sectors(rq));
 | 
	
		
			
				|  |  | +	printk(KERN_INFO "  bio %p, biotail %p, buffer %p, len %u\n",
 | 
	
		
			
				|  |  | +	       rq->bio, rq->biotail, rq->buffer, blk_rq_bytes(rq));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
 | 
	
		
			
				|  |  | +		printk(KERN_INFO "  cdb: ");
 | 
	
		
			
				|  |  | +		for (bit = 0; bit < BLK_MAX_CDB; bit++)
 | 
	
		
			
				|  |  | +			printk("%02x ", rq->cmd[bit]);
 | 
	
		
			
				|  |  | +		printk("\n");
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +EXPORT_SYMBOL(blk_dump_rq_flags);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void blk_delay_work(struct work_struct *work)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct request_queue *q;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	q = container_of(work, struct request_queue, delay_work.work);
 | 
	
		
			
				|  |  | +	spin_lock_irq(q->queue_lock);
 | 
	
		
			
				|  |  | +	__blk_run_queue(q);
 | 
	
		
			
				|  |  | +	spin_unlock_irq(q->queue_lock);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * blk_delay_queue - restart queueing after defined interval
 | 
	
		
			
				|  |  | + * @q:		The &struct request_queue in question
 | 
	
		
			
				|  |  | + * @msecs:	Delay in msecs
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Description:
 | 
	
		
			
				|  |  | + *   Sometimes queueing needs to be postponed for a little while, to allow
 | 
	
		
			
				|  |  | + *   resources to come back. This function will make sure that queueing is
 | 
	
		
			
				|  |  | + *   restarted around the specified time. Queue lock must be held.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +void blk_delay_queue(struct request_queue *q, unsigned long msecs)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	if (likely(!blk_queue_dead(q)))
 | 
	
		
			
				|  |  | +		queue_delayed_work(kblockd_workqueue, &q->delay_work,
 | 
	
		
			
				|  |  | +				   msecs_to_jiffies(msecs));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +EXPORT_SYMBOL(blk_delay_queue);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * blk_start_queue - restart a previously stopped queue
 | 
	
		
			
				|  |  | + * @q:    The &struct request_queue in question
 |