Skip site navigation (1)Skip section navigation (2)
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>