[ Pobierz całość w formacie PDF ]
.This routine is rather generic, in that it can be usedin a filesystem by substituting the appropriate function infor getblk.This routine is optimized to make maximum use of the variousbuffers and caches.*/do {bhrequest = 0;uptodate = 1;while (blocks) {--blocks;#if 1if((block % blocks_per_cluster) == 0) {for(i=0; i<blocks_per_cluster; i++) cluster_list[i] = block+i;generate_cluster(dev, cluster_list, blocksize);}#endif*bhb = getblk(dev, block++, blocksize);if (*bhb && !buffer_uptodate(*bhb)) {uptodate = 0;bhreq[bhrequest++] = *bhb;}if (++bhb == &buflist[NBUF])bhb = buflist;/* If the block we have on hand is uptodate, go aheadand complete processing.*/if (uptodate)break;if (bhb == bhe)break;}/* Now request them all */if (bhrequest) {ll_rw_block(READ, bhrequest, bhreq);refill_freelist(blocksize);}do { /* Finish off all I/O that has actually completed */if (*bhe) {wait_on_buffer(*bhe);if (!buffer_uptodate(*bhe)) { /* read error? */brelse(*bhe);if (++bhe == &buflist[NBUF])bhe = buflist;left = 0;break;}}if (left < blocksize - offset)chars = left;elsechars = blocksize - offset;filp->f_pos += chars;left -= chars;read += chars;if (*bhe) {copy_to_user(buf,offset+(*bhe)->b_data,chars);brelse(*bhe);buf += chars;} else {while (chars-- > 0)put_user(0,buf++);}offset = 0;if (++bhe == &buflist[NBUF])bhe = buflist;} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));} while (left > 0);/* Release the read-ahead blocks */while (bhe != bhb) {brelse(*bhe);if (++bhe == &buflist[NBUF])bhe = buflist;};if (!read)return -EIO;filp->f_reada = 1;return read;}int block_fsync(struct inode *inode, struct file *filp){return fsync_dev (inode->i_rdev);}
[ Pobierz całość w formacie PDF ]