Date: Sat, 22 Dec 2001 14:32:20 -0800 (PST) From: Lamont Granquist <lamont@scriptkiddie.org> To: Alfred Perlstein <bright@mu.org> Cc: <freebsd-hackers@freebsd.org> Subject: Re: The care and feeding of Vnodes? Message-ID: <20011222142936.I386-100000@coredump.scriptkiddie.org> In-Reply-To: <20011222161225.B48837@elvis.mu.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 22 Dec 2001, Alfred Perlstein wrote: > * Lamont Granquist <lamont@scriptkiddie.org> [011222 16:06] wrote: > > So, yesterday I was playing around with the VFS code and trying to figure > > out how to get a 'stub' of a filesystem that I could mount and unmount. > > To do so I need to implement vfs_root() which requires returning a vnode > > for the root of the filesystem. So, I just called getnewvnode(), passing > > it some 'stubby' vfsops that would just printf() whenever they were > > called. That way I thought I could figure out what was getting done to > > the vnode. I didn't do any other initialization to the vnode. > > > > So, I mounted the filesystem this way, and tried to unmount it and I got a > > couple of vnops further into getting the filesystem to unmount. However, > > a few minutes later my laptop locked up, and upon rebooting I got > > softupdate inconsistencies and filesystem corruption. How did I manage to > > hose my system this badly just playing around with one vnode? And what > > should I do in order to pass back this kind of "fake" root vnode that > > isn't backed up by any actual filestore? > > Most likely your misbehaving VOPs caused corruption of other data. that's a little odd, because the VOPs were just the vfs_default.c ones with printf()s thrown in them > Without source to your failed experiment it will be hard to determine > what the problem is. 'k, here you go: /* lcgfs_vfsops.c */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/vnode.h> #include <sys/mount.h> vop_t **lcgfs_vnodeop_p; /* XXX: needs to go in header file */ static int lcgfs_statfs __P((struct mount *, struct statfs *, struct proc *)); static int lcgfs_mount __P((struct mount *, char *, caddr_t, struct nameidata *, struct proc *)); static int lcgfs_root __P((struct mount *mp, struct vnode **vpp)); static int lcgfs_mount_stub __P((struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, struct proc *p)); static int lcgfs_start_stub __P((struct mount *mp, int flags, struct proc *p)); static int lcgfs_unmount_stub __P((struct mount *mp, int mntflags, struct proc *p)); static int lcgfs_root_stub __P((struct mount *mp, struct vnode **vpp)); static int lcgfs_quotactl_stub __P((struct mount *mp, int cmds, uid_t uid, caddr_t arg, struct proc *p)); static int lcgfs_statfs_stub __P((struct mount *mp, struct statfs *sbp, struct proc *p)); static int lcgfs_sync_stub __P((struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)); static int lcgfs_vget_stub __P((struct mount *mp, ino_t ino, struct vnode **vpp)); static int lcgfs_fhtovp_stub __P((struct mount *mp, struct fid *fhp, struct vnode **vpp)); static int lcgfs_checkexp_stub __P((struct mount *mp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp)); static int lcgfs_vptofh_stub __P((struct vnode *vp, struct fid *fhp)); static int lcgfs_init_stub __P((struct vfsconf *)); static int lcgfs_uninit_stub __P((struct vfsconf *)); static int lcgfs_extattrctl_stub __P((struct mount *mp, int cmd, const char *attrname, caddr_t arg, struct proc *p)); static int lcgfs_statfs(mp, sbp, p) struct mount *mp; struct statfs *sbp; struct proc *p; { sbp->f_bsize = 512; sbp->f_iosize = 512; sbp->f_blocks = 1024; sbp->f_bfree = 512; sbp->f_bavail = 512; sbp->f_files = 11; sbp->f_ffree = 22; 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, (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); } strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } static int lcgfs_mount(mp, path, data, ndp, p) struct mount *mp; char *path; caddr_t data; struct nameidata *ndp; struct proc *p; { size_t size; (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); strcpy(mp->mnt_stat.f_mntfromname, "lcgfs"); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - 5); /* (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); */ (void) lcgfs_statfs(mp, &mp->mnt_stat, p); return(0); } int lcgfs_mount_stub (mp, path, data, ndp, p) struct mount *mp; char *path; caddr_t data; struct nameidata *ndp; struct proc *p; { printf("lcgfs_mount_stub\n"); return (0); } int lcgfs_unmount_stub (mp, mntflags, p) struct mount *mp; int mntflags; struct proc *p; { printf("lcgfs_unmount_stub\n"); return (0); } int lcgfs_root (mp, vpp) struct mount *mp; struct vnode **vpp; { register struct vnode *vp; int error; printf("lcgfs_root\n"); error = getnewvnode(VT_LCGFS, mp, lcgfs_vnodeop_p, &vp); /* following three lines added last night after the crash */ /* vp->v_type == VDIR; vp->v_flag = VROOT; *vpp = vp; */ return(error); } int lcgfs_root_stub (mp, vpp) struct mount *mp; struct vnode **vpp; { printf("lcgfs_root_stub\n"); return (EOPNOTSUPP); } int lcgfs_statfs_stub (mp, sbp, p) struct mount *mp; struct statfs *sbp; struct proc *p; { printf("lcgfs_statfs_stub\n"); return (EOPNOTSUPP); } int lcgfs_vptofh_stub (vp, fhp) struct vnode *vp; struct fid *fhp; { printf("lcgfs_vptofh_stub\n"); return (EOPNOTSUPP); } int lcgfs_start_stub (mp, flags, p) /* start an individual fs */ struct mount *mp; int flags; struct proc *p; { printf("lcgfs_start_stub\n"); return (0); } int lcgfs_quotactl_stub (mp, cmds, uid, arg, p) struct mount *mp; int cmds; uid_t uid; caddr_t arg; struct proc *p; { printf("lcgfs_quotactl_stub\n"); return (EOPNOTSUPP); } int lcgfs_sync_stub (mp, waitfor, cred, p) struct mount *mp; int waitfor; struct ucred *cred; struct proc *p; { printf("lcgfs_sync_stub\n"); return (0); } int lcgfs_vget_stub (mp, ino, vpp) struct mount *mp; ino_t ino; struct vnode **vpp; { printf("lcgfs_vget_stub\n"); return (EOPNOTSUPP); } int lcgfs_fhtovp_stub (mp, fhp, vpp) struct mount *mp; struct fid *fhp; struct vnode **vpp; { printf("lcgfs_fhtovp_stub\n"); return (EOPNOTSUPP); } int lcgfs_checkexp_stub (mp, nam, extflagsp, credanonp) struct mount *mp; struct sockaddr *nam; int *extflagsp; struct ucred **credanonp; { printf("lcgfs_checkexp_stub\n"); return (EOPNOTSUPP); } int lcgfs_init_stub (vfsp) /* initialization of filesystem code */ struct vfsconf *vfsp; { printf("lcgfs_init_stub\n"); return (0); } int lcgfs_uninit_stub (vfsp) struct vfsconf *vfsp; { printf("lcgfs_uninit_stub\n"); return(0); } int lcgfs_extattrctl_stub(mp, cmd, attrname, arg, p) struct mount *mp; int cmd; const char *attrname; caddr_t arg; struct proc *p; { printf("lcgfs_extattrctl_stub\n"); return(EOPNOTSUPP); } static struct vfsops lcgfs_vfsops = { lcgfs_mount, /* mount a particular filesystem */ lcgfs_start_stub, /* optional - use default */ lcgfs_unmount_stub, /* unmount a particular filesystem */ lcgfs_root, /* call vget(ROOTINO) (ufs_root) */ lcgfs_quotactl_stub, /* optional - use default */ lcgfs_statfs, /* return statfs structure */ lcgfs_sync_stub, /* flush buffers to rust */ lcgfs_vget_stub, /* get vnode from inode */ lcgfs_fhtovp_stub, /* get vnode from filehandle */ lcgfs_checkexp_stub, /* optional? - use default */ lcgfs_vptofh_stub, /* get filehandle from vnode */ lcgfs_init_stub, /* optional - boot initialization */ lcgfs_uninit_stub, /* optional - use default */ lcgfs_extattrctl_stub, /* optional - use default */ }; VFS_SET(lcgfs_vfsops, lcg, 0); /* lcgfs_vnops.c */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/vnode.h> static int lcgfs_default_stub __P((struct vop_generic_args *ap)); static int lcgfs_advlock_stub __P((struct vop_generic_args *ap)); static int lcgfs_bwrite_stub __P((struct vop_bwrite_args *ap)); static int lcgfs_close_stub __P((struct vop_generic_args *ap)); static int lcgfs_createvobject_stub __P((struct vop_createvobject_args *ap)); static int lcgfs_destroyvobject_stub __P((struct vop_destroyvobject_args *ap)); static int lcgfs_fsync_stub __P((struct vop_generic_args *ap)); static int lcgfs_getvobject_stub __P((struct vop_getvobject_args *ap)); static int lcgfs_ioctl_stub __P((struct vop_generic_args *ap)); static int lcgfs_islocked_stub __P((struct vop_islocked_args *ap)); static int lcgfs_lease_stub __P((struct vop_generic_args *ap)); static int lcgfs_lock_stub __P((struct vop_lock_args *ap)); static int lcgfs_mmap_stub __P((struct vop_generic_args *ap)); static int lcgfs_open_stub __P((struct vop_generic_args *ap)); static int lcgfs_pathconf_stub __P((struct vop_generic_args *ap)); static int lcgfs_poll_stub __P((struct vop_poll_args *ap)); static int lcgfs_readlink_stub __P((struct vop_generic_args *ap)); static int lcgfs_reallocblks_stub __P((struct vop_generic_args *ap)); static int lcgfs_revoke_stub __P((struct vop_revoke_args *ap)); static int lcgfs_strategy_stub __P((struct vop_strategy_args *ap)); static int lcgfs_unlock_stub __P((struct vop_unlock_args *ap)); static int lcgfs_getacl_stub __P((struct vop_generic_args *ap)); static int lcgfs_setacl_stub __P((struct vop_generic_args *ap)); static int lcgfs_getextattr_stub __P((struct vop_generic_args *ap)); static int lcgfs_setextattr_stub __P((struct vop_generic_args *ap)); static int lcgfs_aclcheck_stub __P((struct vop_generic_args *ap)); int lcgfs_default_stub(struct vop_generic_args *ap) { printf("lcgfs_default_stub\n"); return(EOPNOTSUPP); } int lcgfs_advlock_stub(struct vop_generic_args *ap) { printf("lcgfs_advlock_stub\n"); return(EINVAL); } int lcgfs_bwrite_stub(ap) struct vop_bwrite_args *ap; { printf("lcgfs_bwrite_stub\n"); return (vop_stdbwrite(ap)); } int lcgfs_close_stub(struct vop_generic_args *ap) { printf("lcgfs_close_stub\n"); return(0); } int lcgfs_createvobject_stub(ap) struct vop_createvobject_args /* { struct vnode *vp; struct ucred *cred; struct proc *p; } */ *ap; { printf("lcgfs_createvobject_stub\n"); return(vop_stdcreatevobject(ap)); } int lcgfs_destroyvobject_stub(ap) struct vop_destroyvobject_args /* { struct vnode *vp; } */ *ap; { printf("lcgfs_destroyobject_stub\n"); return(vop_stddestroyvobject(ap)); } int lcgfs_fsync_stub(struct vop_generic_args *ap) { printf("lcgfs_fsync_stub\n"); return(0); } int lcgfs_getvobject_stub(ap) struct vop_getvobject_args /* { struct vnode *vp; struct vm_object **objpp; } */ *ap; { printf("lcgfs_getvobject_stub\n"); return(vop_stdgetvobject(ap)); } int lcgfs_ioctl_stub(struct vop_generic_args *ap) { printf("lcgfs_ioctl_stub\n"); return(ENOTTY); } int lcgfs_islocked_stub(ap) struct vop_islocked_args /* { struct vnode *a_vp; struct proc *a_p; } */ *ap; { printf("lcgfs_islocked_stub\n"); return (0); } int lcgfs_lease_stub(struct vop_generic_args *ap) { printf("lcgfs_fsync_stub\n"); return(0); } int lcgfs_lock_stub(ap) struct vop_lock_args /* { struct vnode *a_vp; int a_flags; struct proc *a_p; } */ *ap; { printf("lcgfs_lock_stub\n"); return(vop_nolock(ap)); } int lcgfs_mmap_stub(struct vop_generic_args *ap) { printf("lcgfs_mmap_stub\n"); return(EINVAL); } int lcgfs_open_stub(struct vop_generic_args *ap) { printf("lcgfs_open_stub\n"); return(0); } int lcgfs_pathconf_stub(struct vop_generic_args *ap) { printf("lcgfs_pathconf_stub\n"); return(EINVAL); } int lcgfs_poll_stub(ap) struct vop_poll_args /* { struct vnode *a_vp; int a_events; struct ucred *a_cred; struct proc *a_p; } */ *ap; { printf("lcgfs_poll_stub\n"); return(vop_nopoll(ap)); } int lcgfs_readlink_stub(struct vop_generic_args *ap) { printf("lcgfs_readlink_stub\n"); return(EINVAL); } int lcgfs_reallocblks_stub(struct vop_generic_args *ap) { printf("lcgfs_reallocblks_stub\n"); return(EOPNOTSUPP); } int lcgfs_revoke_stub(ap) struct vop_revoke_args /* { struct vnode *a_vp; int a_flags; } */ *ap; { printf("lcgfs_revoke_stub\n"); return(vop_revoke(ap)); } int lcgfs_strategy_stub(struct vop_strategy_args *ap) { printf("lcgfs_strategy_stub\n"); return(EOPNOTSUPP); } int lcgfs_unlock_stub(ap) struct vop_unlock_args /* { struct vnode *a_vp; int a_flags; struct proc *a_p; } */ *ap; { printf("lcgfs_unlock_stub\n"); return(vop_nounlock(ap)); } int lcgfs_getacl_stub(struct vop_generic_args *ap) { printf("lcgfs_getacl_stub\n"); return(EOPNOTSUPP); } int lcgfs_setacl_stub(struct vop_generic_args *ap) { printf("lcgfs_setacl_stub\n"); return(EOPNOTSUPP); } int lcgfs_getextattr_stub(struct vop_generic_args *ap) { printf("lcgfs_getextattr_stub\n"); return(EOPNOTSUPP); } int lcgfs_setextattr_stub(struct vop_generic_args *ap) { printf("lcgfs_setextattr_stub\n"); return(EOPNOTSUPP); } int lcgfs_aclcheck_stub(struct vop_generic_args *ap) { printf("lcgfs_aclcheck_stub\n"); return(EOPNOTSUPP); } vop_t **lcgfs_vnodeop_p; static struct vnodeopv_entry_desc lcgfs_vnodeop_entries[] = { { &vop_default_desc, (vop_t *) lcgfs_default_stub }, { &vop_advlock_desc, (vop_t *) lcgfs_advlock_stub }, { &vop_bwrite_desc, (vop_t *) lcgfs_bwrite_stub }, { &vop_close_desc, (vop_t *) lcgfs_close_stub }, { &vop_createvobject_desc, (vop_t *) lcgfs_createvobject_stub }, { &vop_destroyvobject_desc, (vop_t *) lcgfs_destroyvobject_stub }, { &vop_fsync_desc, (vop_t *) lcgfs_fsync_stub }, { &vop_getvobject_desc, (vop_t *) lcgfs_getvobject_stub }, { &vop_ioctl_desc, (vop_t *) lcgfs_ioctl_stub }, { &vop_islocked_desc, (vop_t *) lcgfs_islocked_stub }, { &vop_lease_desc, (vop_t *) lcgfs_lease_stub }, { &vop_lock_desc, (vop_t *) lcgfs_lock_stub }, { &vop_mmap_desc, (vop_t *) lcgfs_mmap_stub }, { &vop_open_desc, (vop_t *) lcgfs_open_stub }, { &vop_pathconf_desc, (vop_t *) lcgfs_pathconf_stub }, { &vop_poll_desc, (vop_t *) lcgfs_poll_stub }, { &vop_readlink_desc, (vop_t *) lcgfs_readlink_stub }, { &vop_reallocblks_desc, (vop_t *) lcgfs_reallocblks_stub }, { &vop_revoke_desc, (vop_t *) lcgfs_revoke_stub }, { &vop_strategy_desc, (vop_t *) lcgfs_strategy_stub }, { &vop_unlock_desc, (vop_t *) lcgfs_unlock_stub }, { &vop_getacl_desc, (vop_t *) lcgfs_getacl_stub }, { &vop_setacl_desc, (vop_t *) lcgfs_setacl_stub }, { &vop_aclcheck_desc, (vop_t *) lcgfs_aclcheck_stub }, { &vop_getextattr_desc, (vop_t *) lcgfs_getextattr_stub }, { &vop_setextattr_desc, (vop_t *) lcgfs_setextattr_stub }, { NULL, NULL } }; static struct vnodeopv_desc lcgfs_vnodeop_opv_desc = { &lcgfs_vnodeop_p, lcgfs_vnodeop_entries }; VNODEOP_SET(lcgfs_vnodeop_opv_desc); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011222142936.I386-100000>