📄 ufs_mount.c
字号:
} 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 + -