X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/e15d6f60716593d49afe7b2dcf4d77a659e3ffa6..b13267a5123f6a14e47d788c4a8a2a8692e2a119:/sys/vfs/mfs/mfs_vfsops.c diff --git a/sys/vfs/mfs/mfs_vfsops.c b/sys/vfs/mfs/mfs_vfsops.c index f17222d796..3f9ec17af4 100644 --- a/sys/vfs/mfs/mfs_vfsops.c +++ b/sys/vfs/mfs/mfs_vfsops.c @@ -32,15 +32,14 @@ * * @(#)mfs_vfsops.c 8.11 (Berkeley) 6/19/95 * $FreeBSD: src/sys/ufs/mfs/mfs_vfsops.c,v 1.81.2.3 2001/07/04 17:35:21 tegge Exp $ - * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.22 2005/06/06 15:09:38 drhodus Exp $ + * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.35 2006/09/10 01:26:41 dillon Exp $ */ -#include "opt_mfs.h" - #include #include #include +#include #include #include #include @@ -51,8 +50,13 @@ #include #include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -67,14 +71,13 @@ MALLOC_DEFINE(M_MFSNODE, "MFS node", "MFS vnode private part"); - -extern struct vop_ops *mfs_vnode_vops; +extern struct vop_ops *mfs_vnode_vops_p; static int mfs_mount (struct mount *mp, - char *path, caddr_t data, struct thread *td); -static int mfs_start (struct mount *mp, int flags, struct thread *td); -static int mfs_statfs (struct mount *mp, struct statfs *sbp, - struct thread *td); + char *path, caddr_t data, struct ucred *td); +static int mfs_start (struct mount *mp, int flags); +static int mfs_statfs (struct mount *mp, struct statfs *sbp, + struct ucred *cred); static int mfs_init (struct vfsconf *); d_open_t mfsopen; @@ -83,43 +86,31 @@ d_strategy_t mfsstrategy; #define MFS_CDEV_MAJOR 253 -static struct cdevsw mfs_cdevsw = { - /* name */ "MFS", - /* maj */ MFS_CDEV_MAJOR, - /* flags */ D_DISK, - /* port */ NULL, - /* clone */ NULL, - - /* open */ mfsopen, - /* close */ mfsclose, - /* read */ physread, - /* write */ physwrite, - /* ioctl */ noioctl, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ mfsstrategy, - /* dump */ nodump, - /* psize */ nopsize +static struct dev_ops mfs_ops = { + { "MFS", MFS_CDEV_MAJOR, D_DISK }, + .d_open = mfsopen, + .d_close = mfsclose, + .d_read = physread, + .d_write = physwrite, + .d_strategy = mfsstrategy, }; /* * mfs vfs operations. */ static struct vfsops mfs_vfsops = { - mfs_mount, - mfs_start, - ffs_unmount, - ufs_root, - ufs_quotactl, - mfs_statfs, - ffs_sync, - ffs_vget, - ffs_fhtovp, - ufs_check_export, - ffs_vptofh, - mfs_init, - vfs_stduninit, - vfs_stdextattrctl, + .vfs_mount = mfs_mount, + .vfs_start = mfs_start, + .vfs_unmount = ffs_unmount, + .vfs_root = ufs_root, + .vfs_quotactl = ufs_quotactl, + .vfs_statfs = mfs_statfs, + .vfs_sync = ffs_sync, + .vfs_vget = ffs_vget, + .vfs_fhtovp = ffs_fhtovp, + .vfs_checkexp = ufs_check_export, + .vfs_vptofh = ffs_vptofh, + .vfs_init = mfs_init }; VFS_SET(mfs_vfsops, mfs, 0); @@ -128,9 +119,11 @@ 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) +mfsopen(struct dev_open_args *ap) { - if (flags & FWRITE) + cdev_t dev = ap->a_head.a_dev; + + if (ap->a_oflags & FWRITE) return(EROFS); if (dev->si_drv1) return(0); @@ -138,39 +131,60 @@ mfsopen(dev_t dev, int flags, int mode, struct thread *td) } int -mfsclose(dev_t dev, int flags, int mode, struct thread *td) +mfsclose(struct dev_close_args *ap) { return(0); } -void -mfsstrategy(struct buf *bp) +int +mfsstrategy(struct dev_strategy_args *ap) { + cdev_t dev = ap->a_head.a_dev; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; + off_t boff = bio->bio_offset; + off_t eoff = boff + bp->b_bcount; 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) { + if ((mfsp = dev->si_drv1) == NULL) { + bp->b_error = ENXIO; + goto error; + } + if (boff < 0) + goto bad; + if (eoff > mfsp->mfs_size) { + if (boff > mfsp->mfs_size || (bp->b_flags & B_BNOCLIP)) + goto bad; + /* + * Return EOF by completing the I/O with 0 bytes transfered. + * Set B_INVAL to indicate that any data in the buffer is not + * valid. + */ + if (boff == mfsp->mfs_size) { bp->b_resid = bp->b_bcount; - biodone(bp); - } else { - bp->b_error = EINVAL; - biodone(bp); + bp->b_flags |= B_INVAL; + goto done; } - } else { - bp->b_error = ENXIO; - bp->b_flags |= B_ERROR; - biodone(bp); + bp->b_bcount = mfsp->mfs_size - boff; } + + /* + * Initiate I/O + */ + bioq_insert_tail(&mfsp->bio_queue, bio); + wakeup((caddr_t)mfsp); + return(0); + + /* + * Failure conditions on bio + */ +bad: + bp->b_error = EINVAL; +error: + bp->b_flags |= B_ERROR | B_INVAL; +done: + biodone(bio); + return(0); } /* @@ -212,7 +226,7 @@ mfsstrategy(struct buf *bp) */ /* ARGSUSED */ static int -mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) +mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) { struct vnode *devvp; struct mfs_args args; @@ -222,7 +236,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) size_t size; int flags, err; int minnum; - dev_t dev; + cdev_t dev; /* * Use NULL path to flag a root mount @@ -264,12 +278,14 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; - err = ffs_flushfiles(mp, flags, td); + err = ffs_flushfiles(mp, flags); if (err) goto error_1; } - if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) + if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { + /* XXX reopen the device vnode read-write */ fs->fs_ronly = 0; + } /* if not updating name...*/ if (args.fspec == 0) { /* @@ -290,7 +306,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) */ MALLOC(mfsp, struct mfsnode *, sizeof *mfsp, M_MFSNODE, M_WAITOK); - err = getspecialvnode(VT_MFS, NULL, &mfs_vnode_vops, &devvp, 0, 0); + err = getspecialvnode(VT_MFS, NULL, &mfs_vnode_vops_p, &devvp, 0, 0); if (err) { FREE(mfsp, M_MFSNODE); goto error_1; @@ -300,7 +316,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) ((curproc->p_pid & ~0xFF) << 8); devvp->v_type = VCHR; - dev = make_dev(&mfs_cdevsw, minnum, UID_ROOT, GID_WHEEL, 0600, + dev = make_dev(&mfs_ops, minnum, UID_ROOT, GID_WHEEL, 0600, "MFS%d", minnum >> 16); /* It is not clear that these will get initialized otherwise */ dev->si_bsize_phys = DEV_BSIZE; @@ -312,9 +328,24 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) mfsp->mfs_size = args.size; mfsp->mfs_vnode = devvp; mfsp->mfs_dev = reference_dev(dev); - mfsp->mfs_td = td; + mfsp->mfs_td = curthread; mfsp->mfs_active = 1; - bufq_init(&mfsp->buf_queue); + bioq_init(&mfsp->bio_queue); + + /* + * Our 'block' device must be backed by a VM object. Theoretically + * we could use the anonymous memory VM object supplied by userland, + * but it would be somewhat of a complex task to deal with it + * that way since it would result in I/O requests which supply + * the VM pages from our own object. + * + * vnode_pager_alloc() is typically called when a VM object is + * being referenced externally. We have to undo the refs for + * the self reference between vnode and object. + */ + vnode_pager_alloc(devvp, args.size, 0, 0); + --devvp->v_usecount; + --devvp->v_object->ref_count; /* Save "mounted from" info for mount point (NULL pad)*/ copyinstr( args.fspec, /* device name*/ @@ -324,7 +355,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); vx_unlock(devvp); - if ((err = ffs_mountfs(devvp, mp, td, M_MFSNODE)) != 0) { + if ((err = ffs_mountfs(devvp, mp, M_MFSNODE)) != 0) { mfsp->mfs_active = 0; goto error_2; } @@ -335,7 +366,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) * * This code is common to root and non-root mounts */ - (void) VFS_STATFS(mp, &mp->mnt_stat, td); + VFS_STATFS(mp, &mp->mnt_stat, cred); goto success; @@ -360,12 +391,14 @@ success: */ /* ARGSUSED */ static int -mfs_start(struct mount *mp, int flags, struct thread *td) +mfs_start(struct mount *mp, int flags) { struct vnode *vp = VFSTOUFS(mp)->um_devvp; struct mfsnode *mfsp = VTOMFS(vp); + struct bio *bio; struct buf *bp; int gotsig = 0, sig; + thread_t td = curthread; /* * We must prevent the system from trying to swap @@ -377,15 +410,17 @@ mfs_start(struct mount *mp, int flags, struct thread *td) KKASSERT(curproc); PHOLD(curproc); - while (mfsp->mfs_active) { + mfsp->mfs_td = td; + while (mfsp->mfs_active) { crit_enter(); - while ((bp = bufq_first(&mfsp->buf_queue)) != NULL) { - bufq_remove(&mfsp->buf_queue, bp); + while ((bio = bioq_first(&mfsp->bio_queue)) != NULL) { + bioq_remove(&mfsp->bio_queue, bio); crit_exit(); - mfs_doio(bp, mfsp); - wakeup((caddr_t)bp); + bp = bio->bio_buf; + mfs_doio(bio, mfsp); + wakeup(bp); crit_enter(); } @@ -404,7 +439,7 @@ mfs_start(struct mount *mp, int flags, struct thread *td) */ if (gotsig) { gotsig = 0; - if (dounmount(mp, 0, td) != 0) { + if (dounmount(mp, 0) != 0) { KKASSERT(td->td_proc); sig = CURSIG(td->td_proc); if (sig) @@ -424,11 +459,11 @@ mfs_start(struct mount *mp, int flags, struct thread *td) * Get file system statistics. */ static int -mfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +mfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) { int error; - error = ffs_statfs(mp, sbp, td); + error = ffs_statfs(mp, sbp, cred); sbp->f_type = mp->mnt_vfc->vfc_typenum; return (error); } @@ -439,6 +474,6 @@ mfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) static int mfs_init(struct vfsconf *vfsp) { - cdevsw_add(&mfs_cdevsw, 0, 0); + dev_ops_add(&mfs_ops, 0, 0); return (0); }