diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1997-10-06 20:23:17 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1997-10-06 20:23:17 +0000 |
commit | 85674180ac0b414993bec634994ea51b28390306 (patch) | |
tree | 5ce384dfed739e368b8605fc6db4ed1f26a43609 /sys/ufs/ffs/ffs_vfsops.c | |
parent | 44f83f3e77b70fbce9f014e39cf5c97bae700213 (diff) |
back out vfs lite2 till after 2.2
Diffstat (limited to 'sys/ufs/ffs/ffs_vfsops.c')
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 298 |
1 files changed, 91 insertions, 207 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 7b5f8b2463a..7d85820a10d 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ffs_vfsops.c,v 1.10 1997/10/06 15:26:31 csapuntz Exp $ */ +/* $OpenBSD: ffs_vfsops.c,v 1.11 1997/10/06 20:21:37 deraadt Exp $ */ /* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */ /* @@ -51,7 +51,6 @@ #include <sys/ioctl.h> #include <sys/errno.h> #include <sys/malloc.h> -#include <sys/sysctl.h> #include <dev/rndvar.h> @@ -69,6 +68,7 @@ int ffs_sbupdate __P((struct ufsmount *, int)); struct vfsops ffs_vfsops = { + MOUNT_FFS, ffs_mount, ufs_start, ffs_unmount, @@ -80,53 +80,61 @@ struct vfsops ffs_vfsops = { ffs_fhtovp, ffs_vptofh, ffs_init, - ffs_sysctl }; extern u_long nextgennumber; /* * Called by main() when ufs is going to be mounted as root. + * + * Name is updated by mount(8) after booting. */ +#define ROOTNAME "root_device" int ffs_mountroot() { extern struct vnode *rootvp; - struct fs *fs; - struct mount *mp; + register struct fs *fs; + register struct mount *mp; struct proc *p = curproc; /* XXX */ struct ufsmount *ump; + size_t size; int error; /* * Get vnodes for swapdev and rootdev. */ - if ((error = bdevvp(swapdev, &swapdev_vp)) || - (error = bdevvp(rootdev, &rootvp))) { - printf("ffs_mountroot: can't setup bdevvp's"); + if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) + panic("ffs_mountroot: can't setup bdevvp's"); + + mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); + bzero((char *)mp, (u_long)sizeof(struct mount)); + mp->mnt_op = &ffs_vfsops; + mp->mnt_flag = MNT_RDONLY; + if ((error = ffs_mountfs(rootvp, mp, p)) != 0) { + free(mp, M_MOUNT); return (error); } - - if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) + if ((error = vfs_lock(mp)) != 0) { + (void)ffs_unmount(mp, 0, p); + free(mp, M_MOUNT); return (error); - if ((error = ffs_mountfs(rootvp, mp, p)) != 0) { - 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); - 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); + mp->mnt_vnodecovered = NULLVP; + ump = VFSTOUFS(mp); + fs = ump->um_fs; + bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); + fs->fs_fsmnt[0] = '/'; + bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN); + (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, + &size); + bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + (void)ffs_statfs(mp, &mp->mnt_stat, p); + vfs_unlock(mp); + inittodr(fs->fs_time); + return (0); } /* @@ -164,6 +172,8 @@ ffs_mount(mp, path, data, ndp, p) flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; + if (vfs_busy(mp)) + return (EBUSY); error = ffs_flushfiles(mp, flags, p); if (error == 0 && ffs_cgupdate(ump, MNT_WAIT) == 0 && @@ -171,6 +181,7 @@ ffs_mount(mp, path, data, ndp, p) fs->fs_clean = FS_ISCLEAN; (void) ffs_sbupdate(ump, MNT_WAIT); } + vfs_unbusy(mp); if (error) return (error); fs->fs_ronly = 1; @@ -187,19 +198,18 @@ ffs_mount(mp, path, data, ndp, p) */ if (p->p_ucred->cr_uid != 0) { devvp = ump->um_devvp; - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(devvp); error = VOP_ACCESS(devvp, VREAD | VWRITE, p->p_ucred, p); if (error) { - VOP_UNLOCK(devvp, 0, p); + VOP_UNLOCK(devvp); return (error); } - VOP_UNLOCK(devvp, 0, p); + VOP_UNLOCK(devvp); } fs->fs_ronly = 0; fs->fs_clean <<= 1; fs->fs_fmod = 1; - (void) ffs_sbupdate(ump, MNT_WAIT); } if (args.fspec == 0) { /* @@ -233,13 +243,13 @@ ffs_mount(mp, path, data, ndp, p) accessmode = VREAD; if ((mp->mnt_flag & MNT_RDONLY) == 0) accessmode |= VWRITE; - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(devvp); error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p); if (error) { vput(devvp); return (error); } - VOP_UNLOCK(devvp, 0, p); + VOP_UNLOCK(devvp); } if ((mp->mnt_flag & MNT_UPDATE) == 0) error = ffs_mountfs(devvp, mp, p); @@ -307,12 +317,8 @@ ffs_reload(mountp, cred, p) * 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) + if (vinvalbuf(devvp, 0, cred, p, 0, 0)) panic("ffs_reload: dirty1"); - /* * Step 2: re-read superblock from disk. */ @@ -369,26 +375,19 @@ ffs_reload(mountp, cred, p) } loop: - simple_lock(&mntvnode_slock); for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { - if (vp->v_mount != mountp) { - simple_unlock(&mntvnode_slock); - goto loop; - } - nvp = vp->v_mntvnodes.le_next; /* * Step 4: invalidate all inactive vnodes. */ - if (vrecycle(vp, &mntvnode_slock, p)) - goto loop; - + if (vp->v_usecount == 0) { + vgone(vp); + continue; + } /* * Step 5: invalidate all cached file data. */ - simple_lock(&vp->v_interlock); - simple_unlock(&mntvnode_slock); - if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) + if (vget(vp, 1)) goto loop; if (vinvalbuf(vp, 0, cred, p, 0, 0)) panic("ffs_reload: dirty2"); @@ -404,12 +403,11 @@ loop: } ip->i_din.ffs_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ip->i_number)); - ip->i_effnlink = ip->i_ffs_nlink; brelse(bp); vput(vp); - simple_lock(&mntvnode_slock); + if (vp->v_mount != mountp) + goto loop; } - simple_unlock(&mntvnode_slock); return (0); } @@ -428,7 +426,8 @@ ffs_mountfs(devvp, mp, p) dev_t dev; struct partinfo dpart; caddr_t base, space; - int error, i, blks, size, ronly; + int blks; + int error, i, size, ronly; int32_t *lp; struct ucred *cred; extern struct vnode *rootvp; @@ -446,10 +445,7 @@ ffs_mountfs(devvp, mp, p) return (error); if (vcount(devvp) > 1 && devvp != rootvp) return (EBUSY); - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); - error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0); - VOP_UNLOCK(devvp, 0, p); - if (error) + if ((error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) != 0) return (error); ronly = (mp->mnt_flag & MNT_RDONLY) != 0; @@ -488,6 +484,10 @@ ffs_mountfs(devvp, mp, p) bp = NULL; fs = ump->um_fs; fs->fs_ronly = ronly; + if (ronly == 0) { + fs->fs_clean <<= 1; + fs->fs_fmod = 1; + } size = fs->fs_cssize; blks = howmany(size, fs->fs_fsize); if (fs->fs_contigsumsize > 0) @@ -520,8 +520,9 @@ ffs_mountfs(devvp, mp, p) if (fs->fs_id[0] != 0 && fs->fs_id[1] != 0) mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1]; else - mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; + mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_FFS); mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; + mp->mnt_flag |= MNT_LOCAL; ump->um_mountp = mp; ump->um_dev = dev; ump->um_devvp = devvp; @@ -530,24 +531,14 @@ ffs_mountfs(devvp, mp, p) ump->um_seqinc = fs->fs_frag; for (i = 0; i < MAXQUOTAS; i++) ump->um_quotas[i] = NULLVP; - devvp->v_specmountpoint = mp; + devvp->v_specflags |= SI_MOUNTEDON; ffs_oldfscompat(fs); ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1; /* XXX */ if (fs->fs_maxfilesize > maxfilesize) /* XXX */ fs->fs_maxfilesize = maxfilesize; /* XXX */ - if (ronly == 0) { - if ((fs->fs_flags & FS_DOSOFTDEP) && - (error = softdep_mount(devvp, mp, fs, cred)) != 0) { - free(base, M_UFSMNT); - goto out; - } - fs->fs_clean = 0; - (void) ffs_sbupdate(ump, MNT_WAIT); - } return (0); out: - devvp->v_specmountpoint = NULL; if (bp) brelse(bp); (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); @@ -604,14 +595,8 @@ ffs_unmount(mp, mntflags, p) flags = 0; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - if (mp->mnt_flag & MNT_SOFTDEP) { - if ((error = softdep_flushfiles(mp, flags, p)) != 0) - return (error); - } else { - if ((error = ffs_flushfiles(mp, flags, p)) != 0) - return (error); - } - + if ((error = ffs_flushfiles(mp, flags, p)) != 0) + return (error); ump = VFSTOUFS(mp); fs = ump->um_fs; if (fs->fs_ronly == 0 && @@ -620,7 +605,7 @@ ffs_unmount(mp, mntflags, p) fs->fs_clean = FS_ISCLEAN; (void) ffs_sbupdate(ump, MNT_WAIT); } - ump->um_devvp->v_specmountpoint = NULL; + ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE, NOCRED, p); vrele(ump->um_devvp); @@ -628,6 +613,7 @@ ffs_unmount(mp, mntflags, p) free(fs, M_UFSMNT); free(ump, M_UFSMNT); mp->mnt_data = (qaddr_t)0; + mp->mnt_flag &= ~MNT_LOCAL; return (error); } @@ -640,9 +626,12 @@ ffs_flushfiles(mp, flags, p) int flags; struct proc *p; { + extern int doforce; register struct ufsmount *ump; int error; + if (!doforce) + flags &= ~FORCECLOSE; ump = VFSTOUFS(mp); #ifdef QUOTA if (mp->mnt_flag & MNT_QUOTA) { @@ -660,17 +649,7 @@ ffs_flushfiles(mp, flags, p) */ } #endif - /* - * Flush all the files. - */ - if ((error = vflush(mp, NULL, flags)) != 0) - return (error); - /* - * Flush filesystem metadata. - */ - vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p); - error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p); - VOP_UNLOCK(ump->um_devvp, 0, p); + error = vflush(mp, NULLVP, flags); return (error); } @@ -705,11 +684,10 @@ ffs_statfs(mp, sbp, p) sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; sbp->f_ffree = fs->fs_cstotal.cs_nifree; if (sbp != &mp->mnt_stat) { - sbp->f_type = mp->mnt_vfc->vfc_typenum; bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); } - strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); return (0); } @@ -727,7 +705,7 @@ ffs_sync(mp, waitfor, cred, p) struct ucred *cred; struct proc *p; { - register struct vnode *vp, *nvp; + register struct vnode *vp; register struct inode *ip; register struct ufsmount *ump = VFSTOUFS(mp); register struct fs *fs; @@ -739,71 +717,49 @@ ffs_sync(mp, waitfor, cred, p) * Consistency check that the superblock * is still in the buffer cache. */ - if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { - printf("fs = %s\n", fs->fs_fsmnt); - panic("update: rofs mod"); + if (fs->fs_fmod != 0) { + if (fs->fs_ronly != 0) { /* XXX */ + printf("fs = %s\n", fs->fs_fsmnt); + panic("update: rofs mod"); + } + fs->fs_fmod = 0; + fs->fs_time = time.tv_sec; + allerror = ffs_cgupdate(ump, waitfor); } /* * Write back each (modified) inode. */ - simple_lock(&mntvnode_slock); loop: for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; - vp = nvp) { + vp = vp->v_mntvnodes.le_next) { /* * If the vnode that we are about to sync is no longer * associated with this mount point, start over. */ if (vp->v_mount != mp) goto loop; - - simple_lock(&vp->v_interlock); - nvp = vp->v_mntvnodes.le_next; - ip = VTOI(vp); - if (vp->v_type == VNON || ((ip->i_flag & - (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && - vp->v_dirtyblkhd.lh_first == NULL) || - waitfor == MNT_LAZY) { - simple_unlock(&vp->v_interlock); + if (VOP_ISLOCKED(vp)) continue; - } - simple_unlock(&mntvnode_slock); - error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p); - if (error) { - simple_lock(&mntvnode_slock); - if (error == ENOENT) - goto loop; + ip = VTOI(vp); + if ((ip->i_flag & + (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && + vp->v_dirtyblkhd.lh_first == NULL) continue; - } + if (vget(vp, 1)) + goto loop; if ((error = VOP_FSYNC(vp, cred, waitfor, p)) != 0) allerror = error; - VOP_UNLOCK(vp, 0, p); - vrele(vp); - simple_lock(&mntvnode_slock); + vput(vp); } - simple_unlock(&mntvnode_slock); /* * Force stale file system control information to be flushed. */ - if (waitfor != MNT_LAZY) { - if (ump->um_mountp->mnt_flag & MNT_SOFTDEP) - waitfor = MNT_NOWAIT; - vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p); - if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0) - allerror = error; - VOP_UNLOCK(ump->um_devvp, 0, p); - } + if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0) + allerror = error; #ifdef QUOTA qsync(mp); #endif - /* - * Write back modified superblock. - */ - - if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0) - allerror = error; - return (allerror); } @@ -840,7 +796,6 @@ ffs_vget(mp, ino, vpp) type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); bzero((caddr_t)ip, sizeof(struct inode)); - lockinit(&ip->i_lock, PINOD, "inode", 0, 0); vp->v_data = ip; ip->i_vnode = vp; ip->i_fs = fs = ump->um_fs; @@ -878,10 +833,6 @@ ffs_vget(mp, ino, vpp) return (error); } ip->i_din.ffs_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino)); - if (DOINGSOFTDEP(vp)) - softdep_load_inodeblock(ip); - else - ip->i_effnlink = ip->i_ffs_nlink; brelse(bp); /* @@ -1014,7 +965,7 @@ ffs_cgupdate(mp, waitfor) struct ufsmount *mp; int waitfor; { - register struct fs *fs = mp->um_fs, *dfs; + register struct fs *fs = mp->um_fs; register struct buf *bp; int blks; caddr_t space; @@ -1036,74 +987,7 @@ ffs_cgupdate(mp, waitfor) else bawrite(bp); } - - /* - * Now write back the superblock itself. If any errors occurred - * up to this point, then fail so that the superblock avoids - * being written out as clean. - */ - if (allerror) - return (allerror); - bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0); - fs->fs_fmod = 0; - fs->fs_time = time.tv_sec; - bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); - /* Restore compatibility to old file systems. XXX */ - dfs = (struct fs *)bp->b_data; /* XXX */ - if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ - dfs->fs_nrpos = -1; /* XXX */ - if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ - int32_t *lp, tmp; /* XXX */ - /* XXX */ - lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ - tmp = lp[4]; /* XXX */ - for (i = 4; i > 0; i--) /* XXX */ - lp[i] = lp[i-1]; /* XXX */ - lp[0] = tmp; /* XXX */ - } /* XXX */ - dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ - if (waitfor != MNT_WAIT) - bawrite(bp); - else if ((error = bwrite(bp)) != 0) + if (!allerror && error) allerror = error; - return (allerror); } - -/* - * fast filesystem related variables. - */ -int -ffs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) - int *name; - u_int namelen; - void *oldp; - size_t *oldlenp; - void *newp; - size_t newlen; - struct proc *p; -{ - extern int doclusterread, doclusterwrite, doreallocblks, doasyncfree; - - /* all sysctl names at this level are terminal */ - if (namelen != 1) - return (ENOTDIR); /* overloaded */ - - switch (name[0]) { - case FFS_CLUSTERREAD: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &doclusterread)); - case FFS_CLUSTERWRITE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &doclusterwrite)); - case FFS_REALLOCBLKS: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &doreallocblks)); - case FFS_ASYNCFREE: - return (sysctl_int(oldp, oldlenp, newp, newlen, &doasyncfree)); - default: - return (EOPNOTSUPP); - } - /* NOTREACHED */ -} - |