The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ntfs/ntfs_vfsops.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ntfs_vfsops.c,v 1.2 1999/05/06 15:43:20 christos Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1998, 1999 Semen Ustimenko
    5  * 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.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  * $FreeBSD$
   29  */
   30 
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/namei.h>
   35 #include <sys/conf.h>
   36 #include <sys/proc.h>
   37 #include <sys/kernel.h>
   38 #include <sys/vnode.h>
   39 #include <sys/mount.h>
   40 #include <sys/buf.h>
   41 #include <sys/fcntl.h>
   42 #include <sys/malloc.h>
   43 
   44 #include <vm/vm.h>
   45 #include <vm/vm_param.h>
   46 #include <vm/vm_prot.h>
   47 #include <vm/vm_page.h>
   48 #include <vm/vm_object.h>
   49 #include <vm/vm_extern.h>
   50 
   51 #include <miscfs/specfs/specdev.h>
   52 
   53 /*#define NTFS_DEBUG 1*/
   54 #include <ntfs/ntfs.h>
   55 #include <ntfs/ntfs_inode.h>
   56 #include <ntfs/ntfs_subr.h>
   57 #include <ntfs/ntfs_vfsops.h>
   58 #include <ntfs/ntfs_ihash.h>
   59 #include <ntfs/ntfs_extern.h>
   60 #include <ntfs/ntfsmount.h>
   61 
   62 #if defined(__FreeBSD__)
   63 MALLOC_DEFINE(M_NTFSMNT, "NTFS mount", "NTFS mount structure");
   64 MALLOC_DEFINE(M_NTFSNTNODE,"NTFS ntnode",  "NTFS ntnode information");
   65 MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode",  "NTFS fnode information");
   66 MALLOC_DEFINE(M_NTFSDIR,"NTFS dir",  "NTFS dir buffer");
   67 #endif
   68 
   69 #if defined(__FreeBSD__)
   70 static int      ntfs_mount __P((struct mount *, char *, caddr_t,
   71                                 struct nameidata *, struct proc *));
   72 #else
   73 static int      ntfs_mount __P((struct mount *, const char *, void *,
   74                                 struct nameidata *, struct proc *));
   75 #endif
   76 static int      ntfs_quotactl __P((struct mount *, int, uid_t, caddr_t,
   77                                    struct proc *));
   78 static int      ntfs_root __P((struct mount *, struct vnode **));
   79 static int      ntfs_start __P((struct mount *, int, struct proc *));
   80 static int      ntfs_statfs __P((struct mount *, struct statfs *,
   81                                  struct proc *));
   82 static int      ntfs_sync __P((struct mount *, int, struct ucred *,
   83                                struct proc *));
   84 static int      ntfs_unmount __P((struct mount *, int, struct proc *));
   85 static int      ntfs_vget __P((struct mount *mp, ino_t ino,
   86                                struct vnode **vpp));
   87 static int      ntfs_mountfs __P((register struct vnode *, struct mount *, 
   88                                   struct ntfs_args *, struct proc *));
   89 static int      ntfs_vptofh __P((struct vnode *, struct fid *));
   90 
   91 #if defined(__FreeBSD__)
   92 static int      ntfs_init __P((struct vfsconf *));
   93 static int      ntfs_fhtovp __P((struct mount *, struct fid *,
   94                                  struct sockaddr *, struct vnode **,
   95                                  int *, struct ucred **));
   96 #elif defined(__NetBSD__)
   97 static void     ntfs_init __P((void));
   98 static int      ntfs_fhtovp __P((struct mount *, struct fid *,
   99                                  struct vnode **));
  100 static int      ntfs_checkexp __P((struct mount *, struct mbuf *,
  101                                    int *, struct ucred **));
  102 static int      ntfs_mountroot __P((void));
  103 static int      ntfs_sysctl __P((int *, u_int, void *, size_t *, void *,
  104                                  size_t, struct proc *));
  105 #else
  106 static int      ntfs_init __P((void));
  107 static int      ntfs_fhtovp __P((struct mount *, struct fid *,
  108                                  struct mbuf *, struct vnode **,
  109                                  int *, struct ucred **));
  110 #endif
  111 
  112 #ifdef __NetBSD__
  113 /*ARGSUSED*/
  114 static int
  115 ntfs_checkexp(mp, nam, exflagsp, credanonp)
  116         register struct mount *mp;
  117         struct mbuf *nam;
  118         int *exflagsp;
  119         struct ucred **credanonp;
  120 {
  121 
  122         return (EINVAL);
  123 }
  124 
  125 /*ARGSUSED*/
  126 static int
  127 ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
  128         int *name;
  129         u_int namelen;
  130         void *oldp;
  131         size_t *oldlenp;
  132         void *newp;
  133         size_t newlen;
  134         struct proc *p;
  135 {
  136         return (EINVAL);
  137 }
  138 
  139 static int
  140 ntfs_mountroot()
  141 {
  142         return (EINVAL);
  143 }
  144 #endif
  145 
  146 #if defined(__FreeBSD__)
  147 static int
  148 ntfs_init (
  149         struct vfsconf *vcp )
  150 #elif defined(__NetBSD__)
  151 static void
  152 ntfs_init ()
  153 #else
  154 static int
  155 ntfs_init ()
  156 #endif
  157 {
  158         ntfs_nthashinit();
  159 #if !defined(__NetBSD__)
  160         return 0;
  161 #endif
  162 }
  163 
  164 static int
  165 ntfs_mount ( 
  166         struct mount *mp,
  167 #if defined(__FreeBSD__)
  168         char *path,
  169         caddr_t data,
  170 #else
  171         const char *path,
  172         void *data,
  173 #endif
  174         struct nameidata *ndp,
  175         struct proc *p )
  176 {
  177         u_int           size;
  178         int             err = 0;
  179         struct vnode    *devvp;
  180         struct ntfs_args args;
  181 
  182         /*
  183          * Use NULL path to flag a root mount
  184          */
  185         if( path == NULL) {
  186                 /*
  187                  ***
  188                  * Mounting root file system
  189                  ***
  190                  */
  191         
  192                 /* Get vnode for root device*/
  193                 if( bdevvp( rootdev, &rootvp))
  194                         panic("ffs_mountroot: can't setup bdevvp for root");
  195 
  196                 /*
  197                  * FS specific handling
  198                  */
  199                 mp->mnt_flag |= MNT_RDONLY;     /* XXX globally applicable?*/
  200 
  201                 /*
  202                  * Attempt mount
  203                  */
  204                 if( ( err = ntfs_mountfs(rootvp, mp, &args, p)) != 0) {
  205                         /* fs specific cleanup (if any)*/
  206                         goto error_1;
  207                 }
  208 
  209                 goto dostatfs;          /* success*/
  210 
  211         }
  212 
  213         /*
  214          ***
  215          * Mounting non-root file system or updating a file system
  216          ***
  217          */
  218 
  219         /* copy in user arguments*/
  220         err = copyin(data, (caddr_t)&args, sizeof (struct ntfs_args));
  221         if (err)
  222                 goto error_1;           /* can't get arguments*/
  223 
  224         /*
  225          * If updating, check whether changing from read-only to
  226          * read/write; if there is no device name, that's all we do.
  227          */
  228         if (mp->mnt_flag & MNT_UPDATE) {
  229                 printf("ntfs_mount(): MNT_UPDATE not supported\n");
  230                 err = EINVAL;
  231                 goto error_1;
  232 
  233 #if 0
  234                 ump = VFSTOUFS(mp);
  235                 fs = ump->um_fs;
  236                 err = 0;
  237                 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
  238                         flags = WRITECLOSE;
  239                         if (mp->mnt_flag & MNT_FORCE)
  240                                 flags |= FORCECLOSE;
  241                         if (vfs_busy(mp)) {
  242                                 err = EBUSY;
  243                                 goto error_1;
  244                         }
  245                         err = ffs_flushfiles(mp, flags, p);
  246                         vfs_unbusy(mp);
  247                 }
  248                 if (!err && (mp->mnt_flag & MNT_RELOAD))
  249                         err = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
  250                 if (err) {
  251                         goto error_1;
  252                 }
  253                 if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
  254                         if (!fs->fs_clean) {
  255                                 if (mp->mnt_flag & MNT_FORCE) {
  256                                         printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt);
  257                                 } else {
  258                                         printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",
  259                                             fs->fs_fsmnt);
  260                                         err = EPERM;
  261                                         goto error_1;
  262                                 }
  263                         }
  264                         fs->fs_ronly = 0;
  265                 }
  266                 if (fs->fs_ronly == 0) {
  267                         fs->fs_clean = 0;
  268                         ffs_sbupdate(ump, MNT_WAIT);
  269                 }
  270                 /* if not updating name...*/
  271                 if (args.fspec == 0) {
  272                         /*
  273                          * Process export requests.  Jumping to "success"
  274                          * will return the vfs_export() error code.
  275                          */
  276                         err = vfs_export(mp, &ump->um_export, &args.export);
  277                         goto success;
  278                 }
  279 #endif
  280         }
  281 
  282         /*
  283          * Not an update, or updating the name: look up the name
  284          * and verify that it refers to a sensible block device.
  285          */
  286         NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
  287         err = namei(ndp);
  288         if (err) {
  289                 /* can't get devvp!*/
  290                 goto error_1;
  291         }
  292 
  293         devvp = ndp->ni_vp;
  294 
  295         if (devvp->v_type != VBLK) {
  296                 err = ENOTBLK;
  297                 goto error_2;
  298         }
  299         if (major(devvp->v_rdev) >= nblkdev) {
  300                 err = ENXIO;
  301                 goto error_2;
  302         }
  303         if (mp->mnt_flag & MNT_UPDATE) {
  304 #if 0
  305                 /*
  306                  ********************
  307                  * UPDATE
  308                  ********************
  309                  */
  310 
  311                 if (devvp != ntmp->um_devvp)
  312                         err = EINVAL;   /* needs translation */
  313                 else
  314                         vrele(devvp);
  315                 /*
  316                  * Update device name only on success
  317                  */
  318                 if( !err) {
  319                         /* Save "mounted from" info for mount point (NULL pad)*/
  320                         copyinstr(      args.fspec,
  321                                         mp->mnt_stat.f_mntfromname,
  322                                         MNAMELEN - 1,
  323                                         &size);
  324                         bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
  325                 }
  326 #endif
  327         } else {
  328                 /*
  329                  ********************
  330                  * NEW MOUNT
  331                  ********************
  332                  */
  333 
  334                 /*
  335                  * Since this is a new mount, we want the names for
  336                  * the device and the mount point copied in.  If an
  337                  * error occurs,  the mountpoint is discarded by the
  338                  * upper level code.
  339                  */
  340                 /* Save "last mounted on" info for mount point (NULL pad)*/
  341                 copyinstr(      path,                           /* mount point*/
  342                                 mp->mnt_stat.f_mntonname,       /* save area*/
  343                                 MNAMELEN - 1,                   /* max size*/
  344                                 &size);                         /* real size*/
  345                 bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
  346 
  347                 /* Save "mounted from" info for mount point (NULL pad)*/
  348                 copyinstr(      args.fspec,                     /* device name*/
  349                                 mp->mnt_stat.f_mntfromname,     /* save area*/
  350                                 MNAMELEN - 1,                   /* max size*/
  351                                 &size);                         /* real size*/
  352                 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
  353 
  354                 err = ntfs_mountfs(devvp, mp, &args, p);
  355         }
  356         if (err) {
  357                 goto error_2;
  358         }
  359 
  360 dostatfs:
  361         /*
  362          * Initialize FS stat information in mount struct; uses both
  363          * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
  364          *
  365          * This code is common to root and non-root mounts
  366          */
  367         (void)VFS_STATFS(mp, &mp->mnt_stat, p);
  368 
  369         goto success;
  370 
  371 
  372 error_2:        /* error with devvp held*/
  373 
  374         /* release devvp before failing*/
  375         vrele(devvp);
  376 
  377 error_1:        /* no state to back out*/
  378 
  379 success:
  380         return( err);
  381 }
  382 
  383 /*
  384  * Common code for mount and mountroot
  385  */
  386 int
  387 ntfs_mountfs(devvp, mp, argsp, p)
  388         register struct vnode *devvp;
  389         struct mount *mp;
  390         struct ntfs_args *argsp;
  391         struct proc *p;
  392 {
  393         struct buf *bp;
  394         struct ntfsmount *ntmp;
  395         dev_t dev = devvp->v_rdev;
  396         int error, ronly, ncount, i;
  397         struct vnode *vp;
  398 
  399         /*
  400          * Disallow multiple mounts of the same device.
  401          * Disallow mounting of a device that is currently in use
  402          * (except for root, which might share swap device for miniroot).
  403          * Flush out any old buffers remaining from a previous use.
  404          */
  405         error = vfs_mountedon(devvp);
  406         if (error)
  407                 return (error);
  408         ncount = vcount(devvp);
  409 #if defined(__FreeBSD__)
  410         if (devvp->v_object)
  411                 ncount -= 1;
  412 #endif
  413         if (ncount > 1 && devvp != rootvp)
  414                 return (EBUSY);
  415 #if defined(__FreeBSD__)
  416         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
  417         error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
  418         VOP_UNLOCK(devvp, 0, p);
  419 #else
  420         error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
  421 #endif
  422         if (error)
  423                 return (error);
  424 
  425         ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
  426         error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
  427         if (error)
  428                 return (error);
  429 
  430         bp = NULL;
  431 
  432         error = bread(devvp, BBLOCK, BBSIZE, NOCRED, &bp);
  433         if (error)
  434                 goto out;
  435         ntmp = malloc( sizeof *ntmp, M_NTFSMNT, M_WAITOK );
  436         bzero( ntmp, sizeof *ntmp );
  437         bcopy( bp->b_data, &ntmp->ntm_bootfile, sizeof(struct bootfile) );
  438         brelse( bp );
  439         bp = NULL;
  440 
  441         if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
  442                 error = EINVAL;
  443                 printf("ntfs_mountfs: invalid boot block\n");
  444                 goto out;
  445         }
  446 
  447         {
  448                 int8_t cpr = ntmp->ntm_mftrecsz;
  449                 if( cpr > 0 )
  450                         ntmp->ntm_bpmftrec = ntmp->ntm_spc * cpr;
  451                 else
  452                         ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;
  453         }
  454         dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
  455                 ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media,
  456                 ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec));
  457         dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
  458                 (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn));
  459 
  460         ntmp->ntm_mountp = mp;
  461         ntmp->ntm_dev = dev;
  462         ntmp->ntm_devvp = devvp;
  463         ntmp->ntm_uid = argsp->uid;
  464         ntmp->ntm_gid = argsp->gid;
  465         ntmp->ntm_mode = argsp->mode;
  466         ntmp->ntm_flag = argsp->flag;
  467         mp->mnt_data = (qaddr_t)ntmp;
  468 
  469         dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
  470                 (ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
  471                 (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
  472                 ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
  473 
  474         /*
  475          * We read in some system nodes to do not allow 
  476          * reclaim them and to have everytime access to them.
  477          */ 
  478         {
  479                 int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
  480                 for (i=0; i<3; i++) {
  481                         error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]]));
  482                         if(error)
  483                                 goto out1;
  484                         ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
  485                         VREF(ntmp->ntm_sysvn[pi[i]]);
  486                         vput(ntmp->ntm_sysvn[pi[i]]);
  487                 }
  488         }
  489 
  490         /*
  491          * Read in WHOLE lowcase -> upcase translation
  492          * file.
  493          */
  494         MALLOC(ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
  495                 M_NTFSMNT, M_WAITOK);
  496 
  497         error = VFS_VGET(mp, NTFS_UPCASEINO, &vp);
  498         if(error) 
  499                 goto out1;
  500         error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
  501                         0, 65536*sizeof(wchar), ntmp->ntm_upcase);
  502         vput(vp);
  503         if(error) 
  504                 goto out1;
  505 
  506         /*
  507          * Scan $BitMap and count free clusters
  508          */
  509         error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree);
  510         if(error)
  511                 goto out1;
  512 
  513         /*
  514          * Read and translate to internal format attribute
  515          * definition file. 
  516          */
  517         {
  518                 int num,j;
  519                 struct attrdef ad;
  520 
  521                 /* Open $AttrDef */
  522                 error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp );
  523                 if(error) 
  524                         goto out1;
  525 
  526                 /* Count valid entries */
  527                 for(num=0;;num++) {
  528                         error = ntfs_readattr(ntmp, VTONT(vp),
  529                                         NTFS_A_DATA, NULL,
  530                                         num * sizeof(ad), sizeof(ad),
  531                                         &ad);
  532                         if (error)
  533                                 goto out1;
  534                         if (ad.ad_name[0] == 0)
  535                                 break;
  536                 }
  537 
  538                 /* Alloc memory for attribute definitions */
  539                 MALLOC(ntmp->ntm_ad, struct ntvattrdef *,
  540                         num * sizeof(struct ntvattrdef),
  541                         M_NTFSMNT, M_WAITOK);
  542 
  543                 ntmp->ntm_adnum = num;
  544 
  545                 /* Read them and translate */
  546                 for(i=0;i<num;i++){
  547                         error = ntfs_readattr(ntmp, VTONT(vp),
  548                                         NTFS_A_DATA, NULL,
  549                                         i * sizeof(ad), sizeof(ad),
  550                                         &ad);
  551                         if (error)
  552                                 goto out1;
  553                         j = 0;
  554                         do {
  555                                 ntmp->ntm_ad[i].ad_name[j] = ad.ad_name[j];
  556                         } while(ad.ad_name[j++]);
  557                         ntmp->ntm_ad[i].ad_namelen = j - 1;
  558                         ntmp->ntm_ad[i].ad_type = ad.ad_type;
  559                 }
  560 
  561                 vput(vp);
  562         }
  563 
  564         mp->mnt_stat.f_fsid.val[0] = (long)dev;
  565 #if defined(__FreeBSD__)
  566         mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
  567 #else
  568         mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_NTFS);
  569 #endif
  570         mp->mnt_maxsymlinklen = 0;
  571         mp->mnt_flag |= MNT_LOCAL;
  572 #if defined(__FreeBSD__)
  573         devvp->v_specmountpoint = mp;
  574 #else
  575         devvp->v_specflags |= SI_MOUNTEDON;
  576 #endif
  577         return (0);
  578 
  579 out1:
  580         for(i=0;i<NTFS_SYSNODESNUM;i++)
  581                 if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
  582 
  583         if (vflush(mp,NULLVP,0))
  584                 printf("ntfs_mountfs: vflush failed\n");
  585 
  586 out:
  587 #if defined(__FreeBSD__)
  588         devvp->v_specmountpoint = NULL;
  589 #else
  590         devvp->v_specflags &= ~SI_MOUNTEDON;
  591 #endif
  592         if (bp)
  593                 brelse(bp);
  594         (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
  595         return (error);
  596 }
  597 
  598 static int
  599 ntfs_start (
  600         struct mount *mp,
  601         int flags,
  602         struct proc *p )
  603 {
  604         return (0);
  605 }
  606 
  607 static int
  608 ntfs_unmount( 
  609         struct mount *mp,
  610         int mntflags,
  611         struct proc *p)
  612 {
  613         register struct ntfsmount *ntmp;
  614         int error, ronly = 0, flags, i;
  615 
  616         dprintf(("ntfs_unmount: unmounting...\n"));
  617         ntmp = VFSTONTFS(mp);
  618 
  619         flags = 0;
  620         if(mntflags & MNT_FORCE)
  621                 flags |= FORCECLOSE;
  622 
  623         dprintf(("ntfs_unmount: vflushing...\n"));
  624         error = vflush(mp,NULLVP,flags | SKIPSYSTEM);
  625         if (error) {
  626                 printf("ntfs_unmount: vflush failed: %d\n",error);
  627                 return (error);
  628         }
  629 
  630         /* Check if only system vnodes are rest */
  631         for(i=0;i<NTFS_SYSNODESNUM;i++)
  632                  if((ntmp->ntm_sysvn[i]) && 
  633                     (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
  634 
  635         /* Derefernce all system vnodes */
  636         for(i=0;i<NTFS_SYSNODESNUM;i++)
  637                  if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
  638 
  639         /* vflush system vnodes */
  640         error = vflush(mp,NULLVP,flags);
  641         if (error)
  642                 printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
  643 
  644 #if defined(__FreeBSD__)
  645         ntmp->ntm_devvp->v_specmountpoint = NULL;
  646 #else
  647         ntmp->ntm_devvp->v_specflags &= ~SI_MOUNTEDON;
  648 #endif
  649 
  650         vinvalbuf(ntmp->ntm_devvp, V_SAVE, NOCRED, p, 0, 0);
  651         error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
  652                 NOCRED, p);
  653 
  654         vrele(ntmp->ntm_devvp);
  655 
  656         dprintf(("ntfs_umount: freeing memory...\n"));
  657         mp->mnt_data = (qaddr_t)0;
  658         mp->mnt_flag &= ~MNT_LOCAL;
  659         FREE(ntmp->ntm_ad, M_NTFSMNT);
  660         FREE(ntmp->ntm_upcase, M_NTFSMNT);
  661         FREE(ntmp, M_NTFSMNT);
  662         return (error);
  663 }
  664 
  665 static int
  666 ntfs_root(
  667         struct mount *mp,
  668         struct vnode **vpp )
  669 {
  670         struct vnode *nvp;
  671         int error = 0;
  672 
  673         dprintf(("ntfs_root(): sysvn: %p\n",
  674                 VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
  675         error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp);
  676         if(error) {
  677                 printf("ntfs_root: VFS_VGET failed: %d\n",error);
  678                 return (error);
  679         }
  680 
  681         *vpp = nvp;
  682         return (0);
  683 }
  684 
  685 static int
  686 ntfs_quotactl ( 
  687         struct mount *mp,
  688         int cmds,
  689         uid_t uid,
  690         caddr_t arg,
  691         struct proc *p)
  692 {
  693         printf("\nntfs_quotactl():\n");
  694         return EOPNOTSUPP;
  695 }
  696 
  697 int
  698 ntfs_calccfree(
  699         struct ntfsmount *ntmp,
  700         cn_t *cfreep)
  701 {
  702         struct vnode *vp;
  703         u_int8_t *tmp;
  704         int j, error;
  705         long cfree = 0;
  706         size_t bmsize, i;
  707 
  708         vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
  709 
  710         bmsize = VTOF(vp)->f_size;
  711 
  712         MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
  713 
  714         error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
  715                                0, bmsize, tmp);
  716         if(error) {
  717                 FREE(tmp, M_TEMP);
  718                 return (error);
  719         }
  720 
  721         for(i=0;i<bmsize;i++)
  722                 for(j=0;j<8;j++)
  723                         if(~tmp[i] & (1 << j)) cfree++;
  724 
  725         FREE(tmp, M_TEMP);
  726 
  727         *cfreep = cfree;
  728 
  729         return(0);
  730 }
  731 
  732 static int
  733 ntfs_statfs(
  734         struct mount *mp,
  735         struct statfs *sbp,
  736         struct proc *p)
  737 {
  738         struct ntfsmount *ntmp = VFSTONTFS(mp);
  739         u_int64_t mftsize,mftallocated;
  740 
  741         dprintf(("ntfs_statfs():\n"));
  742 
  743         mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size;
  744         mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated;
  745 
  746 #if defined(__FreeBSD__)
  747         sbp->f_type = mp->mnt_vfc->vfc_typenum;
  748 #elif defined(__NetBSD__)
  749         sbp->f_type = 0;
  750 #else
  751         sbp->f_type = MOUNT_NTFS;
  752 #endif
  753         sbp->f_bsize = ntmp->ntm_bps;
  754         sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc;
  755         sbp->f_blocks = ntmp->ntm_bootfile.bf_spv;
  756         sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree);
  757         sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec;
  758         sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) +
  759                        sbp->f_ffree;
  760         if (sbp != &mp->mnt_stat) {
  761                 bcopy((caddr_t)mp->mnt_stat.f_mntonname,
  762                         (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
  763                 bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
  764                         (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
  765         }
  766         sbp->f_flags = mp->mnt_flag;
  767         
  768         return (0);
  769 }
  770 
  771 static int
  772 ntfs_sync (
  773         struct mount *mp,
  774         int waitfor,
  775         struct ucred *cred,
  776         struct proc *p)
  777 {
  778         /*dprintf(("ntfs_sync():\n"));*/
  779         return (0);
  780 }
  781 
  782 /*ARGSUSED*/
  783 static int
  784 ntfs_fhtovp(
  785 #if defined(__FreeBSD__)
  786         struct mount *mp,
  787         struct fid *fhp,
  788         struct sockaddr *nam,
  789         struct vnode **vpp,
  790         int *exflagsp,
  791         struct ucred **credanonp)
  792 #elif defined(__NetBSD__)
  793         struct mount *mp,
  794         struct fid *fhp,
  795         struct vnode **vpp)
  796 #else
  797         struct mount *mp,
  798         struct fid *fhp,
  799         struct mbuf *nam,
  800         struct vnode **vpp,
  801         int *exflagsp,
  802         struct ucred **credanonp)
  803 #endif
  804 {
  805         printf("\ntfs_fhtovp():\n");
  806         return 0;
  807 }
  808 
  809 static int
  810 ntfs_vptofh(
  811         struct vnode *vp,
  812         struct fid *fhp)
  813 {
  814         printf("ntfs_vptofh():\n");
  815         return EOPNOTSUPP;
  816 }
  817 
  818 int
  819 ntfs_vgetex(
  820         struct mount *mp,
  821         ino_t ino,
  822         u_int32_t attrtype,
  823         char *attrname,
  824         u_long lkflags,
  825         u_long flags,
  826         struct proc *p,
  827         struct vnode **vpp) 
  828 {
  829         int error;
  830         register struct ntfsmount *ntmp;
  831         struct ntnode *ip;
  832         struct fnode *fp;
  833         struct vnode *vp;
  834 
  835         dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%x, f: 0x%x\n",
  836                 ino, attrtype, attrname?attrname:"", lkflags, flags ));
  837 
  838         ntmp = VFSTONTFS(mp);
  839         *vpp = NULL;
  840 
  841         /* Get ntnode */
  842         error = ntfs_ntlookup(ntmp, ino, &ip);
  843         if (error) {
  844                 printf("ntfs_vget: ntfs_ntget failed\n");
  845                 return (error);
  846         }
  847 
  848         /* It may be not initialized fully, so force load it */
  849         if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) {
  850                 error = ntfs_loadntnode(ntmp, ip);
  851                 if(error) {
  852                         printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
  853                                ip->i_number);
  854                         ntfs_ntput(ip);
  855                         return (error);
  856                 }
  857         }
  858 
  859         error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
  860         if (error) {
  861                 printf("ntfs_vget: ntfs_fget failed\n");
  862                 ntfs_ntput(ip);
  863                 return (error);
  864         }
  865 
  866         if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
  867                 if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
  868                     (fp->f_attrtype == 0x80 && fp->f_attrname == NULL)) {
  869                         fp->f_type = VDIR;
  870                 } else if(flags & VG_EXT) {
  871                         fp->f_type = VNON;
  872 
  873                         fp->f_size =fp->f_allocated = 0;
  874                 } else {
  875                         fp->f_type = VREG;      
  876 
  877                         error = ntfs_filesize(ntmp, fp, 
  878                                               &fp->f_size, &fp->f_allocated);
  879                         if (error) {
  880                                 ntfs_ntput(ip);
  881                                 return (error);
  882                         }
  883                 }
  884 
  885                 fp->f_flag |= FN_VALID;
  886         }
  887 
  888         if (FTOV(fp)) {
  889                 VGET(FTOV(fp), lkflags, p);
  890                 *vpp = FTOV(fp);
  891                 ntfs_ntput(ip);
  892                 return (0);
  893         }
  894 
  895         error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
  896         if(error) {
  897                 ntfs_frele(fp);
  898                 ntfs_ntput(ip);
  899                 return (error);
  900         }
  901         dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
  902 
  903         lockinit(&fp->f_lock, PINOD, "fnode", 0, 0);
  904         fp->f_vp = vp;
  905         vp->v_data = fp;
  906         vp->v_type = fp->f_type;
  907 
  908         if (ino == NTFS_ROOTINO)
  909                 vp->v_flag |= VROOT;
  910 
  911         ntfs_ntput(ip);
  912 
  913         if (lkflags & LK_TYPE_MASK) {
  914                 error = VN_LOCK(vp, lkflags, p);
  915                 if (error) {
  916                         vput(vp);
  917                         return (error);
  918                 }
  919         }
  920 
  921         VREF(fp->f_devvp);
  922         *vpp = vp;
  923         return (0);
  924         
  925 }
  926 
  927 static int
  928 ntfs_vget(
  929         struct mount *mp,
  930         ino_t ino,
  931         struct vnode **vpp) 
  932 {
  933         return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
  934                            LK_EXCLUSIVE, 0, curproc, vpp);
  935 }
  936 
  937 #if defined(__FreeBSD__)
  938 static struct vfsops ntfs_vfsops = {
  939         ntfs_mount,
  940         ntfs_start,
  941         ntfs_unmount,
  942         ntfs_root,
  943         ntfs_quotactl,
  944         ntfs_statfs,
  945         ntfs_sync,
  946         ntfs_vget,
  947         ntfs_fhtovp,
  948         ntfs_vptofh,
  949         ntfs_init,
  950         NULL
  951 };
  952 VFS_SET(ntfs_vfsops, ntfs, 0);
  953 #elif defined(__NetBSD__)
  954 extern struct vnodeopv_desc ntfs_vnodeop_opv_desc;
  955 
  956 struct vnodeopv_desc *ntfs_vnodeopv_descs[] = {
  957         &ntfs_vnodeop_opv_desc,
  958         NULL,
  959 };
  960 
  961 struct vfsops ntfs_vfsops = {
  962         MOUNT_NTFS,
  963         ntfs_mount,
  964         ntfs_start,
  965         ntfs_unmount,
  966         ntfs_root,
  967         ntfs_quotactl,
  968         ntfs_statfs,
  969         ntfs_sync,
  970         ntfs_vget,
  971         ntfs_fhtovp,
  972         ntfs_vptofh,
  973         ntfs_init,
  974         ntfs_sysctl,
  975         ntfs_mountroot,
  976         ntfs_checkexp,
  977         ntfs_vnodeopv_descs,
  978 };
  979 #else
  980 static struct vfsops ntfs_vfsops = {
  981         ntfs_mount,
  982         ntfs_start,
  983         ntfs_unmount,
  984         ntfs_root,
  985         ntfs_quotactl,
  986         ntfs_statfs,
  987         ntfs_sync,
  988         ntfs_vget,
  989         ntfs_fhtovp,
  990         ntfs_vptofh,
  991         ntfs_init,
  992 };
  993 VFS_SET(ntfs_vfsops, ntfs, MOUNT_NTFS, 0);
  994 #endif
  995 
  996 

Cache object: af7da1ced09ea313030187a578ce585d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.