| 发表于:2007-07-17 11:24:385楼 得分:0 |
static int __make_request(request_queue_t * q, int rw, 628 struct buffer_head * bh) 629 { 630 unsigned int sector, count; 631 int max_segments = max_segments; 632 struct request * req, *freereq = null; 633 int rw_ahead, max_sectors, el_ret; 634 struct list_head *head, *insert_here; 635 int latency; 636 elevator_t *elevator = &q-> elevator; 637 638 count = bh-> b_size > > 9; 639 sector = bh-> b_rsector; 640 641 rw_ahead = 0; /* normal case; gets changed below for reada */ 642 switch (rw) { 643 case reada: 644 rw_ahead = 1; 645 rw = read; /* drop into read */ 646 case read: 647 case write: 648 latency = elevator_request_latency(elevator, rw); 649 break; 650 default: 651 bug(); 652 goto end_io; 653 } 654 655 /* we 'd better have a real physical mapping! 656 check this bit only if the buffer was dirty and just locked 657 down by us so at this point flushpage will block and 658 won 't clear the mapped bit under us. */ 659 if (!buffer_mapped(bh)) 660 bug(); 661 662 /* 663 * temporary solution - in 2.5 this will be done by the lowlevel 664 * driver. create a bounce buffer if the buffer data points into 665 * high memory - keep the original buffer otherwise. 666 */ 667 #if config_highmem 668 bh = create_bounce(rw, bh); 669 #endif 670 671 /* look for a free request. */ 672 /* 673 * try to coalesce the new request with old requests 674 */ 675 max_sectors = get_max_sectors(bh-> b_rdev); 676 677 again: 678 req = null; 679 head = &q-> queue_head; 680 /* 681 * now we acquire the request spinlock, we have to be mega careful 682 * not to schedule or do something nonatomic 683 */ 684 spin_lock_irq(&io_request_lock); 685 686 insert_here = head-> prev; 687 if (list_empty(head)) { 688 q-> plug_device_fn(q, bh-> b_rdev); /* is atomic */ 689 goto get_rq; 690 } else if (q-> head_active && !q-> plugged) 691 head = head-> next; 692 693 el_ret = elevator-> elevator_merge_fn(q, &req, head, bh, rw,max_sectors); 694 switch (el_ret) { 695 696 case elevator_back_merge: 697 if (!q-> back_merge_fn(q, req, bh, max_segments)) { 698 insert_here = &req-> queue; 699 break; 700 } 701 elevator-> elevator_merge_cleanup_fn(q, req, count); 702 req-> bhtail-> b_reqnext = bh; 703 req-> bhtail = bh; 704 req-> nr_sectors = req-> hard_nr_sectors += count; 705 blk_started_io(count); 706 drive_stat_acct(req-> rq_dev, req-> cmd, count, 0); 707 attempt_back_merge(q, req, max_sectors, max_segments); 708 goto out; 709 710 case elevator_front_merge: 711 if (!q-> front_merge_fn(q, req, bh, max_segments)) { 712 insert_here = req-> queue.prev; 713 break; 714 } 715 elevator-> elevator_merge_cleanup_fn(q, req, count); 716 bh-> b_reqnext = req-> bh; 717 req-> bh = bh; 718 req-> buffer = bh-> b_data; 719 req-> current_nr_sectors = count; 720 req-> sector = req-> hard_sector = sector; 721 req-> nr_sectors = req-> hard_nr_sectors += count; 722 blk_started_io(count); 723 drive_stat_acct(req-> rq_dev, req-> cmd, count, 0); 724 attempt_front_merge(q, head, req, max_sectors, max_segments); 725 goto out; 726 727 /* 728 * elevator says don 't/can 't merge. get new request 729 */ 730 case elevator_no_merge: 731 /* 732 * use elevator hints as to where to insert the 733 * request. if no hints, just add it to the back 734 * of the queue 735 */ 736 if (req) 737 insert_here = &req-> queue; 738 break; 739 740 default: 741 printk( "elevator returned crap (%d)\n ", el_ret); 742 bug(); 743 } 744 745 /* 746 * grab a free request from the freelist - if that is empty, check 747 * if we are doing read ahead and abort instead of blocking for 748 * a free slot. 749 */ 750 get_rq: 751 if (freereq) { 752 req = freereq; 753 freereq = null; 754 } else if ((req = get_request(q, rw)) == null) { 755 spin_unlock_irq(&io_request_lock); 756 if (rw_ahead) 757 goto end_io; 758 759 freereq = __get_request_wait(q, rw); 760 goto again; 761 } 762 763 /* fill up the request-info, and add it to the queue */ 764 req-> elevator_sequence = latency; 765 req-> cmd = rw; 766 req-> errors = 0; 767 req-> hard_sector = req-> sector = sector; 768 req-> hard_nr_sectors = req-> nr_sectors = count; 769 req-> current_nr_sectors = count; 770 req-> nr_segments = 1; /* always 1 for a new request. */ 771 req-> nr_hw_segments = 1; /* always 1 for a new request. */ 772 req-> buffer = bh-> b_data; 773 req-> waiting = null; 774 req-> bh = bh; 775 req-> bhtail = bh; 776 req-> rq_dev = bh-> b_rdev; 777 blk_started_io(count); 778 add_request(q, req, insert_here); 779 out: 780 if (freereq) 781 blkdev_release_request(freereq); 782 spin_unlock_irq(&io_request_lock); 783 return 0; 784 end_io: 785 bh-> b_end_io(bh, test_bit(bh_uptodate, &bh-> b_state)); 786 return 0; 787 } make_request_fn这个函数实际上是指向__make_request的指针,上面是__make_request的代码,我没有看到里面返回非0的地方,不知道有没有人能解答我的困惑啊。 | | |
|