X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/d2495626ce9c73fd035a85c5a25a457e9e58656b..9e8b5f025e5fe4bd4db2fd214d0b257e246aad36:/usr/src/sys/ufs/lfs/lfs_vfsops.c diff --git a/usr/src/sys/ufs/lfs/lfs_vfsops.c b/usr/src/sys/ufs/lfs/lfs_vfsops.c index b41b7526af..6460727a0c 100644 --- a/usr/src/sys/ufs/lfs/lfs_vfsops.c +++ b/usr/src/sys/ufs/lfs/lfs_vfsops.c @@ -1,10 +1,10 @@ /* - * Copyright (c) 1989, 1991 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1989, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. * * %sccs.include.redist.c% * - * @(#)lfs_vfsops.c 7.89 (Berkeley) %G% + * @(#)lfs_vfsops.c 8.20 (Berkeley) %G% */ #include @@ -42,7 +42,7 @@ struct vfsops lfs_vfsops = { lfs_mount, ufs_start, lfs_unmount, - lfs_root, + ufs_root, ufs_quotactl, lfs_statfs, lfs_sync, @@ -50,12 +50,42 @@ struct vfsops lfs_vfsops = { lfs_fhtovp, lfs_vptofh, lfs_init, + lfs_sysctl, }; -int +/* + * Called by main() when ufs is going to be mounted as root. + */ lfs_mountroot() { - panic("lfs_mountroot"); /* XXX -- implement */ + extern struct vnode *rootvp; + struct fs *fs; + struct mount *mp; + struct proc *p = curproc; /* XXX */ + int error; + + /* + * Get vnodes for swapdev and rootdev. + */ + if ((error = bdevvp(swapdev, &swapdev_vp)) || + (error = bdevvp(rootdev, &rootvp))) { + printf("lfs_mountroot: can't setup bdevvp's"); + return (error); + } + if (error = vfs_rootmountalloc("lfs", "root_device", &mp)) + return (error); + if (error = lfs_mountfs(rootvp, mp, p)) { + mp->mnt_vfc->vfc_refcount--; + vfs_unbusy(mp, p); + free(mp, M_MOUNT); + return (error); + } + simple_lock(&mountlist_slock); + CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); + simple_unlock(&mountlist_slock); + (void)lfs_statfs(mp, &mp->mnt_stat, p); + vfs_unbusy(mp, p); + return (0); } /* @@ -76,43 +106,43 @@ lfs_mount(mp, path, data, ndp, p) register struct lfs *fs; /* LFS */ u_int size; int error; + mode_t accessmode; if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) return (error); /* Until LFS can do NFS right. XXX */ - if (args.exflags & MNT_EXPORTED) + if (args.export.ex_flags & MNT_EXPORTED) return (EINVAL); + /* * If updating, check whether changing from read-only to * read/write; if there is no device name, that's all we do. */ if (mp->mnt_flag & MNT_UPDATE) { ump = VFSTOUFS(mp); -#ifdef NOTLFS /* LFS */ - fs = ump->um_fs; - if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) - fs->fs_ronly = 0; -#else - fs = ump->um_lfs; - if (fs->lfs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) + if (fs->lfs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { + /* + * If upgrade to read-write by non-root, then verify + * that user has necessary permissions on the device. + */ + if (p->p_ucred->cr_uid != 0) { + vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, + p); + if (error = VOP_ACCESS(ump->um_devvp, + VREAD | VWRITE, p->p_ucred, p)) { + VOP_UNLOCK(ump->um_devvp, 0, p); + return (error); + } + VOP_UNLOCK(ump->um_devvp, 0, p); + } fs->lfs_ronly = 0; -#endif + } if (args.fspec == 0) { /* * Process export requests. */ - if (args.exflags & MNT_EXPORTED) { - if (error = ufs_hang_addrlist(mp, &args)) - return (error); - mp->mnt_flag |= MNT_EXPORTED; - } - if (args.exflags & MNT_DELEXPORT) { - ufs_free_addrlist(ump); - mp->mnt_flag &= - ~(MNT_EXPORTED | MNT_DEFEXPORTED); - } - return (0); + return (vfs_export(mp, &ump->um_export, &args.export)); } } /* @@ -131,6 +161,21 @@ lfs_mount(mp, path, data, ndp, p) vrele(devvp); return (ENXIO); } + /* + * If mount by non-root, then verify that user has necessary + * permissions on the device. + */ + if (p->p_ucred->cr_uid != 0) { + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) { + vput(devvp); + return (error); + } + VOP_UNLOCK(devvp, 0, p); + } if ((mp->mnt_flag & MNT_UPDATE) == 0) error = lfs_mountfs(devvp, mp, p); /* LFS */ else { @@ -185,11 +230,13 @@ lfs_mountfs(devvp, mp, p) struct partinfo dpart; dev_t dev; int error, i, ronly, size; + struct ucred *cred; - if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p)) + cred = p ? p->p_ucred : NOCRED; + if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) return (error); - if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) + if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0) size = DEV_BSIZE; else { size = dpart.disklab->d_secsize; @@ -206,7 +253,7 @@ lfs_mountfs(devvp, mp, p) ump = NULL; /* Read in the superblock. */ - if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, NOCRED, &bp)) + if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, cred, &bp)) goto out; error = EINVAL; /* XXX needs translation */ goto out; @@ -215,7 +262,7 @@ lfs_mountfs(devvp, mp, p) /* Allocate the mount structure, copy the superblock into it. */ ump = (struct ufsmount *)malloc(sizeof *ump, M_UFSMNT, M_WAITOK); fs = ump->um_lfs = malloc(sizeof(struct lfs), M_UFSMNT, M_WAITOK); - bcopy(bp->b_un.b_addr, fs, sizeof(struct lfs)); + bcopy(bp->b_data, fs, sizeof(struct lfs)); if (sizeof(struct lfs) < LFS_SBPAD) /* XXX why? */ bp->b_flags |= B_INVAL; brelse(bp); @@ -239,7 +286,8 @@ lfs_mountfs(devvp, mp, p) dev = devvp->v_rdev; mp->mnt_data = (qaddr_t)ump; mp->mnt_stat.f_fsid.val[0] = (long)dev; - mp->mnt_stat.f_fsid.val[1] = MOUNT_LFS; + mp->mnt_stat.f_fsid.val[1] = lfs_mount_type; + mp->mnt_maxsymlinklen = fs->lfs_maxsymlinklen; mp->mnt_flag |= MNT_LOCAL; ump->um_mountp = mp; ump->um_dev = dev; @@ -268,7 +316,7 @@ lfs_mountfs(devvp, mp, p) out: if (bp) brelse(bp); - (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); + (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); if (ump) { free(ump->um_lfs, M_UFSMNT); free(ump, M_UFSMNT); @@ -291,11 +339,8 @@ lfs_unmount(mp, mntflags, p) int i, error, flags, ronly; flags = 0; - if (mntflags & MNT_FORCE) { - if (!doforce || mp == rootfs) - return (EINVAL); + if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - } ump = VFSTOUFS(mp); fs = ump->um_lfs; @@ -320,7 +365,7 @@ lfs_unmount(mp, mntflags, p) fs->lfs_clean = 1; if (error = VFS_SYNC(mp, 1, p->p_ucred, p)) return (error); - if (fs->lfs_ivnode->v_dirtyblkhd.le_next) + if (fs->lfs_ivnode->v_dirtyblkhd.lh_first) panic("lfs_unmount: still dirty blocks on ifile vnode\n"); vrele(fs->lfs_ivnode); vgone(fs->lfs_ivnode); @@ -340,17 +385,23 @@ lfs_statfs(mp, sbp, p) fs = ump->um_lfs; if (fs->lfs_magic != LFS_MAGIC) panic("lfs_statfs: magic"); - sbp->f_type = MOUNT_LFS; - sbp->f_bsize = fs->lfs_bsize; + sbp->f_bsize = fs->lfs_fsize; sbp->f_iosize = fs->lfs_bsize; - sbp->f_blocks = dbtofsb(fs,fs->lfs_dsize); - sbp->f_bfree = dbtofsb(fs, fs->lfs_bfree); - sbp->f_bavail = (fs->lfs_dsize * (100 - fs->lfs_minfree) / 100) - - (fs->lfs_dsize - fs->lfs_bfree); - sbp->f_bavail = dbtofsb(fs, sbp->f_bavail); + sbp->f_blocks = dbtofrags(fs,fs->lfs_dsize); + sbp->f_bfree = dbtofrags(fs, fs->lfs_bfree); + /* + * To compute the available space. Subtract the minimum free + * from the total number of blocks in the file system. Set avail + * to the smaller of this number and fs->lfs_bfree. + */ + sbp->f_bavail = fs->lfs_dsize * (100 - fs->lfs_minfree) / 100; + sbp->f_bavail = + sbp->f_bavail > fs->lfs_bfree ? fs->lfs_bfree : sbp->f_bavail; + sbp->f_bavail = dbtofrags(fs, sbp->f_bavail); sbp->f_files = fs->lfs_nfiles; sbp->f_ffree = sbp->f_bfree * INOPB(fs); if (sbp != &mp->mnt_stat) { + sbp->f_type = mp->mnt_vfc->vfc_typenum; bcopy((caddr_t)mp->mnt_stat.f_mntonname, (caddr_t)&sbp->f_mntonname[0], MNAMELEN); bcopy((caddr_t)mp->mnt_stat.f_mntfromname, @@ -372,7 +423,6 @@ lfs_sync(mp, waitfor, cred, p) struct ucred *cred; struct proc *p; { - extern int syncprt; int error; /* All syncs must be checkpoints until roll-forward is implemented. */ @@ -400,7 +450,7 @@ lfs_vget(mp, ino, vpp) struct ifile *ifp; struct vnode *vp; struct ufsmount *ump; - daddr_t daddr; + ufs_daddr_t daddr; dev_t dev; int error; @@ -448,19 +498,17 @@ lfs_vget(mp, ino, vpp) if (error = bread(ump->um_devvp, daddr, (int)fs->lfs_bsize, NOCRED, &bp)) { /* - * The inode does not contain anything useful, so it - * would be misleading to leave it on its hash chain. - * Iput() will return it to the free list. + * The inode does not contain anything useful, so it would + * be misleading to leave it on its hash chain. With mode + * still zero, it will be unlinked and returned to the free + * list by vput(). */ - ufs_ihashrem(ip); - - /* Unlock and discard unneeded inode. */ vput(vp); brelse(bp); *vpp = NULL; return (error); } - ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino); + ip->i_din = *lfs_ifind(fs, ino, (struct dinode *)bp->b_data); brelse(bp); /* @@ -531,3 +579,17 @@ lfs_vptofh(vp, fhp) ufhp->ufid_gen = ip->i_gen; return (0); } + +/* + * Initialize the filesystem, most work done by ufs_init. + */ +int lfs_mount_type; + +int +lfs_init(vfsp) + struct vfsconf *vfsp; +{ + + lfs_mount_type = vfsp->vfc_typenum; + return (ufs_init(vfsp)); +}