|
|
| version 1.14, 2004/05/13 23:49:26 | version 1.15, 2004/05/19 22:53:04 |
|---|---|
| Line 49 | Line 49 |
| #include <sys/vnode.h> | #include <sys/vnode.h> |
| #include <sys/malloc.h> | #include <sys/malloc.h> |
| #include <sys/linker.h> | #include <sys/linker.h> |
| #include <sys/fcntl.h> | |
| #include <sys/buf2.h> | #include <sys/buf2.h> |
| Line 65 | Line 66 |
| MALLOC_DEFINE(M_MFSNODE, "MFS node", "MFS vnode private part"); | MALLOC_DEFINE(M_MFSNODE, "MFS node", "MFS vnode private part"); |
| static int mfs_minor; /* used for building internal dev_t */ | |
| extern vop_t **mfs_vnodeop_p; | extern vop_t **mfs_vnodeop_p; |
| static int mfs_mount (struct mount *mp, | static int mfs_mount (struct mount *mp, |
| Line 77 static int mfs_statfs (struct mount *mp, | Line 76 static int mfs_statfs (struct mount *mp, |
| struct thread *td); | struct thread *td); |
| static int mfs_init (struct vfsconf *); | static int mfs_init (struct vfsconf *); |
| d_open_t mfsopen; | |
| d_close_t mfsclose; | |
| d_strategy_t mfsstrategy; | |
| #define MFS_CDEV_MAJOR 253 | #define MFS_CDEV_MAJOR 253 |
| static struct cdevsw mfs_cdevsw = { | static struct cdevsw mfs_cdevsw = { |
| Line 86 static struct cdevsw mfs_cdevsw = { | Line 89 static struct cdevsw mfs_cdevsw = { |
| /* port */ NULL, | /* port */ NULL, |
| /* clone */ NULL, | /* clone */ NULL, |
| /* open */ noopen, | /* open */ mfsopen, |
| /* close */ noclose, | /* close */ mfsclose, |
| /* read */ physread, | /* read */ physread, |
| /* write */ physwrite, | /* write */ physwrite, |
| /* ioctl */ noioctl, | /* ioctl */ noioctl, |
| /* poll */ nopoll, | /* poll */ nopoll, |
| /* mmap */ nommap, | /* mmap */ nommap, |
| /* strategy */ nostrategy, | /* strategy */ mfsstrategy, |
| /* dump */ nodump, | /* dump */ nodump, |
| /* psize */ nopsize | /* psize */ nopsize |
| }; | }; |
| Line 120 static struct vfsops mfs_vfsops = { | Line 123 static struct vfsops mfs_vfsops = { |
| VFS_SET(mfs_vfsops, mfs, 0); | VFS_SET(mfs_vfsops, mfs, 0); |
| /* | |
| * We allow the underlying MFS block device to be opened and read. | |
| */ | |
| int | |
| mfsopen(dev_t dev, int flags, int mode, struct thread *td) | |
| { | |
| if (flags & FWRITE) | |
| return(EROFS); | |
| if (dev->si_drv1) | |
| return(0); | |
| return(ENXIO); | |
| } | |
| int | |
| mfsclose(dev_t dev, int flags, int mode, struct thread *td) | |
| { | |
| return(0); | |
| } | |
| void | |
| mfsstrategy(struct buf *bp) | |
| { | |
| struct mfsnode *mfsp; | |
| if ((mfsp = bp->b_dev->si_drv1) != NULL) { | |
| off_t boff = (off_t)bp->b_blkno << DEV_BSHIFT; | |
| off_t eoff = boff + bp->b_bcount; | |
| if (eoff <= mfsp->mfs_size) { | |
| bufq_insert_tail(&mfsp->buf_queue, bp); | |
| wakeup((caddr_t)mfsp); | |
| } else if (boff < mfsp->mfs_size) { | |
| bp->b_bcount = mfsp->mfs_size - boff; | |
| bufq_insert_tail(&mfsp->buf_queue, bp); | |
| wakeup((caddr_t)mfsp); | |
| } else if (boff == mfsp->mfs_size) { | |
| bp->b_resid = bp->b_bcount; | |
| biodone(bp); | |
| } else { | |
| bp->b_error = EINVAL; | |
| biodone(bp); | |
| } | |
| } else { | |
| bp->b_error = ENXIO; | |
| bp->b_flags |= B_ERROR; | |
| biodone(bp); | |
| } | |
| } | |
| /* | /* |
| * mfs_mount | * mfs_mount |
| Line 170 mfs_mount(struct mount *mp, char *path, | Line 221 mfs_mount(struct mount *mp, char *path, |
| struct mfsnode *mfsp; | struct mfsnode *mfsp; |
| size_t size; | size_t size; |
| int flags, err; | int flags, err; |
| int minnum; | |
| dev_t dev; | dev_t dev; |
| /* | /* |
| Line 243 mfs_mount(struct mount *mp, char *path, | Line 295 mfs_mount(struct mount *mp, char *path, |
| FREE(mfsp, M_MFSNODE); | FREE(mfsp, M_MFSNODE); |
| goto error_1; | goto error_1; |
| } | } |
| minnum = (curproc->p_pid & 0xFF) | | |
| ((curproc->p_pid & ~0xFF) << 8); | |
| devvp->v_type = VCHR; | devvp->v_type = VCHR; |
| dev = make_dev(&mfs_cdevsw, mfs_minor, 0, 0, 0, "MFS%d", mfs_minor); | dev = make_dev(&mfs_cdevsw, minnum, UID_ROOT, GID_WHEEL, 0600, |
| "MFS%d", minnum >> 16); | |
| /* It is not clear that these will get initialized otherwise */ | /* It is not clear that these will get initialized otherwise */ |
| dev->si_bsize_phys = DEV_BSIZE; | dev->si_bsize_phys = DEV_BSIZE; |
| dev->si_iosize_max = DFLTPHYS; | dev->si_iosize_max = DFLTPHYS; |
| addaliasu(devvp, makeudev(253, mfs_minor++)); | dev->si_drv1 = mfsp; |
| addaliasu(devvp, makeudev(MFS_CDEV_MAJOR, minnum)); | |
| devvp->v_data = mfsp; | devvp->v_data = mfsp; |
| mfsp->mfs_baseoff = args.base; | mfsp->mfs_baseoff = args.base; |
| mfsp->mfs_size = args.size; | mfsp->mfs_size = args.size; |
| mfsp->mfs_vnode = devvp; | mfsp->mfs_vnode = devvp; |
| mfsp->mfs_dev = reference_dev(dev); | |
| mfsp->mfs_td = td; | mfsp->mfs_td = td; |
| mfsp->mfs_active = 1; | mfsp->mfs_active = 1; |
| bufq_init(&mfsp->buf_queue); | bufq_init(&mfsp->buf_queue); |
| Line 365 mfs_start(struct mount *mp, int flags, s | Line 424 mfs_start(struct mount *mp, int flags, s |
| SIGDELSET(td->td_proc->p_siglist, sig); | SIGDELSET(td->td_proc->p_siglist, sig); |
| } | } |
| } | } |
| else if (tsleep((caddr_t)vp, PCATCH, "mfsidl", 0)) | else if (tsleep((caddr_t)mfsp, PCATCH, "mfsidl", 0)) |
| gotsig++; /* try to unmount in next pass */ | gotsig++; /* try to unmount in next pass */ |
| } | } |
| PRELE(curproc); | PRELE(curproc); |
| v_release_rdev(vp); /* hack because we do not implement CLOSE */ | |
| /* XXX destroy/release devvp */ | |
| return (0); | return (0); |
| } | } |
| Line 391 mfs_statfs(struct mount *mp, struct stat | Line 452 mfs_statfs(struct mount *mp, struct stat |
| static int | static int |
| mfs_init(struct vfsconf *vfsp) | mfs_init(struct vfsconf *vfsp) |
| { | { |
| cdevsw_add(&mfs_cdevsw); | cdevsw_add(&mfs_cdevsw, 0, 0); |
| return (0); | return (0); |
| } | } |