在看linux0.11代码里面的电梯算法的时候,产生了一些疑惑,经过分析解决了,发现网上也有不少讨论,我自己的分析记录下来。
00017 int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
00018 {
00019 int left,chars,nr;
00020 struct buffer_head * bh;
00021
00022 if ((left=count)<=0)
00023 return 0;
00024 while (left) {
00025 if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) {
00026 if (!(bh=bread(inode->i_dev,nr)))
00027 break;
00028 } else
00029 bh = NULL;
00030 nr = filp->f_pos % BLOCK_SIZE;
00031 chars = MIN( BLOCK_SIZE-nr , left );
00032 filp->f_pos += chars;
00033 left -= chars;
00034 if (bh) {
00035 char * p = nr + bh->b_data;
00036 while (chars-->0)
00037 put_fs_byte(*(p++),buf++);
00038 brelse(bh);
00039 } else {
00040 while (chars-->0)
00041 put_fs_byte(0,buf++);
00042 }
00043 }
00044 inode->i_atime = CURRENT_TIME;
00045 return (count-left)?(count-left):-ERROR;
00046 }
00270 struct buffer_head * bread(int dev,int block)
00271 {
00272 struct buffer_head * bh;
00273
00274 if (!(bh=getblk(dev,block)))
00275 panic("bread: getblk returned NULL\n");
00276 if (bh->b_uptodate)
00277 return bh;
00278 ll_rw_block(READ,bh);
00279 wait_on_buffer(bh);
00280 if (bh->b_uptodate)
00281 return bh;
00282 brelse(bh);
00283 return NULL;
00284 }
00145 void ll_rw_block(int rw, struct buffer_head * bh)
00146 {
00147 unsigned int major;
00148
00149 if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||
00150 !(blk_dev[major].request_fn)) {
00151 printk("Trying to read nonexistent block-device\n\r");
00152 return;
00153 }
00154 make_request(major,rw,bh);
00155 }
00088 static void make_request(int major,int rw, struct buffer_head * bh)
00089 {
00090 struct request * req;
00091 int rw_ahead;
00092
00093 /* WRITEA/READA is special case - it is not really needed, so if the */
00094 /* buffer is locked, we just forget about it, else it's a normal read */
00095 if ((rw_ahead = (rw == READA || rw == WRITEA))) {
00096