[BACK]Return to mfs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / ufs / mfs

Annotation of src/sys/ufs/mfs/mfs_vnops.c, Revision 1.55

1.55    ! dholland    1: /*     $NetBSD: mfs_vnops.c,v 1.54 2010/06/24 13:03:19 hannken Exp $   */
1.22      thorpej     2:
1.1       mycroft     3: /*
                      4:  * Copyright (c) 1989, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.34      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       mycroft    16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  *
1.13      fvdl       31:  *     @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95
1.1       mycroft    32:  */
1.28      lukem      33:
                     34: #include <sys/cdefs.h>
1.55    ! dholland   35: __KERNEL_RCSID(0, "$NetBSD: mfs_vnops.c,v 1.54 2010/06/24 13:03:19 hannken Exp $");
1.1       mycroft    36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/time.h>
                     40: #include <sys/kernel.h>
                     41: #include <sys/proc.h>
                     42: #include <sys/buf.h>
1.37      yamt       43: #include <sys/bufq.h>
1.1       mycroft    44: #include <sys/vnode.h>
1.49      ad         45: #include <sys/kmem.h>
1.1       mycroft    46:
1.9       mycroft    47: #include <miscfs/genfs/genfs.h>
1.1       mycroft    48: #include <miscfs/specfs/specdev.h>
                     49:
1.23      thorpej    50: #include <machine/vmparam.h>
                     51:
1.1       mycroft    52: #include <ufs/mfs/mfsnode.h>
                     53: #include <ufs/mfs/mfs_extern.h>
                     54:
                     55: /*
                     56:  * mfs vnode operations.
                     57:  */
1.39      xtraeme    58: int (**mfs_vnodeop_p)(void *);
1.27      jdolecek   59: const struct vnodeopv_entry_desc mfs_vnodeop_entries[] = {
1.1       mycroft    60:        { &vop_default_desc, vn_default_error },
                     61:        { &vop_lookup_desc, mfs_lookup },               /* lookup */
                     62:        { &vop_create_desc, mfs_create },               /* create */
                     63:        { &vop_mknod_desc, mfs_mknod },                 /* mknod */
                     64:        { &vop_open_desc, mfs_open },                   /* open */
                     65:        { &vop_close_desc, mfs_close },                 /* close */
                     66:        { &vop_access_desc, mfs_access },               /* access */
                     67:        { &vop_getattr_desc, mfs_getattr },             /* getattr */
                     68:        { &vop_setattr_desc, mfs_setattr },             /* setattr */
                     69:        { &vop_read_desc, mfs_read },                   /* read */
                     70:        { &vop_write_desc, mfs_write },                 /* write */
1.55    ! dholland   71:        { &vop_fallocate_desc, genfs_eopnotsupp },      /* fallocate */
        !            72:        { &vop_fdiscard_desc, genfs_eopnotsupp },       /* fdiscard */
1.1       mycroft    73:        { &vop_ioctl_desc, mfs_ioctl },                 /* ioctl */
1.10      mycroft    74:        { &vop_poll_desc, mfs_poll },                   /* poll */
1.13      fvdl       75:        { &vop_revoke_desc, mfs_revoke },               /* revoke */
1.1       mycroft    76:        { &vop_mmap_desc, mfs_mmap },                   /* mmap */
1.52      christos   77:        { &vop_fsync_desc, spec_fsync },                /* fsync */
1.1       mycroft    78:        { &vop_seek_desc, mfs_seek },                   /* seek */
                     79:        { &vop_remove_desc, mfs_remove },               /* remove */
                     80:        { &vop_link_desc, mfs_link },                   /* link */
                     81:        { &vop_rename_desc, mfs_rename },               /* rename */
                     82:        { &vop_mkdir_desc, mfs_mkdir },                 /* mkdir */
                     83:        { &vop_rmdir_desc, mfs_rmdir },                 /* rmdir */
                     84:        { &vop_symlink_desc, mfs_symlink },             /* symlink */
                     85:        { &vop_readdir_desc, mfs_readdir },             /* readdir */
                     86:        { &vop_readlink_desc, mfs_readlink },           /* readlink */
                     87:        { &vop_abortop_desc, mfs_abortop },             /* abortop */
                     88:        { &vop_inactive_desc, mfs_inactive },           /* inactive */
                     89:        { &vop_reclaim_desc, mfs_reclaim },             /* reclaim */
1.48      ad         90:        { &vop_lock_desc, genfs_nolock },               /* lock */
                     91:        { &vop_unlock_desc, genfs_nounlock },           /* unlock */
1.1       mycroft    92:        { &vop_bmap_desc, mfs_bmap },                   /* bmap */
                     93:        { &vop_strategy_desc, mfs_strategy },           /* strategy */
                     94:        { &vop_print_desc, mfs_print },                 /* print */
                     95:        { &vop_islocked_desc, mfs_islocked },           /* islocked */
                     96:        { &vop_pathconf_desc, mfs_pathconf },           /* pathconf */
                     97:        { &vop_advlock_desc, mfs_advlock },             /* advlock */
                     98:        { &vop_bwrite_desc, mfs_bwrite },               /* bwrite */
1.29      chs        99:        { &vop_putpages_desc, mfs_putpages },           /* putpages */
                    100:        { NULL, NULL }
1.1       mycroft   101: };
1.27      jdolecek  102: const struct vnodeopv_desc mfs_vnodeop_opv_desc =
1.1       mycroft   103:        { &mfs_vnodeop_p, mfs_vnodeop_entries };
                    104:
                    105: /*
                    106:  * Vnode Operations.
                    107:  *
                    108:  * Open called to allow memory filesystem to initialize and
                    109:  * validate before actual IO. Record our process identifier
                    110:  * so we can tell when we are doing I/O to ourself.
                    111:  */
                    112: /* ARGSUSED */
                    113: int
1.39      xtraeme   114: mfs_open(void *v)
1.6       christos  115: {
1.1       mycroft   116:        struct vop_open_args /* {
                    117:                struct vnode *a_vp;
                    118:                int  a_mode;
1.43      elad      119:                kauth_cred_t a_cred;
1.6       christos  120:        } */ *ap = v;
1.1       mycroft   121:
                    122:        if (ap->a_vp->v_type != VBLK) {
                    123:                panic("mfs_ioctl not VBLK");
                    124:                /* NOTREACHED */
                    125:        }
                    126:        return (0);
                    127: }
                    128:
                    129: /*
                    130:  * Pass I/O requests to the memory filesystem process.
                    131:  */
                    132: int
1.39      xtraeme   133: mfs_strategy(void *v)
1.6       christos  134: {
1.1       mycroft   135:        struct vop_strategy_args /* {
1.36      hannken   136:                struct vnode *a_vp;
1.1       mycroft   137:                struct buf *a_bp;
1.6       christos  138:        } */ *ap = v;
1.36      hannken   139:        struct vnode *vp = ap->a_vp;
1.20      augustss  140:        struct buf *bp = ap->a_bp;
                    141:        struct mfsnode *mfsp;
1.1       mycroft   142:
1.36      hannken   143:        if (vp->v_type != VBLK || vp->v_usecount == 0)
1.1       mycroft   144:                panic("mfs_strategy: bad dev");
                    145:        mfsp = VTOMFS(vp);
1.23      thorpej   146:        /* check for mini-root access */
                    147:        if (mfsp->mfs_proc == NULL) {
1.44      christos  148:                void *base;
1.22      thorpej   149:
1.44      christos  150:                base = (char *)mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT);
1.1       mycroft   151:                if (bp->b_flags & B_READ)
1.14      perry     152:                        memcpy(bp->b_data, base, bp->b_bcount);
1.1       mycroft   153:                else
1.14      perry     154:                        memcpy(base, bp->b_data, bp->b_bcount);
1.25      thorpej   155:                bp->b_resid = 0;
1.23      thorpej   156:                biodone(bp);
1.48      ad        157:        } else if (mfsp->mfs_proc == curproc) {
1.23      thorpej   158:                mfs_doio(bp, mfsp->mfs_baseoff);
1.24      sommerfe  159:        } else if (doing_shutdown) {
1.38      perry     160:                /*
1.24      sommerfe  161:                 * bitbucket I/O during shutdown.
                    162:                 * Note that reads should *not* happen here, but..
                    163:                 */
                    164:                if (bp->b_flags & B_READ)
                    165:                        printf("warning: mfs read during shutdown\n");
1.25      thorpej   166:                bp->b_resid = 0;
1.24      sommerfe  167:                biodone(bp);
1.1       mycroft   168:        } else {
1.49      ad        169:                mutex_enter(&mfs_lock);
1.53      yamt      170:                bufq_put(mfsp->mfs_buflist, bp);
1.48      ad        171:                cv_broadcast(&mfsp->mfs_cv);
1.49      ad        172:                mutex_exit(&mfs_lock);
1.23      thorpej   173:        }
                    174:        return (0);
                    175: }
1.22      thorpej   176:
1.23      thorpej   177: /*
                    178:  * Memory file system I/O.
                    179:  */
                    180: void
1.44      christos  181: mfs_doio(struct buf *bp, void *base)
1.23      thorpej   182: {
1.48      ad        183:
1.44      christos  184:        base = (char *)base + (bp->b_blkno << DEV_BSHIFT);
1.23      thorpej   185:        if (bp->b_flags & B_READ)
                    186:                bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
                    187:        else
                    188:                bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
1.45      ad        189:        if (bp->b_error == 0)
1.16      chs       190:                bp->b_resid = 0;
1.1       mycroft   191:        biodone(bp);
                    192: }
                    193:
                    194: /*
                    195:  * This is a noop, simply returning what one has been given.
                    196:  */
                    197: int
1.39      xtraeme   198: mfs_bmap(void *v)
1.6       christos  199: {
1.1       mycroft   200:        struct vop_bmap_args /* {
                    201:                struct vnode *a_vp;
                    202:                daddr_t  a_bn;
                    203:                struct vnode **a_vpp;
                    204:                daddr_t *a_bnp;
                    205:                int *a_runp;
1.6       christos  206:        } */ *ap = v;
1.1       mycroft   207:
                    208:        if (ap->a_vpp != NULL)
                    209:                *ap->a_vpp = ap->a_vp;
                    210:        if (ap->a_bnp != NULL)
                    211:                *ap->a_bnp = ap->a_bn;
1.13      fvdl      212:        if (ap->a_runp != NULL)
                    213:                 *ap->a_runp = 0;
1.1       mycroft   214:        return (0);
                    215: }
                    216:
                    217: /*
                    218:  * Memory filesystem close routine
                    219:  */
                    220: /* ARGSUSED */
                    221: int
1.39      xtraeme   222: mfs_close(void *v)
1.6       christos  223: {
1.1       mycroft   224:        struct vop_close_args /* {
                    225:                struct vnode *a_vp;
                    226:                int  a_fflag;
1.43      elad      227:                kauth_cred_t a_cred;
1.6       christos  228:        } */ *ap = v;
1.20      augustss  229:        struct vnode *vp = ap->a_vp;
                    230:        struct mfsnode *mfsp = VTOMFS(vp);
1.23      thorpej   231:        struct buf *bp;
1.1       mycroft   232:        int error;
                    233:
                    234:        /*
1.23      thorpej   235:         * Finish any pending I/O requests.
                    236:         */
1.49      ad        237:        mutex_enter(&mfs_lock);
1.53      yamt      238:        while ((bp = bufq_get(mfsp->mfs_buflist)) != NULL) {
1.49      ad        239:                mutex_exit(&mfs_lock);
1.23      thorpej   240:                mfs_doio(bp, mfsp->mfs_baseoff);
1.49      ad        241:                mutex_enter(&mfs_lock);
1.23      thorpej   242:        }
1.49      ad        243:        mutex_exit(&mfs_lock);
1.23      thorpej   244:        /*
1.1       mycroft   245:         * On last close of a memory filesystem
                    246:         * we must invalidate any in core blocks, so that
                    247:         * we can, free up its vnode.
                    248:         */
1.46      pooka     249:        if ((error = vinvalbuf(vp, V_SAVE, ap->a_cred, curlwp, 0, 0)) != 0)
1.1       mycroft   250:                return (error);
                    251:        /*
                    252:         * There should be no way to have any more uses of this
                    253:         * vnode, so if we find any other uses, it is a panic.
                    254:         */
1.53      yamt      255:        if (bufq_peek(mfsp->mfs_buflist) != NULL)
1.1       mycroft   256:                panic("mfs_close");
                    257:        /*
                    258:         * Send a request to the filesystem server to exit.
                    259:         */
1.49      ad        260:        mutex_enter(&mfs_lock);
1.30      hannken   261:        mfsp->mfs_shutdown = 1;
1.48      ad        262:        cv_broadcast(&mfsp->mfs_cv);
1.49      ad        263:        mutex_exit(&mfs_lock);
1.1       mycroft   264:        return (0);
                    265: }
                    266:
                    267: /*
                    268:  * Memory filesystem inactive routine
                    269:  */
                    270: /* ARGSUSED */
                    271: int
1.39      xtraeme   272: mfs_inactive(void *v)
1.6       christos  273: {
1.1       mycroft   274:        struct vop_inactive_args /* {
                    275:                struct vnode *a_vp;
1.6       christos  276:        } */ *ap = v;
1.13      fvdl      277:        struct vnode *vp = ap->a_vp;
                    278:        struct mfsnode *mfsp = VTOMFS(vp);
1.1       mycroft   279:
1.53      yamt      280:        if (bufq_peek(mfsp->mfs_buflist) != NULL)
1.8       christos  281:                panic("mfs_inactive: not inactive (mfs_buflist %p)",
1.53      yamt      282:                        bufq_peek(mfsp->mfs_buflist));
1.54      hannken   283:        VOP_UNLOCK(vp);
1.1       mycroft   284:        return (0);
                    285: }
                    286:
                    287: /*
                    288:  * Reclaim a memory filesystem devvp so that it can be reused.
                    289:  */
                    290: int
1.39      xtraeme   291: mfs_reclaim(void *v)
1.6       christos  292: {
1.1       mycroft   293:        struct vop_reclaim_args /* {
                    294:                struct vnode *a_vp;
1.6       christos  295:        } */ *ap = v;
1.20      augustss  296:        struct vnode *vp = ap->a_vp;
1.48      ad        297:        struct mfsnode *mfsp = VTOMFS(vp);
1.49      ad        298:        int refcnt;
1.48      ad        299:
1.49      ad        300:        mutex_enter(&mfs_lock);
                    301:        vp->v_data = NULL;
                    302:        refcnt = --mfsp->mfs_refcnt;
                    303:        mutex_exit(&mfs_lock);
                    304:
                    305:        if (refcnt == 0) {
                    306:                bufq_free(mfsp->mfs_buflist);
                    307:                cv_destroy(&mfsp->mfs_cv);
                    308:                kmem_free(mfsp, sizeof(*mfsp));
                    309:        }
1.1       mycroft   310:
                    311:        return (0);
                    312: }
                    313:
                    314: /*
                    315:  * Print out the contents of an mfsnode.
                    316:  */
                    317: int
1.39      xtraeme   318: mfs_print(void *v)
1.6       christos  319: {
1.1       mycroft   320:        struct vop_print_args /* {
                    321:                struct vnode *a_vp;
1.6       christos  322:        } */ *ap = v;
1.20      augustss  323:        struct mfsnode *mfsp = VTOMFS(ap->a_vp);
1.1       mycroft   324:
1.21      thorpej   325:        printf("tag VT_MFS, pid %d, base %p, size %ld\n",
                    326:            (mfsp->mfs_proc != NULL) ? mfsp->mfs_proc->p_pid : 0,
1.8       christos  327:            mfsp->mfs_baseoff, mfsp->mfs_size);
1.1       mycroft   328:        return (0);
                    329: }

CVSweb <webmaster@jp.NetBSD.org>