/* * Get file system statistics. */ int mfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) { int error; error = ffs_statfs(mp, sbp, p); strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN); if (sbp != &mp->mnt_stat) bcopy(&mp->mnt_stat.mount_info.mfs_args, &sbp->mount_info.mfs_args, sizeof(struct mfs_args)); return (error); }
/* * Called by main() when ufs is going to be mounted as root. */ ffs_mountroot() { extern struct vnode *rootvp; struct fs *fs; struct mount *mp; struct proc *p = current_proc(); /* XXX */ struct ufsmount *ump; u_int size; int error; /* * Get vnode for rootdev. */ if (error = bdevvp(rootdev, &rootvp)) { printf("ffs_mountroot: can't setup bdevvp"); return (error); } if (error = vfs_rootmountalloc("ufs", "root_device", &mp)) { vrele(rootvp); /* release the reference from bdevvp() */ return (error); } /* Must set the MNT_ROOTFS flag before doing the actual mount */ mp->mnt_flag |= MNT_ROOTFS; /* Set asynchronous flag by default */ mp->mnt_flag |= MNT_ASYNC; if (error = ffs_mountfs(rootvp, mp, p)) { mp->mnt_vfc->vfc_refcount--; if (mp->mnt_kern_flag & MNTK_IO_XINFO) FREE(mp->mnt_xinfo_ptr, M_TEMP); vfs_unbusy(mp, p); vrele(rootvp); /* release the reference from bdevvp() */ FREE_ZONE(mp, sizeof (struct mount), M_MOUNT); return (error); } simple_lock(&mountlist_slock); CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); simple_unlock(&mountlist_slock); ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp, p); inittodr(fs->fs_time); return (0); }
int ffs_mountroot(void) { struct fs *fs; struct mount *mp; struct proc *p = curproc; /* XXX */ struct ufsmount *ump; int error; /* * Get vnodes for swapdev and rootdev. */ swapdev_vp = NULL; if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("ffs_mountroot: can't setup bdevvp's\n"); if (swapdev_vp) vrele(swapdev_vp); return (error); } if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) { vrele(swapdev_vp); vrele(rootvp); return (error); } if ((error = ffs_mountfs(rootvp, mp, p)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT); vrele(swapdev_vp); vrele(rootvp); return (error); } CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr(fs->fs_time); return (0); }
int mfs_mountroot(void) { struct fs *fs; struct mount *mp; struct proc *p = curproc; struct ufsmount *ump; struct mfsnode *mfsp; int error; if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("mfs_mountroot: can't setup bdevvp's"); return (error); } if ((error = vfs_rootmountalloc("mfs", "mfs_root", &mp)) != 0) return (error); mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); rootvp->v_data = mfsp; rootvp->v_op = mfs_vnodeop_p; rootvp->v_tag = VT_MFS; mfsp->mfs_baseoff = mfs_rootbase; mfsp->mfs_size = mfs_rootsize; mfsp->mfs_vnode = rootvp; mfsp->mfs_pid = p->p_pid; mfsp->mfs_buflist = (struct buf *)0; if ((error = ffs_mountfs(rootvp, mp, p)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT); free(mfsp, M_MFSNODE); return (error); } CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr((time_t)0); return (0); }
/* * Reload all incore data for a filesystem (used after running fsck on * the root filesystem and finding things to fix). The filesystem must * be mounted read-only. * * Things to do to update the mount: * 1) invalidate all cached meta-data. * 2) re-read superblock from disk. * 3) re-read summary information from disk. * 4) invalidate all inactive vnodes. * 5) invalidate all cached file data. * 6) re-read inode data for all active vnodes. */ int ffs_reload(struct mount *mountp, struct ucred *cred, struct proc *p) { struct vnode *devvp; caddr_t space; struct fs *fs, *newfs; struct partinfo dpart; int i, blks, size, error; int32_t *lp; struct buf *bp = NULL; struct ffs_reload_args fra; if ((mountp->mnt_flag & MNT_RDONLY) == 0) return (EINVAL); /* * Step 1: invalidate all cached meta-data. */ devvp = VFSTOUFS(mountp)->um_devvp; vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); error = vinvalbuf(devvp, 0, cred, p, 0, 0); VOP_UNLOCK(devvp, 0, p); if (error) panic("ffs_reload: dirty1"); /* * Step 2: re-read superblock from disk. */ if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) size = DEV_BSIZE; else size = dpart.disklab->d_secsize; error = bread(devvp, (daddr_t)(SBOFF / size), SBSIZE, NOCRED, &bp); if (error) { brelse(bp); return (error); } newfs = (struct fs *)bp->b_data; if (ffs_validate(newfs) == 0) { brelse(bp); return (EINVAL); } fs = VFSTOUFS(mountp)->um_fs; /* * Copy pointer fields back into superblock before copying in XXX * new superblock. These should really be in the ufsmount. XXX * Note that important parameters (eg fs_ncg) are unchanged. */ newfs->fs_csp = fs->fs_csp; newfs->fs_maxcluster = fs->fs_maxcluster; newfs->fs_ronly = fs->fs_ronly; bcopy(newfs, fs, (u_int)fs->fs_sbsize); if (fs->fs_sbsize < SBSIZE) bp->b_flags |= B_INVAL; brelse(bp); mountp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; ffs1_compat_read(fs, VFSTOUFS(mountp), SBOFF); ffs_oldfscompat(fs); (void)ffs_statfs(mountp, &mountp->mnt_stat, p); /* * Step 3: re-read summary information from disk. */ blks = howmany(fs->fs_cssize, fs->fs_fsize); space = (caddr_t)fs->fs_csp; 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; error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, NOCRED, &bp); if (error) { brelse(bp); return (error); } bcopy(bp->b_data, space, (u_int)size); space += size; brelse(bp); } if ((fs->fs_flags & FS_DOSOFTDEP)) (void) softdep_mount(devvp, mountp, fs, cred); /* * We no longer know anything about clusters per cylinder group. */ if (fs->fs_contigsumsize > 0) { lp = fs->fs_maxcluster; for (i = 0; i < fs->fs_ncg; i++) *lp++ = fs->fs_contigsumsize; } fra.p = p; fra.cred = cred; fra.fs = fs; fra.devvp = devvp; error = vfs_mount_foreach_vnode(mountp, ffs_reload_vnode, &fra); return (error); }