[BACK]Return to ntfs_vfsops.c CVS log [TXT][DIR] Up to [local] / sys / ntfs

Annotation of sys/ntfs/ntfs_vfsops.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ntfs_vfsops.c,v 1.11 2006/04/19 11:55:55 pedro Exp $  */
                      2: /*     $NetBSD: ntfs_vfsops.c,v 1.7 2003/04/24 07:50:19 christos Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1998, 1999 Semen Ustimenko
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  *
                     29:  *     Id: ntfs_vfsops.c,v 1.7 1999/05/31 11:28:30 phk Exp
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
                     33: #ifdef __KERNEL_RCSID
                     34: __KERNEL_RCSID(0, "$NetBSD: ntfs_vfsops.c,v 1.7 2003/04/24 07:50:19 christos Exp $");
                     35: #endif
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/namei.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/kernel.h>
                     42: #include <sys/vnode.h>
                     43: #include <sys/mount.h>
                     44: #include <sys/buf.h>
                     45: #include <sys/fcntl.h>
                     46: #include <sys/malloc.h>
                     47: #include <sys/systm.h>
                     48: #include <sys/device.h>
                     49: #include <sys/conf.h>
                     50:
                     51: #if defined(__NetBSD__) || defined(__OpenBSD__)
                     52: #include <uvm/uvm_extern.h>
                     53: #else
                     54: #include <vm/vm.h>
                     55: #endif
                     56:
                     57: #include <miscfs/specfs/specdev.h>
                     58:
                     59: /*#define NTFS_DEBUG 1*/
                     60: #if defined(__FreeBSD__) || defined(__NetBSD__)
                     61: #include <fs/ntfs/ntfs.h>
                     62: #include <fs/ntfs/ntfs_inode.h>
                     63: #include <fs/ntfs/ntfs_subr.h>
                     64: #include <fs/ntfs/ntfs_vfsops.h>
                     65: #include <fs/ntfs/ntfs_ihash.h>
                     66: #include <fs/ntfs/ntfsmount.h>
                     67: #else
                     68: #include <ntfs/ntfs.h>
                     69: #include <ntfs/ntfs_inode.h>
                     70: #include <ntfs/ntfs_subr.h>
                     71: #include <ntfs/ntfs_vfsops.h>
                     72: #include <ntfs/ntfs_ihash.h>
                     73: #include <ntfs/ntfsmount.h>
                     74: #endif
                     75:
                     76: #ifdef MALLOC_DEFINE
                     77: MALLOC_DEFINE(M_NTFSMNT, "NTFS mount", "NTFS mount structure");
                     78: MALLOC_DEFINE(M_NTFSNTNODE,"NTFS ntnode",  "NTFS ntnode information");
                     79: MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode",  "NTFS fnode information");
                     80: MALLOC_DEFINE(M_NTFSDIR,"NTFS dir",  "NTFS dir buffer");
                     81: #endif
                     82:
                     83: #if defined(__FreeBSD__)
                     84: static int     ntfs_mount(struct mount *, char *, caddr_t,
                     85:                                struct nameidata *, struct proc *);
                     86: #else
                     87: static int     ntfs_mount(struct mount *, const char *, void *,
                     88:                                struct nameidata *, struct proc *);
                     89: #endif
                     90: static int     ntfs_quotactl(struct mount *, int, uid_t, caddr_t,
                     91:                                   struct proc *);
                     92: static int     ntfs_root(struct mount *, struct vnode **);
                     93: static int     ntfs_start(struct mount *, int, struct proc *);
                     94: static int     ntfs_statfs(struct mount *, struct statfs *,
                     95:                                 struct proc *);
                     96: static int     ntfs_sync(struct mount *, int, struct ucred *,
                     97:                               struct proc *);
                     98: static int     ntfs_unmount(struct mount *, int, struct proc *);
                     99: static int     ntfs_vget(struct mount *mp, ino_t ino,
                    100:                               struct vnode **vpp);
                    101: static int     ntfs_mountfs(struct vnode *, struct mount *,
                    102:                                  struct ntfs_args *, struct proc *);
                    103: static int     ntfs_vptofh(struct vnode *, struct fid *);
                    104:
                    105: #if defined(__FreeBSD__)
                    106: static int     ntfs_init(struct vfsconf *);
                    107: static int     ntfs_fhtovp(struct mount *, struct fid *,
                    108:                                 struct sockaddr *, struct vnode **,
                    109:                                 int *, struct ucred **);
                    110: #elif defined(__NetBSD__)
                    111: static void    ntfs_init(void);
                    112: static void    ntfs_reinit(void);
                    113: static void    ntfs_done(void);
                    114: static int     ntfs_fhtovp(struct mount *, struct fid *,
                    115:                                 struct vnode **);
                    116: static int     ntfs_checkexp(struct mount *, struct mbuf *,
                    117:                                   int *, struct ucred **);
                    118: static int     ntfs_mountroot(void);
                    119: static int     ntfs_sysctl(int *, u_int, void *, size_t *, void *,
                    120:                                 size_t, struct proc *);
                    121: #elif defined(__OpenBSD__)
                    122: static int     ntfs_init(struct vfsconf *);
                    123: static int     ntfs_fhtovp(struct mount *, struct fid *,
                    124:                             struct vnode **);
                    125: static int     ntfs_checkexp(struct mount *, struct mbuf *,
                    126:                               int *, struct ucred **);
                    127: static int     ntfs_sysctl(int *, u_int, void *, size_t *, void *,
                    128:                             size_t, struct proc *);
                    129: #else
                    130: static int     ntfs_init(void);
                    131: static int     ntfs_fhtovp(struct mount *, struct fid *,
                    132:                                 struct mbuf *, struct vnode **,
                    133:                                 int *, struct ucred **);
                    134: #endif
                    135:
                    136: #if defined(__FreeBSD__) || defined(__NetBSD__)
                    137: struct genfs_ops ntfs_genfsops = {
                    138:        NULL,
                    139:        NULL,
                    140:        genfs_compat_gop_write,
                    141: };
                    142: #endif
                    143:
                    144: #if defined(__NetBSD__) || defined(__OpenBSD__)
                    145: /*
                    146:  * Verify a remote client has export rights and return these rights via.
                    147:  * exflagsp and credanonp.
                    148:  */
                    149: static int
                    150: ntfs_checkexp(mp, nam, exflagsp, credanonp)
                    151:        struct mount *mp;
                    152:        struct mbuf *nam;
                    153:        int *exflagsp;
                    154:        struct ucred **credanonp;
                    155: {
                    156:        struct netcred *np;
                    157:        struct ntfsmount *ntm = VFSTONTFS(mp);
                    158:
                    159:        /*
                    160:         * Get the export permission structure for this <mp, client> tuple.
                    161:         */
                    162:        np = vfs_export_lookup(mp, &ntm->ntm_export, nam);
                    163:        if (np == NULL)
                    164:                return (EACCES);
                    165:
                    166:        *exflagsp = np->netc_exflags;
                    167:        *credanonp = &np->netc_anon;
                    168:        return (0);
                    169: }
                    170:
                    171: /*ARGSUSED*/
                    172: static int
                    173: ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    174:        int *name;
                    175:        u_int namelen;
                    176:        void *oldp;
                    177:        size_t *oldlenp;
                    178:        void *newp;
                    179:        size_t newlen;
                    180:        struct proc *p;
                    181: {
                    182:        return (EINVAL);
                    183: }
                    184:
                    185: #endif
                    186:
                    187: #ifdef __NetBSD__
                    188: static int
                    189: ntfs_mountroot()
                    190: {
                    191:        struct mount *mp;
                    192:        struct proc *p = curproc;       /* XXX */
                    193:        int error;
                    194:        struct ntfs_args args;
                    195:
                    196:        if (root_device->dv_class != DV_DISK)
                    197:                return (ENODEV);
                    198:
                    199:        /*
                    200:         * Get vnodes for rootdev.
                    201:         */
                    202:        if (bdevvp(rootdev, &rootvp))
                    203:                panic("ntfs_mountroot: can't setup rootvp");
                    204:
                    205:        if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) {
                    206:                vrele(rootvp);
                    207:                return (error);
                    208:        }
                    209:
                    210:        args.flag = 0;
                    211:        args.uid = 0;
                    212:        args.gid = 0;
                    213:        args.mode = 0777;
                    214:
                    215:        if ((error = ntfs_mountfs(rootvp, mp, &args, p)) != 0) {
                    216:                mp->mnt_op->vfs_refcount--;
                    217:                vfs_unbusy(mp);
                    218:                free(mp, M_MOUNT);
                    219:                vrele(rootvp);
                    220:                return (error);
                    221:        }
                    222:
                    223:        CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
                    224:        (void)ntfs_statfs(mp, &mp->mnt_stat, p);
                    225:        vfs_unbusy(mp);
                    226:
                    227:        return (0);
                    228: }
                    229:
                    230: static void
                    231: ntfs_init()
                    232: {
                    233: #ifdef _LKM
                    234:        malloc_type_attach(M_NTFSMNT);
                    235:        malloc_type_attach(M_NTFSNTNODE);
                    236:        malloc_type_attach(M_NTFSFNODE);
                    237:        malloc_type_attach(M_NTFSDIR);
                    238:        malloc_type_attach(M_NTFSNTHASH);
                    239:        malloc_type_attach(M_NTFSNTVATTR);
                    240:        malloc_type_attach(M_NTFSRDATA);
                    241:        malloc_type_attach(M_NTFSDECOMP);
                    242:        malloc_type_attach(M_NTFSRUN);
                    243: #endif
                    244:        ntfs_nthashinit();
                    245:        ntfs_toupper_init();
                    246: }
                    247:
                    248: static void
                    249: ntfs_reinit()
                    250: {
                    251:        ntfs_nthashreinit();
                    252: }
                    253:
                    254: static void
                    255: ntfs_done()
                    256: {
                    257:        ntfs_nthashdone();
                    258: #ifdef _LKM
                    259:        malloc_type_detach(M_NTFSMNT);
                    260:        malloc_type_detach(M_NTFSNTNODE);
                    261:        malloc_type_detach(M_NTFSFNODE);
                    262:        malloc_type_detach(M_NTFSDIR);
                    263:        malloc_type_detach(M_NTFSNTHASH);
                    264:        malloc_type_detach(M_NTFSNTVATTR);
                    265:        malloc_type_detach(M_NTFSRDATA);
                    266:        malloc_type_detach(M_NTFSDECOMP);
                    267:        malloc_type_detach(M_NTFSRUN);
                    268: #endif
                    269: }
                    270:
                    271: #elif defined(__FreeBSD__) || defined(__OpenBSD__)
                    272:
                    273: static int
                    274: ntfs_init (
                    275:        struct vfsconf *vcp )
                    276: {
                    277:        ntfs_nthashinit();
                    278:        ntfs_toupper_init();
                    279:        return 0;
                    280: }
                    281:
                    282: #endif /* NetBSD */
                    283:
                    284: static int
                    285: ntfs_mount(
                    286:        struct mount *mp,
                    287: #if defined(__FreeBSD__)
                    288:        char *path,
                    289:        caddr_t data,
                    290: #else
                    291:        const char *path,
                    292:        void *data,
                    293: #endif
                    294:        struct nameidata *ndp,
                    295:        struct proc *p )
                    296: {
                    297:        int             err = 0;
                    298:        struct vnode    *devvp;
                    299:        struct ntfs_args args;
                    300:        size_t size;
                    301:        mode_t amode;
                    302:
                    303: #ifdef __FreeBSD__
                    304:        /*
                    305:         * Use NULL path to flag a root mount
                    306:         */
                    307:        if( path == NULL) {
                    308:                /*
                    309:                 ***
                    310:                 * Mounting root file system
                    311:                 ***
                    312:                 */
                    313:
                    314:                /* Get vnode for root device*/
                    315:                if( bdevvp( rootdev, &rootvp))
                    316:                        panic("ffs_mountroot: can't setup bdevvp for root");
                    317:
                    318:                /*
                    319:                 * FS specific handling
                    320:                 */
                    321:                mp->mnt_flag |= MNT_RDONLY;     /* XXX globally applicable?*/
                    322:
                    323:                /*
                    324:                 * Attempt mount
                    325:                 */
                    326:                if( ( err = ntfs_mountfs(rootvp, mp, &args, p)) != 0) {
                    327:                        /* fs specific cleanup (if any)*/
                    328:                        goto error_1;
                    329:                }
                    330:
                    331:                goto dostatfs;          /* success*/
                    332:
                    333:        }
                    334: #endif /* FreeBSD */
                    335:
                    336: #ifdef __NetBSD__
                    337:        if (mp->mnt_flag & MNT_GETARGS) {
                    338:                struct ntfsmount *ntmp = VFSTONTFS(mp);
                    339:                if (ntmp == NULL)
                    340:                        return EIO;
                    341:                args.fspec = NULL;
                    342:                args.uid = ntmp->ntm_uid;
                    343:                args.gid = ntmp->ntm_gid;
                    344:                args.mode = ntmp->ntm_mode;
                    345:                args.flag = ntmp->ntm_flag;
                    346:                vfs_showexport(mp, &args.export, &ntmp->ntm_export);
                    347:                return copyout(&args, data, sizeof(args));
                    348:        }
                    349: #endif
                    350:
                    351:        /*
                    352:         ***
                    353:         * Mounting non-root file system or updating a file system
                    354:         ***
                    355:         */
                    356:
                    357:        /* copy in user arguments*/
                    358:        err = copyin(data, (caddr_t)&args, sizeof (struct ntfs_args));
                    359:        if (err)
                    360:                goto error_1;           /* can't get arguments*/
                    361:
                    362:        /*
                    363:         * If updating, check whether changing from read-only to
                    364:         * read/write; if there is no device name, that's all we do.
                    365:         */
                    366:        if (mp->mnt_flag & MNT_UPDATE) {
                    367:                /* if not updating name...*/
                    368:                if (args.fspec == 0) {
                    369:                        /*
                    370:                         * Process export requests.  Jumping to "success"
                    371:                         * will return the vfs_export() error code.
                    372:                         */
                    373:                        struct ntfsmount *ntm = VFSTONTFS(mp);
                    374:                        err = vfs_export(mp, &ntm->ntm_export, &args.export_info);
                    375:                        goto success;
                    376:                }
                    377:
                    378:                printf("ntfs_mount(): MNT_UPDATE not supported\n");
                    379:                err = EINVAL;
                    380:                goto error_1;
                    381:        }
                    382:
                    383:        /*
                    384:         * Not an update, or updating the name: look up the name
                    385:         * and verify that it refers to a sensible block device.
                    386:         */
                    387:        NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
                    388:        err = namei(ndp);
                    389:        if (err) {
                    390:                /* can't get devvp!*/
                    391:                goto error_1;
                    392:        }
                    393:
                    394:        devvp = ndp->ni_vp;
                    395:
                    396:        if (devvp->v_type != VBLK) {
                    397:                err = ENOTBLK;
                    398:                goto error_2;
                    399:        }
                    400:
                    401: #ifdef __FreeBSD__
                    402:        if (bdevsw(devvp->v_rdev) == NULL) {
                    403: #elif defined(__NetBSD__)
                    404:        if (bdevsw_lookup(devvp->v_rdev) == NULL) {
                    405: #else
                    406:        if (major(devvp->v_rdev) >= nblkdev) {
                    407: #endif
                    408:                err = ENXIO;
                    409:                goto error_2;
                    410:        }
                    411:
                    412:        /*
                    413:         * If we are not root, make sure we have permission to access the
                    414:         * requested device.
                    415:         */
                    416:        if (p->p_ucred->cr_uid) {
                    417:                amode = (mp->mnt_flag & MNT_RDONLY) ? VREAD : (VREAD | VWRITE);
                    418:                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
                    419:                err = VOP_ACCESS(devvp, amode, p->p_ucred, p);
                    420:                VOP_UNLOCK(devvp, 0, p);
                    421:                if (err)
                    422:                        goto error_2;
                    423:        }
                    424:
                    425:        if (mp->mnt_flag & MNT_UPDATE) {
                    426: #if 0
                    427:                /*
                    428:                 ********************
                    429:                 * UPDATE
                    430:                 ********************
                    431:                 */
                    432:
                    433:                if (devvp != ntmp->um_devvp)
                    434:                        err = EINVAL;   /* needs translation */
                    435:                else
                    436:                        vrele(devvp);
                    437:                /*
                    438:                 * Update device name only on success
                    439:                 */
                    440:                if( !err) {
                    441:                        err = set_statfs_info(NULL, UIO_USERSPACE, args.fspec,
                    442:                            UIO_USERSPACE, mp, p);
                    443:                }
                    444: #endif
                    445:        } else {
                    446:                /*
                    447:                 ********************
                    448:                 * NEW MOUNT
                    449:                 ********************
                    450:                 */
                    451:
                    452:                /*
                    453:                 * Since this is a new mount, we want the names for
                    454:                 * the device and the mount point copied in.  If an
                    455:                 * error occurs,  the mountpoint is discarded by the
                    456:                 * upper level code.
                    457:                 */
                    458:                /* Save "last mounted on" info for mount point (NULL pad)*/
                    459: #if defined(__FreeBSD__) || defined(__NetBSD__)
                    460:                err = set_statfs_info(path, UIO_USERSPACE, args.fspec,
                    461:                    UIO_USERSPACE, mp, p);
                    462: #else
                    463:                (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1,
                    464:                           &size);
                    465:                bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
                    466:                (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname,
                    467:                           MNAMELEN - 1, &size);
                    468:                bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                    469:                bcopy(&args, &mp->mnt_stat.mount_info.ntfs_args, sizeof(args));
                    470: #endif
                    471:                if ( !err) {
                    472:                        err = ntfs_mountfs(devvp, mp, &args, p);
                    473:                }
                    474:        }
                    475:        if (err) {
                    476:                goto error_2;
                    477:        }
                    478:
                    479: #ifdef __FreeBSD__
                    480: dostatfs:
                    481: #endif
                    482:        /*
                    483:         * Initialize FS stat information in mount struct; uses both
                    484:         * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
                    485:         *
                    486:         * This code is common to root and non-root mounts
                    487:         */
                    488:        (void)VFS_STATFS(mp, &mp->mnt_stat, p);
                    489:
                    490:        goto success;
                    491:
                    492:
                    493: error_2:       /* error with devvp held*/
                    494:
                    495:        /* release devvp before failing*/
                    496:        vrele(devvp);
                    497:
                    498: error_1:       /* no state to back out*/
                    499:
                    500: success:
                    501:        return(err);
                    502: }
                    503:
                    504: /*
                    505:  * Common code for mount and mountroot
                    506:  */
                    507: int
                    508: ntfs_mountfs(devvp, mp, argsp, p)
                    509:        struct vnode *devvp;
                    510:        struct mount *mp;
                    511:        struct ntfs_args *argsp;
                    512:        struct proc *p;
                    513: {
                    514:        struct buf *bp;
                    515:        struct ntfsmount *ntmp = NULL;
                    516:        dev_t dev = devvp->v_rdev;
                    517:        int error, ronly, ncount, i;
                    518:        struct vnode *vp;
                    519:
                    520:        /*
                    521:         * Disallow multiple mounts of the same device.
                    522:         * Disallow mounting of a device that is currently in use
                    523:         * (except for root, which might share swap device for miniroot).
                    524:         * Flush out any old buffers remaining from a previous use.
                    525:         */
                    526:        error = vfs_mountedon(devvp);
                    527:        if (error)
                    528:                return (error);
                    529:        ncount = vcount(devvp);
                    530:        if (ncount > 1 && devvp != rootvp)
                    531:                return (EBUSY);
                    532:        error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
                    533:        if (error)
                    534:                return (error);
                    535:
                    536:        ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
                    537:        error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
                    538:        if (error)
                    539:                return (error);
                    540:
                    541:        bp = NULL;
                    542:
                    543:        error = bread(devvp, BBLOCK, BBSIZE, NOCRED, &bp);
                    544:        if (error)
                    545:                goto out;
                    546:        ntmp = malloc(sizeof *ntmp, M_NTFSMNT, M_WAITOK);
                    547:        bzero(ntmp, sizeof *ntmp);
                    548:        bcopy(bp->b_data, &ntmp->ntm_bootfile, sizeof(struct bootfile));
                    549:        brelse(bp);
                    550:        bp = NULL;
                    551:
                    552:        if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
                    553:                error = EINVAL;
                    554:                dprintf(("ntfs_mountfs: invalid boot block\n"));
                    555:                goto out;
                    556:        }
                    557:
                    558:        {
                    559:                int8_t cpr = ntmp->ntm_mftrecsz;
                    560:                if( cpr > 0 )
                    561:                        ntmp->ntm_bpmftrec = ntmp->ntm_spc * cpr;
                    562:                else
                    563:                        ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;
                    564:        }
                    565:        dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
                    566:                ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media,
                    567:                ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec));
                    568:        dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
                    569:                (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn));
                    570:
                    571:        ntmp->ntm_mountp = mp;
                    572:        ntmp->ntm_dev = dev;
                    573:        ntmp->ntm_devvp = devvp;
                    574:        ntmp->ntm_uid = argsp->uid;
                    575:        ntmp->ntm_gid = argsp->gid;
                    576:        ntmp->ntm_mode = argsp->mode;
                    577:        ntmp->ntm_flag = argsp->flag;
                    578: #ifdef __OpenBSD__
                    579:        mp->mnt_data = (qaddr_t) ntmp;
                    580: #else
                    581:        mp->mnt_data = ntmp;
                    582: #endif
                    583:
                    584:        /* set file name encode/decode hooks XXX utf-8 only for now */
                    585:        ntmp->ntm_wget = ntfs_utf8_wget;
                    586:        ntmp->ntm_wput = ntfs_utf8_wput;
                    587:        ntmp->ntm_wcmp = ntfs_utf8_wcmp;
                    588:
                    589:        dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
                    590:                (ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
                    591:                (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
                    592:                ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
                    593:
                    594:        /*
                    595:         * We read in some system nodes to do not allow
                    596:         * reclaim them and to have everytime access to them.
                    597:         */
                    598:        {
                    599:                int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
                    600:                for (i=0; i<3; i++) {
                    601:                        error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]]));
                    602:                        if(error)
                    603:                                goto out1;
                    604:                        ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
                    605:                        VREF(ntmp->ntm_sysvn[pi[i]]);
                    606:                        vput(ntmp->ntm_sysvn[pi[i]]);
                    607:                }
                    608:        }
                    609:
                    610:        /* read the Unicode lowercase --> uppercase translation table,
                    611:         * if necessary */
                    612: #ifndef __OpenBSD__
                    613:        if ((error = ntfs_toupper_use(mp, ntmp)))
                    614: #else
                    615:        if ((error = ntfs_toupper_use(mp, ntmp, p)))
                    616: #endif
                    617:                goto out1;
                    618:
                    619:        /*
                    620:         * Scan $BitMap and count free clusters
                    621:         */
                    622:        error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree);
                    623:        if(error)
                    624:                goto out1;
                    625:
                    626:        /*
                    627:         * Read and translate to internal format attribute
                    628:         * definition file.
                    629:         */
                    630:        {
                    631:                int num,j;
                    632:                struct attrdef ad;
                    633:
                    634:                /* Open $AttrDef */
                    635:                error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp );
                    636:                if(error)
                    637:                        goto out1;
                    638:
                    639:                /* Count valid entries */
                    640:                for(num=0;;num++) {
                    641:                        error = ntfs_readattr(ntmp, VTONT(vp),
                    642:                                        NTFS_A_DATA, NULL,
                    643:                                        num * sizeof(ad), sizeof(ad),
                    644:                                        &ad, NULL);
                    645:                        if (error)
                    646:                                goto out1;
                    647:                        if (ad.ad_name[0] == 0)
                    648:                                break;
                    649:                }
                    650:
                    651:                /* Alloc memory for attribute definitions */
                    652:                ntmp->ntm_ad = (struct ntvattrdef *) malloc(
                    653:                        num * sizeof(struct ntvattrdef),
                    654:                        M_NTFSMNT, M_WAITOK);
                    655:
                    656:                ntmp->ntm_adnum = num;
                    657:
                    658:                /* Read them and translate */
                    659:                for(i=0;i<num;i++){
                    660:                        error = ntfs_readattr(ntmp, VTONT(vp),
                    661:                                        NTFS_A_DATA, NULL,
                    662:                                        i * sizeof(ad), sizeof(ad),
                    663:                                        &ad, NULL);
                    664:                        if (error)
                    665:                                goto out1;
                    666:                        j = 0;
                    667:                        do {
                    668:                                ntmp->ntm_ad[i].ad_name[j] = ad.ad_name[j];
                    669:                        } while(ad.ad_name[j++]);
                    670:                        ntmp->ntm_ad[i].ad_namelen = j - 1;
                    671:                        ntmp->ntm_ad[i].ad_type = ad.ad_type;
                    672:                }
                    673:
                    674:                vput(vp);
                    675:        }
                    676:
                    677: #if defined(__FreeBSD__)
                    678:        mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
                    679:        mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
                    680: #else
                    681:        mp->mnt_stat.f_fsid.val[0] = dev;
                    682:        mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_NTFS);
                    683: #endif
                    684:        mp->mnt_maxsymlinklen = 0;
                    685:        mp->mnt_flag |= MNT_LOCAL;
                    686:        devvp->v_specmountpoint = mp;
                    687:        return (0);
                    688:
                    689: out1:
                    690:        for (i = 0; i < NTFS_SYSNODESNUM; i++)
                    691:                if (ntmp->ntm_sysvn[i])
                    692:                        vrele(ntmp->ntm_sysvn[i]);
                    693:
                    694:        if (vflush(mp,NULLVP,0))
                    695:                dprintf(("ntfs_mountfs: vflush failed\n"));
                    696:
                    697: out:
                    698:        devvp->v_specmountpoint = NULL;
                    699:        if (bp)
                    700:                brelse(bp);
                    701:
                    702:        if (ntmp != NULL) {
                    703:                if (ntmp->ntm_ad != NULL)
                    704:                        free(ntmp->ntm_ad, M_NTFSMNT);
                    705:                free(ntmp, M_NTFSMNT);
                    706:                mp->mnt_data = NULL;
                    707:        }
                    708:
                    709:        /* lock the device vnode before calling VOP_CLOSE() */
                    710:        VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
                    711:        (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
                    712:        VOP__UNLOCK(devvp, 0, p);
                    713:
                    714:        return (error);
                    715: }
                    716:
                    717: static int
                    718: ntfs_start (
                    719:        struct mount *mp,
                    720:        int flags,
                    721:        struct proc *p )
                    722: {
                    723:        return (0);
                    724: }
                    725:
                    726: static int
                    727: ntfs_unmount(
                    728:        struct mount *mp,
                    729:        int mntflags,
                    730:        struct proc *p)
                    731: {
                    732:        struct ntfsmount *ntmp;
                    733:        int error, ronly = 0, flags, i;
                    734:
                    735:        dprintf(("ntfs_unmount: unmounting...\n"));
                    736:        ntmp = VFSTONTFS(mp);
                    737:
                    738:        flags = 0;
                    739:        if(mntflags & MNT_FORCE)
                    740:                flags |= FORCECLOSE;
                    741:
                    742:        dprintf(("ntfs_unmount: vflushing...\n"));
                    743:        error = vflush(mp,NULLVP,flags | SKIPSYSTEM);
                    744:        if (error) {
                    745:                dprintf(("ntfs_unmount: vflush failed: %d\n",error));
                    746:                return (error);
                    747:        }
                    748:
                    749:        /* Check if only system vnodes are rest */
                    750:        for(i=0;i<NTFS_SYSNODESNUM;i++)
                    751:                 if((ntmp->ntm_sysvn[i]) &&
                    752:                    (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
                    753:
                    754:        /* Dereference all system vnodes */
                    755:        for(i=0;i<NTFS_SYSNODESNUM;i++)
                    756:                 if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
                    757:
                    758:        /* vflush system vnodes */
                    759:        error = vflush(mp,NULLVP,flags);
                    760:        if (error) {
                    761:                /* XXX should this be panic() ? */
                    762:                printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
                    763:        }
                    764:
                    765:        /* Check if the type of device node isn't VBAD before
                    766:         * touching v_specinfo.  If the device vnode is revoked, the
                    767:         * field is NULL and touching it causes null pointer derefercence.
                    768:         */
                    769:        if (ntmp->ntm_devvp->v_type != VBAD)
                    770:                ntmp->ntm_devvp->v_specmountpoint = NULL;
                    771:
                    772:        vinvalbuf(ntmp->ntm_devvp, V_SAVE, NOCRED, p, 0, 0);
                    773:
                    774:        /* lock the device vnode before calling VOP_CLOSE() */
                    775: #ifndef __OpenBSD__
                    776:        VOP_LOCK(ntmp->ntm_devvp, LK_EXCLUSIVE | LK_RETRY);
                    777: #else
                    778:        VOP_LOCK(ntmp->ntm_devvp, LK_EXCLUSIVE | LK_RETRY, p);
                    779: #endif
                    780:        error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
                    781:                NOCRED, p);
                    782:        VOP__UNLOCK(ntmp->ntm_devvp, 0, p);
                    783:
                    784:        vrele(ntmp->ntm_devvp);
                    785:
                    786:        /* free the toupper table, if this has been last mounted ntfs volume */
                    787: #ifndef __OpenBSD__
                    788:        ntfs_toupper_unuse();
                    789: #else
                    790:        ntfs_toupper_unuse(p);
                    791: #endif
                    792:
                    793:        dprintf(("ntfs_umount: freeing memory...\n"));
                    794:        mp->mnt_data = NULL;
                    795:        mp->mnt_flag &= ~MNT_LOCAL;
                    796:        free(ntmp->ntm_ad, M_NTFSMNT);
                    797:        free(ntmp, M_NTFSMNT);
                    798:        return (error);
                    799: }
                    800:
                    801: static int
                    802: ntfs_root(
                    803:        struct mount *mp,
                    804:        struct vnode **vpp )
                    805: {
                    806:        struct vnode *nvp;
                    807:        int error = 0;
                    808:
                    809:        dprintf(("ntfs_root(): sysvn: %p\n",
                    810:                VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
                    811:        error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp);
                    812:        if(error) {
                    813:                printf("ntfs_root: VFS_VGET failed: %d\n",error);
                    814:                return (error);
                    815:        }
                    816:
                    817:        *vpp = nvp;
                    818:        return (0);
                    819: }
                    820:
                    821: /*
                    822:  * Do operations associated with quotas, not supported
                    823:  */
                    824: /* ARGSUSED */
                    825: static int
                    826: ntfs_quotactl (
                    827:        struct mount *mp,
                    828:        int cmds,
                    829:        uid_t uid,
                    830:        caddr_t arg,
                    831:        struct proc *p)
                    832: {
                    833:
                    834:        return EOPNOTSUPP;
                    835: }
                    836:
                    837: int
                    838: ntfs_calccfree(
                    839:        struct ntfsmount *ntmp,
                    840:        cn_t *cfreep)
                    841: {
                    842:        struct vnode *vp;
                    843:        u_int8_t *tmp;
                    844:        int j, error;
                    845:        cn_t cfree = 0;
                    846:        size_t bmsize, i;
                    847:
                    848:        vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
                    849:
                    850:        bmsize = VTOF(vp)->f_size;
                    851:
                    852:        tmp = (u_int8_t *) malloc(bmsize, M_TEMP, M_WAITOK);
                    853:
                    854:        error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
                    855:                               0, bmsize, tmp, NULL);
                    856:        if (error)
                    857:                goto out;
                    858:
                    859:        for(i=0;i<bmsize;i++)
                    860:                for(j=0;j<8;j++)
                    861:                        if(~tmp[i] & (1 << j)) cfree++;
                    862:        *cfreep = cfree;
                    863:
                    864:     out:
                    865:        free(tmp, M_TEMP);
                    866:        return(error);
                    867: }
                    868:
                    869: static int
                    870: ntfs_statfs(
                    871:        struct mount *mp,
                    872:        struct statfs *sbp,
                    873:        struct proc *p)
                    874: {
                    875:        struct ntfsmount *ntmp = VFSTONTFS(mp);
                    876:        u_int64_t mftallocated;
                    877:
                    878:        dprintf(("ntfs_statfs():\n"));
                    879:
                    880:        mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated;
                    881:
                    882: #if defined(__FreeBSD__)
                    883:        sbp->f_type = mp->mnt_vfc->vfc_typenum;
                    884: #elif defined(__NetBSD__)
                    885:        sbp->f_type = 0;
                    886: #elif !defined(__OpenBSD__)
                    887:        sbp->f_type = MOUNT_NTFS;
                    888: #endif
                    889:        sbp->f_bsize = ntmp->ntm_bps;
                    890:        sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc;
                    891:        sbp->f_blocks = ntmp->ntm_bootfile.bf_spv;
                    892:        sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree);
                    893:        sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec;
                    894:        sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) +
                    895:                       sbp->f_ffree;
                    896:        sbp->f_flags = mp->mnt_flag;
                    897: #if !defined(__OpenBSD__)
                    898:        copy_statfs_info(sbp, mp);
                    899: #else
                    900:        if (sbp != &mp->mnt_stat) {
                    901:                bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
                    902:                bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
                    903:                bcopy(&mp->mnt_stat.mount_info.msdosfs_args,
                    904:                    &sbp->mount_info.msdosfs_args, sizeof(struct msdosfs_args));
                    905:        }
                    906:        strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
                    907: #endif
                    908:        return (0);
                    909: }
                    910:
                    911: static int
                    912: ntfs_sync (
                    913:        struct mount *mp,
                    914:        int waitfor,
                    915:        struct ucred *cred,
                    916:        struct proc *p)
                    917: {
                    918:        /*dprintf(("ntfs_sync():\n"));*/
                    919:        return (0);
                    920: }
                    921:
                    922: /*ARGSUSED*/
                    923: static int
                    924: ntfs_fhtovp(
                    925: #if defined(__FreeBSD__)
                    926:        struct mount *mp,
                    927:        struct fid *fhp,
                    928:        struct sockaddr *nam,
                    929:        struct vnode **vpp,
                    930:        int *exflagsp,
                    931:        struct ucred **credanonp)
                    932: #elif defined(__NetBSD__) || defined(__OpenBSD__)
                    933:        struct mount *mp,
                    934:        struct fid *fhp,
                    935:        struct vnode **vpp)
                    936: #else
                    937:        struct mount *mp,
                    938:        struct fid *fhp,
                    939:        struct mbuf *nam,
                    940:        struct vnode **vpp,
                    941:        int *exflagsp,
                    942:        struct ucred **credanonp)
                    943: #endif
                    944: {
                    945:        struct ntfid *ntfhp = (struct ntfid *)fhp;
                    946:        int error;
                    947:
                    948:        ddprintf(("ntfs_fhtovp(): %s: %d\n", mp->mnt_stat.f_mntonname,
                    949:                ntfhp->ntfid_ino));
                    950:
                    951:        error = ntfs_vgetex(mp, ntfhp->ntfid_ino, ntfhp->ntfid_attr, NULL,
                    952:                        LK_EXCLUSIVE | LK_RETRY, 0, curproc, vpp); /* XXX */
                    953:        if (error != 0) {
                    954:                *vpp = NULLVP;
                    955:                return (error);
                    956:        }
                    957:
                    958:        /* XXX as unlink/rmdir/mkdir/creat are not currently possible
                    959:         * with NTFS, we don't need to check anything else for now */
                    960:        return (0);
                    961: }
                    962:
                    963: static int
                    964: ntfs_vptofh(
                    965:        struct vnode *vp,
                    966:        struct fid *fhp)
                    967: {
                    968:        struct ntnode *ntp;
                    969:        struct ntfid *ntfhp;
                    970:        struct fnode *fn;
                    971:
                    972:        ddprintf(("ntfs_fhtovp(): %s: %p\n", vp->v_mount->mnt_stat.f_mntonname,
                    973:                vp));
                    974:
                    975:        fn = VTOF(vp);
                    976:        ntp = VTONT(vp);
                    977:        ntfhp = (struct ntfid *)fhp;
                    978:        ntfhp->ntfid_len = sizeof(struct ntfid);
                    979:        ntfhp->ntfid_ino = ntp->i_number;
                    980:        ntfhp->ntfid_attr = fn->f_attrtype;
                    981: #ifdef notyet
                    982:        ntfhp->ntfid_gen = ntp->i_gen;
                    983: #endif
                    984:        return (0);
                    985: }
                    986:
                    987: int
                    988: ntfs_vgetex(
                    989:        struct mount *mp,
                    990:        ino_t ino,
                    991:        u_int32_t attrtype,
                    992:        char *attrname,
                    993:        u_long lkflags,
                    994:        u_long flags,
                    995:        struct proc *p,
                    996:        struct vnode **vpp)
                    997: {
                    998:        int error;
                    999:        struct ntfsmount *ntmp;
                   1000:        struct ntnode *ip;
                   1001:        struct fnode *fp;
                   1002:        struct vnode *vp;
                   1003:        enum vtype f_type;
                   1004:
                   1005:        dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n",
                   1006:                ino, attrtype, attrname?attrname:"", (u_long)lkflags,
                   1007:                (u_long)flags ));
                   1008:
                   1009:        ntmp = VFSTONTFS(mp);
                   1010:        *vpp = NULL;
                   1011:
                   1012:        /* Get ntnode */
                   1013: #ifndef __OpenBSD__
                   1014:        error = ntfs_ntlookup(ntmp, ino, &ip);
                   1015: #else
                   1016:        error = ntfs_ntlookup(ntmp, ino, &ip, p);
                   1017: #endif
                   1018:        if (error) {
                   1019:                printf("ntfs_vget: ntfs_ntget failed\n");
                   1020:                return (error);
                   1021:        }
                   1022:
                   1023:        /* It may be not initialized fully, so force load it */
                   1024:        if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) {
                   1025:                error = ntfs_loadntnode(ntmp, ip);
                   1026:                if(error) {
                   1027:                        printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
                   1028:                               ip->i_number);
                   1029: #ifndef __OpenBSD__
                   1030:                        ntfs_ntput(ip);
                   1031: #else
                   1032:                        ntfs_ntput(ip, p);
                   1033: #endif
                   1034:                        return (error);
                   1035:                }
                   1036:        }
                   1037:
                   1038:        error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
                   1039:        if (error) {
                   1040:                printf("ntfs_vget: ntfs_fget failed\n");
                   1041: #ifndef __OpenBSD__
                   1042:                ntfs_ntput(ip);
                   1043: #else
                   1044:                ntfs_ntput(ip, p);
                   1045: #endif
                   1046:                return (error);
                   1047:        }
                   1048:
                   1049:        if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
                   1050:                if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
                   1051:                    (fp->f_attrtype == NTFS_A_DATA && fp->f_attrname == NULL)) {
                   1052:                        f_type = VDIR;
                   1053:                } else if (flags & VG_EXT) {
                   1054:                        f_type = VNON;
                   1055:                        fp->f_size = fp->f_allocated = 0;
                   1056:                } else {
                   1057:                        f_type = VREG;
                   1058:
                   1059:                        error = ntfs_filesize(ntmp, fp,
                   1060:                                              &fp->f_size, &fp->f_allocated);
                   1061:                        if (error) {
                   1062: #ifndef __OpenBSD__
                   1063:                                ntfs_ntput(ip);
                   1064: #else
                   1065:                                ntfs_ntput(ip, p);
                   1066: #endif
                   1067:                                return (error);
                   1068:                        }
                   1069:                }
                   1070:
                   1071:                fp->f_flag |= FN_VALID;
                   1072:        }
                   1073:
                   1074:        /*
                   1075:         * We may be calling vget() now. To avoid potential deadlock, we need
                   1076:         * to release ntnode lock, since due to locking order vnode
                   1077:         * lock has to be acquired first.
                   1078:         * ntfs_fget() bumped ntnode usecount, so ntnode won't be recycled
                   1079:         * prematurely.
                   1080:         */
                   1081: #ifndef __OpenBSD__
                   1082:        ntfs_ntput(ip);
                   1083: #else
                   1084:        ntfs_ntput(ip, p);
                   1085: #endif
                   1086:
                   1087:        if (FTOV(fp)) {
                   1088:                /* vget() returns error if the vnode has been recycled */
                   1089:                if (VGET(FTOV(fp), lkflags, p) == 0) {
                   1090:                        *vpp = FTOV(fp);
                   1091:                        return (0);
                   1092:                }
                   1093:        }
                   1094:
                   1095:        error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
                   1096:        if(error) {
                   1097:                ntfs_frele(fp);
                   1098: #ifndef __OpenBSD__
                   1099:                ntfs_ntput(ip);
                   1100: #else
                   1101:                ntfs_ntput(ip, p);
                   1102: #endif
                   1103:                return (error);
                   1104:        }
                   1105:        dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
                   1106:
                   1107: #ifdef __FreeBSD__
                   1108:        lockinit(&fp->f_lock, PINOD, "fnode", 0, 0);
                   1109: #endif
                   1110:        fp->f_vp = vp;
                   1111:        vp->v_data = fp;
                   1112:        vp->v_type = f_type;
                   1113:
                   1114:        if (ino == NTFS_ROOTINO)
                   1115:                vp->v_flag |= VROOT;
                   1116:
                   1117:        if (lkflags & LK_TYPE_MASK) {
                   1118:                error = VN_LOCK(vp, lkflags, p);
                   1119:                if (error) {
                   1120:                        vput(vp);
                   1121:                        return (error);
                   1122:                }
                   1123:        }
                   1124:
                   1125: #if defined(__FreeBSD__) || defined(__NetBSD__)
                   1126:        genfs_node_init(vp, &ntfs_genfsops);
                   1127: #endif
                   1128:        *vpp = vp;
                   1129:        return (0);
                   1130: }
                   1131:
                   1132: static int
                   1133: ntfs_vget(
                   1134:        struct mount *mp,
                   1135:        ino_t ino,
                   1136:        struct vnode **vpp)
                   1137: {
                   1138:        return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
                   1139:                        LK_EXCLUSIVE | LK_RETRY, 0, curproc, vpp); /* XXX */
                   1140: }
                   1141:
                   1142: #if defined(__FreeBSD__)
                   1143: static struct vfsops ntfs_vfsops = {
                   1144:        ntfs_mount,
                   1145:        ntfs_start,
                   1146:        ntfs_unmount,
                   1147:        ntfs_root,
                   1148:        ntfs_quotactl,
                   1149:        ntfs_statfs,
                   1150:        ntfs_sync,
                   1151:        ntfs_vget,
                   1152:        ntfs_fhtovp,
                   1153:        ntfs_vptofh,
                   1154:        ntfs_init,
                   1155:        NULL
                   1156: };
                   1157: VFS_SET(ntfs_vfsops, ntfs, 0);
                   1158: #elif defined(__NetBSD__)
                   1159: extern const struct vnodeopv_desc ntfs_vnodeop_opv_desc;
                   1160:
                   1161: const struct vnodeopv_desc * const ntfs_vnodeopv_descs[] = {
                   1162:        &ntfs_vnodeop_opv_desc,
                   1163:        NULL,
                   1164: };
                   1165:
                   1166: struct vfsops ntfs_vfsops = {
                   1167:        MOUNT_NTFS,
                   1168:        ntfs_mount,
                   1169:        ntfs_start,
                   1170:        ntfs_unmount,
                   1171:        ntfs_root,
                   1172:        ntfs_quotactl,
                   1173:        ntfs_statfs,
                   1174:        ntfs_sync,
                   1175:        ntfs_vget,
                   1176:        ntfs_fhtovp,
                   1177:        ntfs_vptofh,
                   1178:        ntfs_init,
                   1179:        ntfs_reinit,
                   1180:        ntfs_done,
                   1181:        ntfs_sysctl,
                   1182:        ntfs_mountroot,
                   1183:        ntfs_checkexp,
                   1184:        ntfs_vnodeopv_descs,
                   1185: };
                   1186: #elif defined(__OpenBSD__)
                   1187: extern const struct vnodeopv_desc ntfs_vnodeop_opv_desc;
                   1188:
                   1189: const struct vnodeopv_desc * const ntfs_vnodeopv_descs[] = {
                   1190:        &ntfs_vnodeop_opv_desc,
                   1191:        NULL,
                   1192: };
                   1193:
                   1194: const struct vfsops ntfs_vfsops = {
                   1195:        ntfs_mount,
                   1196:        ntfs_start,
                   1197:        ntfs_unmount,
                   1198:        ntfs_root,
                   1199:        ntfs_quotactl,
                   1200:        ntfs_statfs,
                   1201:        ntfs_sync,
                   1202:        ntfs_vget,
                   1203:        ntfs_fhtovp,
                   1204:        ntfs_vptofh,
                   1205:        ntfs_init,
                   1206:        ntfs_sysctl,
                   1207:        ntfs_checkexp,
                   1208: };
                   1209:
                   1210: #endif

CVSweb