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

📄 super.c

📁 用于motorala 68K系列处理器的小实时多任务操作系统 The OMU Kernel was written to provide a cut-down Unix-like O/S for a
💻 C
字号:
/* * Super-Block processing (free list etc). * S.Hosgood 5.mar.84 * Modded to update free block and inode count, and use byteclr() * T.Barnaby 4.March.1985 */# include	"../include/param.h"# include       "../include/inode.h"# include       "../include/filsys.h"# include       "../include/buf.h"# include       "../include/fblk.h"# include       "../include/dev.h"# include       "../include/ino.h"# include	"../include/signal.h"# include	<errno.h># include	"../include/procs.h"long time();/* * Getfree - removes a free block from a disk, returns its number. *              Block is cleared. */getfree(mdev, min_dev)struct dev *mdev;{	long fb, count;	struct buf *s_buf, *fb_buf;	struct filsys *s_blk;	struct fblk *fb_ptr;	fb = 0;	/* obtain superblock for this volume */	s_buf = getbuf(mdev, min_dev, SUPERB, ALLBUF);	s_buf->b_flags |= B_BUSY;		/* Mark buffer as busy */	s_blk = ( struct filsys * ) s_buf->b_buf;	/* check if any free list */	if (s_blk->s_nfree){		/* free blocks exist */		fb = s_blk->s_free[--s_blk->s_nfree];		/* Checks if block number valid, if not set it to 0 to prevent		 * further use and return 0, only done if not last block on		 * disk.		 */		if((fb < (long)s_blk->s_isize) || (fb > (long)s_blk->s_fsize)){			if(fb || s_blk->s_nfree){				printf("Physblk: Free list up the creek! block %d\n",fb);				s_blk->s_free[++s_blk->s_nfree] = 0;				fb = 0;			}		}		s_buf->b_flags |= WRITE;	}	/* check if we need secondary free block search */	if (fb){		if (s_blk->s_nfree == 0){			/* read in next block in free chain */			fb_buf = getbuf(mdev, min_dev, fb, ALLBUF);			fb_ptr = ( struct fblk * ) fb_buf->b_buf;			s_blk->s_nfree = fb_ptr->df_nfree;			for (count = 0; count < s_blk->s_nfree; count++)				s_blk->s_free[count] = fb_ptr->df_free[count];		}	}	else{		printf("Physblk: No space on filestore %d,%d\n", mdev - &bdevsw[0], min_dev);	}	/* read in and clear free block */	if (fb){		fb_buf = getbuf(mdev, min_dev, fb, ALLBUF);		byteclr(fb_buf->b_buf,BSIZE);		fb_buf->b_flags |= WRITE;		/* Update free block count */		if((--s_blk->s_tfree) < 0) s_blk->s_tfree = 0;		s_buf->b_flags |= WRITE;	}	s_buf->b_flags &= ~B_BUSY;	/* No longer busy */	return fb;}/* * Makefree - makes a block appear on the free-list. */makefree(mdev, min_dev, bno)struct dev *mdev;{	int count;	struct buf *s_buf, *fb_buf;	struct filsys *s_blk;	struct fblk *fb_ptr;	/* obtain superblock for this volume */	s_buf = getbuf(mdev, min_dev, SUPERB, ALLBUF);	s_buf->b_flags |= B_BUSY;		/* Mark buffer as busy */	s_blk = ( struct filsys * ) s_buf->b_buf;	/* check if we need to use a new chain block */	if (s_blk->s_nfree >= NICFREE){		/* get block to be freed, use as chain block */		fb_buf = getbuf(mdev, min_dev, bno, ALLBUF);		fb_ptr = ( struct fblk * ) fb_buf->b_buf;		fb_ptr->df_nfree = s_blk->s_nfree;		for (count = 0; count < s_blk->s_nfree; count++){			fb_ptr->df_free[count] = s_blk->s_free[count];		}		fb_buf->b_flags |= WRITE;		s_blk->s_nfree = 0;	}	/* enter block to be freed into superblock */	s_blk->s_free[s_blk->s_nfree++] = bno;	/* Update free block count */	s_blk->s_tfree++;	s_buf->b_flags |= WRITE;	s_buf->b_flags &= ~B_BUSY;	/* No longer busy */	return;}/* * Lockfree - returns pointer to a locked inode from the free inode list. */struct inode *lockfree(mdev, min_dev)struct dev *mdev;{	int	fi, count;	long	now;	struct	buf *s_buf;	struct	filsys *s_blk;	struct	inode *fi_ptr;	/* obtain superblock for this volume */	s_buf = getbuf(mdev, min_dev, SUPERB, ALLBUF);	s_buf->b_flags |= B_BUSY;		/* Mark buffer as busy */	s_blk = ( struct filsys * ) s_buf->b_buf;	fi_ptr = NULLIPTR;	/* scan down free i-list. */	while (s_blk->s_ninode){		fi = s_blk->s_inode[--s_blk->s_ninode];		s_buf->b_flags |= WRITE;		if (fi_ptr = getiptr(mdev, min_dev, fi)){			if (fi_ptr->i_mode == 0)				/* found a clear inode */				break;			printf("inode %d was busy\n", fi);			freeiptr(fi_ptr);			fi_ptr = NULLIPTR;		}	}	/* if list exhausted, scan for a free inode */	if (! fi_ptr) {		for (fi = 3; fi < ((s_blk->s_isize - 2) * INOPB); fi++) {			if (fi_ptr = getiptr(mdev, min_dev, fi)) {				if (fi_ptr->i_mode == 0){					/* This is clear, Now trys to read					 * in the next INOPB - 1 more inodes					 * into the super-block free-list.					 */					addifree(mdev, min_dev, s_blk, fi);					break;				}				freeiptr(fi_ptr);				fi_ptr = NULLIPTR;			}		}	}	if (fi_ptr) {		/* make mode non-zero to indicate capture */		fi_ptr->i_flag = 0;		fi_ptr->i_mode = 1;		fi_ptr->i_uid = cur_proc->uid;		fi_ptr->i_gid = cur_proc->gid;		/* set create time etc */		now = time(( long * ) 0);		fi_ptr->i_atime = fi_ptr->i_mtime = fi_ptr->i_ctime = now;		for (count = 0; count < 13; count++)			fi_ptr->i_addr[count] = 0;		fi_ptr->i_flag |= ICHG;		fi_ptr->i_size = 0;		s_buf->b_flags |= WRITE;		/* Update free inode count obtain superblock for this volume */		if((--s_blk->s_tinode) < 0) s_blk->s_tinode = 0;		s_buf->b_flags |= WRITE;	}	else{		printf("no inodes on disk %d\n", min_dev);		error(ENOSPC);	}	s_buf->b_flags &= ~B_BUSY;	/* No longer busy */	return fi_ptr;}/* *	Addifree()	Adds the next INOPB -1 from the given inode number *			to the superblock inode free list if they are free. */addifree(mdev, min_dev, s_blk, fi)struct	dev *mdev;int	min_dev;struct	filsys *s_blk;int	fi;{	long	fit;	struct	inode *fi_ptr;	/* This bit doesn't work as any free inodes aquired are subtracted	 * From the total number of free nodes on the disk (Whoops)	 * I shall do this better sometime.......	 */	return;	fit = ((s_blk->s_isize - 2) * INOPB);	/* Last + 1 inode */	if((fi + INOPB) < fit) fit = fi + INOPB;/* Gets last inode to look at */	/* Scans next NIOPB - 1 inodes, if free adds to super-block free list */	for(fi++; fi < fit; fi++){		if(fi_ptr = getiptr(mdev, min_dev, fi)){			freeiptr(fi_ptr);		}	}}/* * Makeifree - enters inode in free inode list. */makeifree(mdev, min_dev, fi)struct dev *mdev;{	struct buf *s_buf;	struct filsys *s_blk;	s_buf = getbuf(mdev, min_dev, SUPERB, ALLBUF);	s_buf->b_flags |= B_BUSY;		/* Mark buffer as busy */	s_blk = ( struct filsys * ) s_buf->b_buf;	if (s_blk->s_ninode < NICINOD){		s_blk->s_inode[s_blk->s_ninode++] = fi;	}	/* Update free inode count */	s_blk->s_tinode++;	s_buf->b_flags |= WRITE;	s_buf->b_flags &= ~B_BUSY;	/* No longer busy */	return;}/* * Set_time - sets system clock from superblock time. */set_time(){	struct buf *s_buf;	struct filsys *s_blk;	/* get root volume superblock */	s_buf = getbuf(&bdevsw[0], 0, SUPERB, ALLBUF);	s_blk = ( struct filsys * ) s_buf->b_buf;	setime(s_blk->s_time);	return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -