diff options
author | iedowse <iedowse@FreeBSD.org> | 2002-05-16 19:08:03 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2002-05-16 19:08:03 +0000 |
commit | 4009aa43de152606c655cf815548d7719f363b62 (patch) | |
tree | 90aeb827be217019fb5a2b0c03ee96df99127d25 /sys/gnu/ext2fs/ext2_vfsops.c | |
parent | 4ed909bc5ca3075a914b3c63bcee97068e0c0fa5 (diff) | |
download | FreeBSD-src-4009aa43de152606c655cf815548d7719f363b62.zip FreeBSD-src-4009aa43de152606c655cf815548d7719f363b62.tar.gz |
Complete the separation of ext2fs from ufs by copying the remaining
shared code and converting all ufs references. Originally it may
have made sense to share common features between the two filesystems,
but recently it has only caused problems, the UFS2 work being the
final straw.
All UFS_* indirect calls are now direct calls to ext2_* functions,
and ext2fs-specific mount and inode structures have been introduced.
Diffstat (limited to 'sys/gnu/ext2fs/ext2_vfsops.c')
-rw-r--r-- | sys/gnu/ext2fs/ext2_vfsops.c | 193 |
1 files changed, 101 insertions, 92 deletions
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c index 54c4305..b9afe91 100644 --- a/sys/gnu/ext2fs/ext2_vfsops.c +++ b/sys/gnu/ext2fs/ext2_vfsops.c @@ -40,8 +40,6 @@ * $FreeBSD$ */ -#include "opt_quota.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/namei.h> @@ -57,12 +55,8 @@ #include <sys/stat.h> #include <sys/mutex.h> -#include <ufs/ufs/extattr.h> -#include <ufs/ufs/quota.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufs_extern.h> - +#include <gnu/ext2fs/ext2_mount.h> +#include <gnu/ext2fs/inode.h> #include <gnu/ext2fs/fs.h> #include <gnu/ext2fs/ext2_extern.h> @@ -71,26 +65,29 @@ static int ext2_fhtovp(struct mount *, struct fid *, struct vnode **); static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td); +static int ext2_init(struct vfsconf *); static int ext2_mount(struct mount *, char *, caddr_t, struct nameidata *, struct thread *); static int ext2_mountfs(struct vnode *, struct mount *, struct thread *); static int ext2_reload(struct mount *mountp, struct ucred *cred, struct thread *td); -static int ext2_sbupdate(struct ufsmount *, int); +static int ext2_root(struct mount *, struct vnode **vpp); +static int ext2_sbupdate(struct ext2mount *, int); static int ext2_statfs(struct mount *, struct statfs *, struct thread *); static int ext2_sync(struct mount *, int, struct ucred *, struct thread *); static int ext2_unmount(struct mount *, int, struct thread *); static int ext2_vget(struct mount *, ino_t, int, struct vnode **); static int ext2_vptofh(struct vnode *, struct fid *); -static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part"); +MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part"); +static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure"); static struct vfsops ext2fs_vfsops = { ext2_mount, - ufs_start, /* empty function */ + vfs_stdstart, ext2_unmount, - ufs_root, /* root inode via vget */ - ufs_quotactl, /* does operations associated with quotas */ + ext2_root, /* root inode via vget */ + vfs_stdquotactl, ext2_statfs, ext2_sync, ext2_vget, @@ -129,7 +126,7 @@ ext2_mountroot() register struct ext2_sb_info *fs; register struct mount *mp; struct thread *td = curthread; - struct ufsmount *ump; + struct ext2mount *ump; u_int size; int error; @@ -155,7 +152,7 @@ ext2_mountroot() TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); mp->mnt_flag |= MNT_ROOTFS; mp->mnt_vnodecovered = NULLVP; - ump = VFSTOUFS(mp); + ump = VFSTOEXT2(mp); fs = ump->um_e2fs; bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); fs->fs_fsmnt[0] = '/'; @@ -180,13 +177,13 @@ static int ext2_mount(mp, path, data, ndp, td) register struct mount *mp; char *path; - caddr_t data; /* this is actually a (struct ufs_args *) */ + caddr_t data; /* this is actually a (struct ext2_args *) */ struct nameidata *ndp; struct thread *td; { struct vnode *devvp; - struct ufs_args args; - struct ufsmount *ump = 0; + struct ext2_args args; + struct ext2mount *ump = 0; register struct ext2_sb_info *fs; size_t size; int error, flags; @@ -195,7 +192,7 @@ ext2_mount(mp, path, data, ndp, td) /* Double-check the length of path.. */ if (strlen(path) >= MAXMNTLEN - 1) return (ENAMETOOLONG); - error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); + error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args)); if (error != 0) return (error); /* @@ -203,7 +200,7 @@ ext2_mount(mp, path, data, ndp, td) * read/write; if there is no device name, that's all we do. */ if (mp->mnt_flag & MNT_UPDATE) { - ump = VFSTOUFS(mp); + ump = VFSTOEXT2(mp); fs = ump->um_e2fs; error = 0; if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) { @@ -310,7 +307,7 @@ ext2_mount(mp, path, data, ndp, td) vrele(devvp); return (error); } - ump = VFSTOUFS(mp); + ump = VFSTOEXT2(mp); fs = ump->um_e2fs; /* * Note that this strncpy() is ok because of a check at the start @@ -466,7 +463,7 @@ static int compute_sb_data(devvp, es, fs) V(s_db_per_group) fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), - M_UFSMNT, M_WAITOK); + M_EXT2MNT, M_WAITOK); /* adjust logic_sb_block */ if(fs->s_blocksize > SBSIZE) @@ -481,7 +478,7 @@ static int compute_sb_data(devvp, es, fs) if(error) { for (j = 0; j < i; j++) brelse(fs->s_group_desc[j]); - bsd_free(fs->s_group_desc, M_UFSMNT); + bsd_free(fs->s_group_desc, M_EXT2MNT); printf("EXT2-fs: unable to read group descriptors (%d)\n", error); return EIO; } @@ -491,7 +488,7 @@ static int compute_sb_data(devvp, es, fs) if(!ext2_check_descriptors(fs)) { for (j = 0; j < db_count; j++) ULCK_BUF(fs->s_group_desc[j]) - bsd_free(fs->s_group_desc, M_UFSMNT); + bsd_free(fs->s_group_desc, M_EXT2MNT); printf("EXT2-fs: (ext2_check_descriptors failure) " "unable to read group descriptors\n"); return EIO; @@ -539,7 +536,7 @@ ext2_reload(mountp, cred, td) /* * Step 1: invalidate all cached meta-data. */ - devvp = VFSTOUFS(mountp)->um_devvp; + devvp = VFSTOEXT2(mountp)->um_devvp; if (vinvalbuf(devvp, 0, cred, td, 0, 0)) panic("ext2_reload: dirty1"); /* @@ -553,7 +550,7 @@ ext2_reload(mountp, cred, td) brelse(bp); return (EIO); /* XXX needs translation */ } - fs = VFSTOUFS(mountp)->um_e2fs; + fs = VFSTOEXT2(mountp)->um_e2fs; bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block)); if((error = compute_sb_data(devvp, es, fs)) != 0) { @@ -600,9 +597,8 @@ loop: vput(vp); return (error); } - ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + - EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), - &ip->i_din); + ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + + EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip); brelse(bp); vput(vp); mtx_lock(&mntvnode_mtx); @@ -620,12 +616,12 @@ ext2_mountfs(devvp, mp, td) struct mount *mp; struct thread *td; { - register struct ufsmount *ump; + register struct ext2mount *ump; struct buf *bp; register struct ext2_sb_info *fs; struct ext2_super_block * es; dev_t dev = devvp->v_rdev; - int error, i; + int error; int ronly; /* @@ -677,22 +673,16 @@ ext2_mountfs(devvp, mp, td) goto out; } } - ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK); + ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK); bzero((caddr_t)ump, sizeof *ump); - ump->um_malloctype = M_EXT2NODE; - ump->um_blkatoff = ext2_blkatoff; - ump->um_truncate = ext2_truncate; - ump->um_update = ext2_update; - ump->um_valloc = ext2_valloc; - ump->um_vfree = ext2_vfree; /* I don't know whether this is the right strategy. Note that we dynamically allocate both a ext2_sb_info and a ext2_super_block while Linux keeps the super block in a locked buffer */ ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), - M_UFSMNT, M_WAITOK); + M_EXT2MNT, M_WAITOK); ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), - M_UFSMNT, M_WAITOK); + M_EXT2MNT, M_WAITOK); bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block)); if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs))) goto out; @@ -720,14 +710,12 @@ ext2_mountfs(devvp, mp, td) ump->um_mountp = mp; ump->um_dev = dev; ump->um_devvp = devvp; - /* setting those two parameters allows us to use + /* setting those two parameters allowed us to use ufs_bmap w/o changse ! */ ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); ump->um_bptrtodb = fs->s_es->s_log_block_size + 1; ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); - for (i = 0; i < MAXQUOTAS; i++) - ump->um_quotas[i] = NULLVP; devvp->v_rdev->si_mountpoint = mp; if (ronly == 0) ext2_sbupdate(ump, MNT_WAIT); @@ -737,9 +725,9 @@ out: brelse(bp); (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, td); if (ump) { - bsd_free(ump->um_e2fs->s_es, M_UFSMNT); - bsd_free(ump->um_e2fs, M_UFSMNT); - bsd_free(ump, M_UFSMNT); + bsd_free(ump->um_e2fs->s_es, M_EXT2MNT); + bsd_free(ump->um_e2fs, M_EXT2MNT); + bsd_free(ump, M_EXT2MNT); mp->mnt_data = (qaddr_t)0; } return (error); @@ -754,7 +742,7 @@ ext2_unmount(mp, mntflags, td) int mntflags; struct thread *td; { - register struct ufsmount *ump; + register struct ext2mount *ump; register struct ext2_sb_info *fs; int error, flags, ronly, i; @@ -766,7 +754,7 @@ ext2_unmount(mp, mntflags, td) } if ((error = ext2_flushfiles(mp, flags, td)) != 0) return (error); - ump = VFSTOUFS(mp); + ump = VFSTOEXT2(mp); fs = ump->um_e2fs; ronly = fs->s_rd_only; if (ronly == 0) { @@ -778,7 +766,7 @@ ext2_unmount(mp, mntflags, td) /* release buffers containing group descriptors */ for(i = 0; i < fs->s_db_per_group; i++) ULCK_BUF(fs->s_group_desc[i]) - bsd_free(fs->s_group_desc, M_UFSMNT); + bsd_free(fs->s_group_desc, M_EXT2MNT); /* release cached inode/block bitmaps */ for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) @@ -793,9 +781,9 @@ ext2_unmount(mp, mntflags, td) error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, td); vrele(ump->um_devvp); - bsd_free(fs->s_es, M_UFSMNT); - bsd_free(fs, M_UFSMNT); - bsd_free(ump, M_UFSMNT); + bsd_free(fs->s_es, M_EXT2MNT); + bsd_free(fs, M_EXT2MNT); + bsd_free(ump, M_EXT2MNT); mp->mnt_data = (qaddr_t)0; mp->mnt_flag &= ~MNT_LOCAL; return (error); @@ -810,28 +798,8 @@ ext2_flushfiles(mp, flags, td) int flags; struct thread *td; { - register struct ufsmount *ump; int error; -#if QUOTA - int i; -#endif - ump = VFSTOUFS(mp); -#if QUOTA - if (mp->mnt_flag & MNT_QUOTA) { - if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0) - return (error); - for (i = 0; i < MAXQUOTAS; i++) { - if (ump->um_quotas[i] == NULLVP) - continue; - quotaoff(td, mp, i); - } - /* - * Here we fall through to vflush again to ensure - * that we have gotten rid of all the system vnodes. - */ - } -#endif error = vflush(mp, 0, flags); return (error); } @@ -847,12 +815,12 @@ ext2_statfs(mp, sbp, td) struct thread *td; { unsigned long overhead; - register struct ufsmount *ump; + register struct ext2mount *ump; register struct ext2_sb_info *fs; register struct ext2_super_block *es; int i, nsb; - ump = VFSTOUFS(mp); + ump = VFSTOEXT2(mp); fs = ump->um_e2fs; es = fs->s_es; @@ -908,7 +876,7 @@ ext2_sync(mp, waitfor, cred, td) { struct vnode *nvp, *vp; struct inode *ip; - struct ufsmount *ump = VFSTOUFS(mp); + struct ext2mount *ump = VFSTOEXT2(mp); struct ext2_sb_info *fs; int error, allerror = 0; @@ -964,9 +932,6 @@ loop: allerror = error; VOP_UNLOCK(ump->um_devvp, 0, td); } -#if QUOTA - qsync(mp); -#endif /* * Write back modified superblock. */ @@ -994,17 +959,17 @@ ext2_vget(mp, ino, flags, vpp) { register struct ext2_sb_info *fs; register struct inode *ip; - struct ufsmount *ump; + struct ext2mount *ump; struct buf *bp; struct vnode *vp; dev_t dev; int i, error; int used_blocks; - ump = VFSTOUFS(mp); + ump = VFSTOEXT2(mp); dev = ump->um_dev; restart: - if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0) + if ((error = ext2_ihashget(dev, ino, flags, vpp)) != 0) return (error); if (*vpp != NULL) return (0); @@ -1048,17 +1013,13 @@ restart: ip->i_e2fs = fs = ump->um_e2fs; ip->i_dev = dev; ip->i_number = ino; -#if QUOTA - for (i = 0; i < MAXQUOTAS; i++) - ip->i_dquot[i] = NODQUOT; -#endif /* * Put it onto its hash chain and lock it so that other requests for * this inode will block if they arrive while we are sleeping waiting * for old data structures to be purged or for the contents of the * disk portion of this inode to be read. */ - ufs_ihashins(ip); + ext2_ihashins(ip); if (ext2fs_inode_hash_lock < 0) wakeup(&ext2fs_inode_hash_lock); @@ -1082,8 +1043,8 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); return (error); } /* convert ext2 inode to dinode */ - ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * - ino_to_fsbo(fs, ino)), &ip->i_din); + ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * + ino_to_fsbo(fs, ino)), ip); ip->i_block_group = ino_to_cg(fs, ino); ip->i_next_alloc_block = 0; ip->i_next_alloc_goal = 0; @@ -1107,7 +1068,7 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); * Initialize the vnode from the inode, check for aliases. * Note that the underlying vnode may have changed. */ - if ((error = ufs_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) { + if ((error = ext2_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) { vput(vp); *vpp = NULL; return (error); @@ -1146,15 +1107,32 @@ ext2_fhtovp(mp, fhp, vpp) struct fid *fhp; struct vnode **vpp; { + struct inode *ip; register struct ufid *ufhp; + struct vnode *nvp; struct ext2_sb_info *fs; + int error; ufhp = (struct ufid *)fhp; - fs = VFSTOUFS(mp)->um_e2fs; + fs = VFSTOEXT2(mp)->um_e2fs; if (ufhp->ufid_ino < ROOTINO || ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group) return (ESTALE); - return (ufs_fhtovp(mp, ufhp, vpp)); + + error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp); + if (error) { + *vpp = NULLVP; + return (error); + } + ip = VTOI(nvp); + if (ip->i_mode == 0 || + ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) { + vput(nvp); + *vpp = NULLVP; + return (ESTALE); + } + *vpp = nvp; + return (0); } /* @@ -1182,7 +1160,7 @@ ext2_vptofh(vp, fhp) */ static int ext2_sbupdate(mp, waitfor) - struct ufsmount *mp; + struct ext2mount *mp; int waitfor; { register struct ext2_sb_info *fs = mp->um_e2fs; @@ -1207,3 +1185,34 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no"); return (error); } + +/* + * Return the root of a filesystem. + */ +static int +ext2_root(mp, vpp) + struct mount *mp; + struct vnode **vpp; +{ + struct vnode *nvp; + int error; + + error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp); + if (error) + return (error); + *vpp = nvp; + return (0); +} + +static int +ext2_init(struct vfsconf *vfsp) +{ + static int done; + + if (done) + return (0); + done = 1; + ext2_ihashinit(); + + return (0); +} |