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

📄 ufs_mount.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		} else {			CALL_TO_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);			(*bdevsw[major(dev)].d_close)(dev,			 ronly ? FREAD : FREAD | FWRITE);			RETURN_FROM_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);			ronly = 1;			CALL_TO_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);			u.u_error = (*bdevsw[major(dev)].d_open)					(dev, ronly ? FREAD : FREAD|FWRITE);			RETURN_FROM_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);			if (u.u_error)				goto done;			u.u_error = EROFS;		}	}	/* get the superblock */	tp = bread(dev, SBLOCK, SBSIZE, (struct gnode *) NULL);	if (tp->b_flags & B_ERROR)		goto ERROR;	fs = tp->b_un.b_fs;	/*	 *	Check the magic number and see 	 *	if we have a valid filesystem.	 */	if (fs->fs_magic != FS_MAGIC ) {		/*001*/ 		u.u_error = EINVAL;		/* also needs translation */		goto ERROR;	}		/* 	 * only root can mount a non-cleaned filesystem and then only	 * forcibly	 */	if ((fs->fs_clean != FS_CLEAN) && !force) {		uprintf("ufs_mount: fs %s not cleaned -- please fsck\n",		devname);		u.u_error = EINVAL;		goto ERROR;	}	bp = geteblk((int)fs->fs_sbsize);	mp->m_bufp = bp;	/* map the superblock into a buffer not connected with a device */	bcopy((caddr_t)tp->b_un.b_addr, (caddr_t)bp->b_un.b_addr,	   (u_int)fs->fs_sbsize);	brelse(tp);	tp = 0;	fs = bp->b_un.b_fs;	if (!root)		bcopy(name, fs->fs_fsmnt, MAXMNTLEN);	else		bcopy("/", fs->fs_fsmnt, sizeof("/"));			fs->fs_ronly = (ronly != 0);			/* need to check writeability of device */	if (ronly == 0)		mp->m_flags |= M_MOD;	blks = howmany(fs->fs_cssize, fs->fs_fsize);	KM_ALLOC(space, caddr_t, fs->fs_cssize, KM_TEMP, KM_CALL);	if (space == 0) { 		u.u_error = ENOMEM;		goto ERROR;	}		/* get the cylinder groups */	for (i = 0; i < blks; i += fs->fs_frag) {		size = fs->fs_bsize;		if (i + fs->fs_frag > blks)			size = (blks - i) * fs->fs_fsize;		tp = bread(dev, fsbtodb(fs, fs->fs_csaddr + i), size, 			   (struct gnode *) NULL);		if (tp->b_flags&B_ERROR) {		        KM_FREE(space, KM_TEMP);			goto ERROR;		}		bcopy((caddr_t)tp->b_un.b_addr, space, (u_int)size);		fs->fs_csp[i / fs->fs_frag] = (struct csum *)space;		space += size;		brelse(tp);		tp = 0;	}		/* gfs has no knowledge of the following parameters, set them here */	mp->m_bsize = fs->fs_bsize;	mp->m_fstype = GT_ULTRIX;		(void) ufs_getfsdata(mp);		/* this gget is very order dependent, do it last */		if ((gp = gget(mp, ROOTINO, 0, NULL)) == NULL) 		panic("ufs_mount: cannot find root inode");	ufs_gunlock(gp);		/* point the mount table toward the root of the filesystem */		mp->m_rootgp = gp;	gp->g_ops = ufs_gnode_ops;	/*	 * once we are mounted, make no presumptions on the cleanliness	 * of the filesystem.	 */		fs->fs_clean = 0;	mp->m_nupdate = FSCLEAN_UPDATES;	if ((!root) && (!ronly))		CHECK_CLEAN_THRESHOLD(fs, 				      devname, 				      (fs->fs_deftimer == 0 ? 1 : fs->fs_deftimer),				      "mounts");	if(!(ronly || root))		ufs_sbupdat(mp, 0);	if (root) {		devname = mp->m_fs_data->fd_devname;		bcopy("/dev/",devname,5);		bcopy(devget.dev_name,&devname[5],strlen(devget.dev_name));		i = strlen(devname);		if(devget.unit_num > 99) {			devname[i++] = '0' + devget.unit_num/100;		}		if(devget.unit_num > 9) {			devname[i++] = '0' + ((devget.unit_num%100)/10);		}		devname[i++] = '0' + devget.unit_num%10;		devname[i++] = 'a' + (devget.category_stat & DEV_DPMASK);		devname[i++] = '\0';		bcopy("/", mp->m_fs_data->fd_path, sizeof("/"));		inittodr(fs->fs_time);	}	/*	 * Set up partition id	 */	devget_to_partid(&devget, (struct ufs_partid *)&mp->m_fs_data->fd_spare[0]);	return (mp);ERROR:	CALL_TO_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);	(*bdevsw[major(dev)].d_close)(dev, ronly ? FREAD : FREAD | FWRITE);	RETURN_FROM_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);	/* something happened and we need to invalidate the buffer cache	 * so that later we may re-use the device	 */	binval(dev, (struct gnode *) 0);done:	return(NULL);}ufs_umount(mp, force)	register struct	mount	*mp;	register int force;{	register struct gnode *gp = mp->m_gnodp;	register struct fs  *fs;	register int stillopen;	dev_t	dev = mp->m_dev;	int saveaffinity;	nchinval(dev); /* flush the name cache */	xumount(dev); /* get rid of the sticky bitted files */	if (!ISREADONLY(mp))		ufs_sbupdat(mp, 0);		/* flush the superblock */	 /* try to flush gnodes */#ifdef QUOTA	stillopen = gflush(dev, mp->m_qinod, mp->m_rootgp);#else	stillopen = gflush(dev, mp->m_rootgp);#endif	 	if (stillopen < 0) {             /* someone has a file open */		return(EBUSY);	}	(void) grele(mp->m_rootgp);#ifdef QUOTA	closedq(mp, 0);	/* there is a nasty piece of baggage with quotas, we must reflush	 * all the gnodes for the device to get rid of the quota gnode	 */		(void) gflush(dev, (struct gnode *) NULL, (struct gnode *) NULL);#endif		/* make the mounted directory accessible again */	gp->g_flag &= ~GMOUNT;	(void) grele(gp);		/* mark the filesystem as clean */	if (!ISREADONLY(mp))		ufs_sbupdat(mp, 1);			/* free the cylinder group stuff */	fs = mp->m_bufp->b_un.b_fs;	KM_FREE((caddr_t)fs->fs_csp[0], KM_TEMP);		if (!stillopen) {		CALL_TO_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);		(*bdevsw[major(dev)].d_close)(dev, !fs->fs_ronly);		RETURN_FROM_NONSMP_DRIVER(bdevsw[major(dev)], saveaffinity);	}	return(NULL);}/* ************************* Disk Layout *********************** *  |-------------|------------|------------|--------------------|--------| *  | Super block | cg blk  #0 | inode blk  | Data blocks        | Alt sb | *  |             |            |            |                    |        | ... *  | cg totals   | cg 0 sum   | ipg inodes | data blk 1 of cg 0 |        | *  |             |            |            | contains cgsum     |        | *  |             |            |            | structures for all |        | *  |             |            |            | cg's in fs.        |        | *  |---------------------------------------------------------------------| * *  ufs_alloc's routines update the cg totals in the super block, and *  the cylinder group summary information in the cg block, and the *  appropriate cg summary structure in the first data block of cg 0. *  However, it only synchronously writes out the cg block, and only *  marks the super block as modified, and does nothing to update the *  information in the data block. What ufs_sbupdat is doing, is *  synchronously writing the super block, and the cgsum information in *  the first data block of cg 0. By this time, the cg block summary info *  is on the disk. UFS uses all three summaries as a consistency check. * *  Since the super block contains the free block maps, inconsistencies *  can occur if a power failure happens, after a cg block is synched *  to disk, and before the super block is written out. I am not sure *  if this can or should be fixed. However, with this in mind, we should *  still make some attempt to keep the cgsum info in each cg, consistent *  with the copy in the data block 1. Currently, this is not guarenteed *  because fs_lock(mp) cannot be held during a bwrite. This is not *  serious, because most cgsum areas are 1K in length. */ufs_sbupdat(mp, flag)	register struct mount *mp;	int flag;{	register struct fs *fs = mp->m_bufp->b_un.b_fs;	register struct buf *bp;	register int blks, i, size;	caddr_t space;		bp = getblk(mp->m_dev, SBLOCK, (int)fs->fs_sbsize,		    (struct gnode *) NULL);	fs_lock(mp);	mp->m_flags &= ~ M_MOD;	fs->fs_time = timepick->tv_sec;	/*	 * Don't set FS_CLEAN byte if file system was force mounted.	 */	fs->fs_clean = (flag == 1 && !(mp->m_fs_data->fd_flags & M_FORCE))	  ? FS_CLEAN : 1;	if (mp->m_rootgp != NULL)		verify_clean_threshold(fs, mp);	/*	 * we use 0 instead of gp because the superblock and such is not	 * really in the buffer cache	 */		bcopy((caddr_t)fs, bp->b_un.b_addr, (u_int)fs->fs_sbsize);	fs_unlock(mp);	bwrite(bp);	blks = howmany(fs->fs_cssize, fs->fs_fsize);	space = (caddr_t)fs->fs_csp[0];	for (i = 0; i < blks; i += fs->fs_frag) {		size = fs->fs_bsize;		if (i + fs->fs_frag > blks)			size = (blks - i) * fs->fs_fsize;		bp = getblk(mp->m_dev, fsbtodb(fs, fs->fs_csaddr + i),			    size, (struct gnode *) NULL);	        fs_lock(mp);		bcopy(space, bp->b_un.b_addr, (u_int)size);		space += size;		fs_unlock(mp);		bwrite(bp);	}}verify_clean_threshold(fs, mp)	register struct fs *fs;	register struct mount *mp;{	u_int sdelta;	u_int edelta;	char *devname = mp->m_fs_data->fd_devname;	sdelta = fs->fs_lastfsck / 86400;	edelta = timepick->tv_sec / 86400;	if (fs->fs_lastfsck) {		if ((sdelta > edelta) || (edelta - sdelta >= 60)) {			fs->fs_cleantimer = 0;			fs->fs_lastfsck = 0;		}	}	if (--mp->m_nupdate <= 1) {		if (!fs->fs_cleantimer || fs->fs_cleantimer-- <= 1)			fs->fs_cleantimer = 0;		mp->m_nupdate = FSCLEAN_UPDATES;	}}

⌨️ 快捷键说明

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