On Sat, 22 Dec 2001, Alfred Perlstein wrote:
> * Lamont Granquist <[EMAIL PROTECTED]> [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 [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message