llinux中的塊裝置操作

來源:互聯網
上載者:User

當核心想快裝置發出一個讀寫請求或其他請求時,ll_rw_block就會根據其參數指明的操作命令和資料緩衝塊頭中的裝置號,利用對應請求項的操作函數do_xx_request建立一個塊裝置請求項,並利用電梯演算法將新產生的請求項插入請求項隊列中。

1.

struct request {
 int dev;  /* -1 if no request */
 int cmd;  /* READ or WRITE */
 int errors;
 unsigned long sector;
 unsigned long nr_sectors;
 char * buffer;
 struct task_struct * waiting;
 struct buffer_head * bh;
 struct request * next;
};

struct request request[NR_REQUEST];

2.

struct blk_dev_struct{

 (void *)(request_fn)();

 struct request *current_request;

}

struct blk_dev_struct blk_dev[NR_BLK];

每個塊裝置中當前請求項與請求項數組中該裝置的請求項鏈表共同構成了當前塊裝置的請求隊列。

 

對於一個當前閒置塊裝置,當ll_rw_block為其建立第一個請求項時,會讓當前請求項指標指向剛剛建立的請求項,並立刻調用當前塊裝置的請求項操作函數進行讀寫操作。

 

3.

在end_request()中有:

#define CURRENT(blk_dev[MAJOR_NR]->currnt_request)

#define CURRENT_DEV DEVICE_NR(CURRENT->DEV)
wake_up(&CURRENT->waiting);
wake_up(&wait_for_request);
第1句是把等待該項裝置的進程喚醒,第2句中的wait_for_request是指什麼呢?
趙博在extern struct task_struct * wait_for_request; 說是等待請求的任務結構。在進行塊裝置的I/O操作時,需要使用請求項

struct request request[NR_REAUEST];

因此請求項本身就是一種資源,所以第二句的意識是喚醒那些等待有空閑請求可用的進程等待隊列。

CURRENT->waiting是當前請求項的進程隊列,wait_for_rquest是等待可用請求項的進程等待隊列

 

對於寫請求,請求項指標會指向請求項數組中的2/3處。

 

1.讀寫硬碟出錯時的處理

首先會調用bad_wr_intr函數,該函數會判斷失敗次數是否大於規定的錯誤最大值,如果是則結束當前請求向並喚醒等待該請求向的進程,並且置位對應緩衝區的標誌位,表示緩衝區沒有得到更新。如果出錯的次數大於最大出錯值的一半時,則要求置位硬碟控制器。

static void bad_wr_intr(void)

{

     if(++CURRENT->error >= MAX_ERRORS)

            end_request(0);

     if(CURRENT->error > MAX_ERRORS/2)

            reset = 1;

}

//reset時複位標誌,當讀寫硬碟發生錯誤時會設定這個標誌,並調用相關的複位函數來複位硬碟控制器和硬碟

static int reset = 1;

 

複位硬碟控制器函數

static int reset_controller(void)

{

    unsigned int i;

     oub_p(4,HD_CMD); //向控制器發送複位位元組

     for(i = 0;i<100;i++) {}; //等待一會

     oub_p((hd_info[0].ctl&0x0f), HD_CMD): //發送正常的控制位元組,其中hd_info[0]的資訊是通過BIOS傳進來的在初始化硬碟資訊的時候對各個硬碟資訊數組進行初始化

     if(device_busy)  //等待硬碟就緒,否則提示錯誤資訊

           printk(" hd controller still busy/n");

     if((i = inb_p(HD_ERR))!=1)

           printk("hd controller reset failed!/n");

}

複位硬碟

static void reset_hd(int nr)
{
 reset_controller();
 hd_out(nr,hd_info[nr].sect,hd_info[nr].sect,hd_info[nr].head-1,

                                                    hd_info[nr].cyl,WIN_SPECIFY,&recal_intr);
}

WIN_SPECIFY表示建立硬碟驅動參數,recal_intr是在硬碟中斷處理函數中調用的重新校正處理函數

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.