⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 一个简单的操作系统minix的核心代码
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -