📄 cache.c
字号:
21202 } else {
21203 bit = (bit_t) z - (sp->s_firstdatazone - 1);
21204 }
21205 b = alloc_bit(sp, ZMAP, bit);
21206 if (b == NO_BIT) {
21207 err_code = ENOSPC;
21208 major = (int) (sp->s_dev >> MAJOR) & BYTE;
21209 minor = (int) (sp->s_dev >> MINOR) & BYTE;
21210 printf("No space on %sdevice %d/%d\n",
21211 sp->s_dev == ROOT_DEV ? "root " : "", major, minor);
21212 return(NO_ZONE);
21213 }
21214 if (z == sp->s_firstdatazone) sp->s_zsearch = b; /* for next time */
21215 return(sp->s_firstdatazone - 1 + (zone_t) b);
21216 }
21219 /*===========================================================================*
21220 * free_zone *
21221 *===========================================================================*/
21222 PUBLIC void free_zone(dev, numb)
21223 dev_t dev; /* device where zone located */
21224 zone_t numb; /* zone to be returned */
21225 {
21226 /* Return a zone. */
21227
21228 register struct super_block *sp;
21229 bit_t bit;
21230
21231 /* Locate the appropriate super_block and return bit. */
21232 sp = get_super(dev);
21233 if (numb < sp->s_firstdatazone || numb >= sp->s_zones) return;
21234 bit = (bit_t) (numb - (sp->s_firstdatazone - 1));
21235 free_bit(sp, ZMAP, bit);
21236 if (bit < sp->s_zsearch) sp->s_zsearch = bit;
21237 }
21240 /*===========================================================================*
21241 * rw_block *
21242 *===========================================================================*/
21243 PUBLIC void rw_block(bp, rw_flag)
21244 register struct buf *bp; /* buffer pointer */
21245 int rw_flag; /* READING or WRITING */
21246 {
21247 /* Read or write a disk block. This is the only routine in which actual disk
21248 * I/O is invoked. If an error occurs, a message is printed here, but the error
21249 * is not reported to the caller. If the error occurred while purging a block
21250 * from the cache, it is not clear what the caller could do about it anyway.
21251 */
21252
21253 int r, op;
21254 off_t pos;
21255 dev_t dev;
21256
21257 if ( (dev = bp->b_dev) != NO_DEV) {
21258 pos = (off_t) bp->b_blocknr * BLOCK_SIZE;
21259 op = (rw_flag == READING ? DEV_READ : DEV_WRITE);
21260 r = dev_io(op, FALSE, dev, pos, BLOCK_SIZE, FS_PROC_NR, bp->b_data);
21261 if (r != BLOCK_SIZE) {
21262 if (r >= 0) r = END_OF_FILE;
21263 if (r != END_OF_FILE)
21264 printf("Unrecoverable disk error on device %d/%d, block %ld\n",
21265 (dev>>MAJOR)&BYTE, (dev>>MINOR)&BYTE, bp->b_blocknr);
21266 bp->b_dev = NO_DEV; /* invalidate block */
21267
21268 /* Report read errors to interested parties. */
21269 if (rw_flag == READING) rdwt_err = r;
21270 }
21271 }
21272
21273 bp->b_dirt = CLEAN;
21274 }
21277 /*===========================================================================*
21278 * invalidate *
21279 *===========================================================================*/
21280 PUBLIC void invalidate(device)
21281 dev_t device; /* device whose blocks are to be purged */
21282 {
21283 /* Remove all the blocks belonging to some device from the cache. */
21284
21285 register struct buf *bp;
21286
21287 for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++)
21288 if (bp->b_dev == device) bp->b_dev = NO_DEV;
21289 }
21292 /*==========================================================================*
21293 * flushall *
21294 *==========================================================================*/
21295 PUBLIC void flushall(dev)
21296 dev_t dev; /* device to flush */
21297 {
21298 /* Flush all dirty blocks for one device. */
21299
21300 register struct buf *bp;
21301 static struct buf *dirty[NR_BUFS]; /* static so it isn't on stack */
21302 int ndirty;
21303
21304 for (bp = &buf[0], ndirty = 0; bp < &buf[NR_BUFS]; bp++)
21305 if (bp->b_dirt == DIRTY && bp->b_dev == dev) dirty[ndirty++] = bp;
21306 rw_scattered(dev, dirty, ndirty, WRITING);
21307 }
21310 /*===========================================================================*
21311 * rw_scattered *
21312 *===========================================================================*/
21313 PUBLIC void rw_scattered(dev, bufq, bufqsize, rw_flag)
21314 dev_t dev; /* major-minor device number */
21315 struct buf **bufq; /* pointer to array of buffers */
21316 int bufqsize; /* number of buffers */
21317 int rw_flag; /* READING or WRITING */
21318 {
21319 /* Read or write scattered data from a device. */
21320
21321 register struct buf *bp;
21322 int gap;
21323 register int i;
21324 register struct iorequest_s *iop;
21325 static struct iorequest_s iovec[NR_IOREQS]; /* static so it isn't on stack */
21326 int j;
21327
21328 /* (Shell) sort buffers on b_blocknr. */
21329 gap = 1;
21330 do
21331 gap = 3 * gap + 1;
21332 while (gap <= bufqsize);
21333 while (gap != 1) {
21334 gap /= 3;
21335 for (j = gap; j < bufqsize; j++) {
21336 for (i = j - gap;
21337 i >= 0 && bufq[i]->b_blocknr > bufq[i + gap]->b_blocknr;
21338 i -= gap) {
21339 bp = bufq[i];
21340 bufq[i] = bufq[i + gap];
21341 bufq[i + gap] = bp;
21342 }
21343 }
21344 }
21345
21346 /* Set up i/o vector and do i/o. The result of dev_io is discarded because
21347 * all results are returned in the vector. If dev_io fails completely, the
21348 * vector is unchanged and all results are taken as errors.
21349 */
21350 while (bufqsize > 0) {
21351 for (j = 0, iop = iovec; j < NR_IOREQS && j < bufqsize; j++, iop++) {
21352 bp = bufq[j];
21353 iop->io_position = (off_t) bp->b_blocknr * BLOCK_SIZE;
21354 iop->io_buf = bp->b_data;
21355 iop->io_nbytes = BLOCK_SIZE;
21356 iop->io_request = rw_flag == WRITING ?
21357 DEV_WRITE : DEV_READ | OPTIONAL_IO;
21358 }
21359 (void) dev_io(SCATTERED_IO, 0, dev, (off_t) 0, j, FS_PROC_NR,
21360 (char *) iovec);
21361
21362 /* Harvest the results. Leave read errors for rw_block() to complain. */
21363 for (i = 0, iop = iovec; i < j; i++, iop++) {
21364 bp = bufq[i];
21365 if (rw_flag == READING) {
21366 if (iop->io_nbytes == 0)
21367 bp->b_dev = dev; /* validate block */
21368 put_block(bp, PARTIAL_DATA_BLOCK);
21369 } else {
21370 if (iop->io_nbytes != 0) {
21371 printf("Unrecoverable write error on device %d/%d, block %ld\n",
21372 (dev>>MAJOR)&BYTE, (dev>>MINOR)&BYTE, bp->b_blocknr);
21373 bp->b_dev = NO_DEV; /* invalidate block */
21374 }
21375 bp->b_dirt = CLEAN;
21376 }
21377 }
21378 bufq += j;
21379 bufqsize -= j;
21380 }
21381 }
21384 /*===========================================================================*
21385 * rm_lru *
21386 *===========================================================================*/
21387 PRIVATE void rm_lru(bp)
21388 struct buf *bp;
21389 {
21390 /* Remove a block from its LRU chain. */
21391
21392 struct buf *next_ptr, *prev_ptr;
21393
21394 bufs_in_use++;
21395 next_ptr = bp->b_next; /* successor on LRU chain */
21396 prev_ptr = bp->b_prev; /* predecessor on LRU chain */
21397 if (prev_ptr != NIL_BUF)
21398 prev_ptr->b_next = next_ptr;
21399 else
21400 front = next_ptr; /* this block was at front of chain */
21401
21402 if (next_ptr != NIL_BUF)
21403 next_ptr->b_prev = prev_ptr;
21404 else
21405 rear = prev_ptr; /* this block was at rear of chain */
21406 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -