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/fs/hpfs/hpfs_vnops.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 /*-
    2  * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/kernel.h>
   32 #include <sys/proc.h>
   33 #include <sys/time.h>
   34 #include <sys/types.h>
   35 #include <sys/stat.h>
   36 #include <sys/vnode.h>
   37 #include <sys/mount.h>
   38 #include <sys/namei.h>
   39 #include <sys/malloc.h>
   40 #include <sys/bio.h>
   41 #include <sys/buf.h>
   42 #include <sys/dirent.h>
   43 
   44 #include <vm/vm.h>
   45 #include <vm/vm_param.h>
   46 #include <vm/vm_page.h>
   47 #include <vm/vm_object.h>
   48 #include <vm/vm_pager.h>
   49 #include <vm/vnode_pager.h>
   50 #include <vm/vm_extern.h>
   51 
   52 #include <sys/unistd.h> /* for pathconf(2) constants */
   53 
   54 #include <fs/hpfs/hpfs.h>
   55 #include <fs/hpfs/hpfsmount.h>
   56 #include <fs/hpfs/hpfs_subr.h>
   57 #include <fs/hpfs/hpfs_ioctl.h>
   58 
   59 static int      hpfs_de_uiomove(struct hpfsmount *, struct hpfsdirent *,
   60                                      struct uio *);
   61 static int      hpfs_ioctl(struct vop_ioctl_args *ap);
   62 static int      hpfs_read(struct vop_read_args *);
   63 static int      hpfs_write(struct vop_write_args *ap);
   64 static int      hpfs_getattr(struct vop_getattr_args *ap);
   65 static int      hpfs_setattr(struct vop_setattr_args *ap);
   66 static int      hpfs_inactive(struct vop_inactive_args *ap);
   67 static int      hpfs_print(struct vop_print_args *ap);
   68 static int      hpfs_reclaim(struct vop_reclaim_args *ap);
   69 static int      hpfs_strategy(struct vop_strategy_args *ap);
   70 static int      hpfs_access(struct vop_access_args *ap);
   71 static int      hpfs_open(struct vop_open_args *ap);
   72 static int      hpfs_close(struct vop_close_args *ap);
   73 static int      hpfs_readdir(struct vop_readdir_args *ap);
   74 static int      hpfs_lookup(struct vop_lookup_args *ap);
   75 static int      hpfs_create(struct vop_create_args *);
   76 static int      hpfs_remove(struct vop_remove_args *);
   77 static int      hpfs_bmap(struct vop_bmap_args *ap);
   78 static int      hpfs_fsync(struct vop_fsync_args *ap);
   79 static int      hpfs_pathconf(struct vop_pathconf_args *ap);
   80 
   81 static int
   82 hpfs_fsync(ap)
   83         struct vop_fsync_args /* {
   84                 struct vnode *a_vp;
   85                 struct ucred *a_cred;
   86                 int a_waitfor;
   87                 struct thread *a_td;
   88         } */ *ap;
   89 {
   90         /*
   91          * Flush our dirty buffers.
   92          */
   93         vop_stdfsync(ap);
   94 
   95         /*
   96          * Write out the on-disc version of the vnode.
   97          */
   98         return hpfs_update(VTOHP(ap->a_vp));
   99 }
  100 
  101 static int
  102 hpfs_ioctl (
  103         struct vop_ioctl_args /* {
  104                 struct vnode *a_vp;
  105                 u_long a_command;
  106                 caddr_t a_data;
  107                 int a_fflag;
  108                 struct ucred *a_cred;
  109                 struct thread *a_td;
  110         } */ *ap)
  111 {
  112         register struct vnode *vp = ap->a_vp;
  113         register struct hpfsnode *hp = VTOHP(vp);
  114         int error;
  115 
  116         printf("hpfs_ioctl(0x%x, 0x%lx, 0x%p, 0x%x): ",
  117                 hp->h_no, ap->a_command, ap->a_data, ap->a_fflag);
  118 
  119         switch (ap->a_command) {
  120         case HPFSIOCGEANUM: {
  121                 u_long eanum;
  122                 u_long passed;
  123                 struct ea *eap;
  124 
  125                 eanum = 0;
  126 
  127                 if (hp->h_fn.fn_ealen > 0) {
  128                         eap = (struct ea *)&(hp->h_fn.fn_int);
  129                         passed = 0;
  130 
  131                         while (passed < hp->h_fn.fn_ealen) {
  132 
  133                                 printf("EAname: %s\n", EA_NAME(eap));
  134 
  135                                 eanum++;
  136                                 passed += sizeof(struct ea) +
  137                                           eap->ea_namelen + 1 + eap->ea_vallen;
  138                                 eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
  139                                                 passed);
  140                         }
  141                         error = 0;
  142                 } else {
  143                         error = ENOENT;
  144                 }
  145 
  146                 printf("%lu eas\n", eanum);
  147 
  148                 *(u_long *)ap->a_data = eanum;
  149 
  150                 break;
  151         }
  152         case HPFSIOCGEASZ: {
  153                 u_long eanum;
  154                 u_long passed;
  155                 struct ea *eap;
  156 
  157                 printf("EA%ld\n", *(u_long *)ap->a_data);
  158 
  159                 eanum = 0;
  160                 if (hp->h_fn.fn_ealen > 0) {
  161                         eap = (struct ea *)&(hp->h_fn.fn_int);
  162                         passed = 0;
  163 
  164                         error = ENOENT;
  165                         while (passed < hp->h_fn.fn_ealen) {
  166                                 printf("EAname: %s\n", EA_NAME(eap));
  167 
  168                                 if (eanum == *(u_long *)ap->a_data) {
  169                                         *(u_long *)ap->a_data =
  170                                                 eap->ea_namelen + 1 +
  171                                                 eap->ea_vallen;
  172 
  173                                         error = 0;
  174                                         break;
  175                                 }
  176 
  177                                 eanum++;
  178                                 passed += sizeof(struct ea) +
  179                                           eap->ea_namelen + 1 + eap->ea_vallen;
  180                                 eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
  181                                                 passed);
  182                         }
  183                 } else {
  184                         error = ENOENT;
  185                 }
  186 
  187                 break;
  188         }
  189         case HPFSIOCRDEA: {
  190                 u_long eanum;
  191                 u_long passed;
  192                 struct hpfs_rdea *rdeap;
  193                 struct ea *eap;
  194 
  195                 rdeap = (struct hpfs_rdea *)ap->a_data;
  196                 printf("EA%ld\n", rdeap->ea_no);
  197 
  198                 eanum = 0;
  199                 if (hp->h_fn.fn_ealen > 0) {
  200                         eap = (struct ea *)&(hp->h_fn.fn_int);
  201                         passed = 0;
  202 
  203                         error = ENOENT;
  204                         while (passed < hp->h_fn.fn_ealen) {
  205                                 printf("EAname: %s\n", EA_NAME(eap));
  206 
  207                                 if (eanum == rdeap->ea_no) {
  208                                         rdeap->ea_sz = eap->ea_namelen + 1 +
  209                                                         eap->ea_vallen;
  210                                         copyout(EA_NAME(eap),rdeap->ea_data,
  211                                                 rdeap->ea_sz);
  212                                         error = 0;
  213                                         break;
  214                                 }
  215 
  216                                 eanum++;
  217                                 passed += sizeof(struct ea) +
  218                                           eap->ea_namelen + 1 + eap->ea_vallen;
  219                                 eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
  220                                                 passed);
  221                         }
  222                 } else {
  223                         error = ENOENT;
  224                 }
  225 
  226                 break;
  227         }
  228         default:
  229                 error = ENOTTY;
  230                 break;
  231         }
  232         return (error);
  233 }
  234 
  235 /*
  236  * Map file offset to disk offset.
  237  */
  238 int
  239 hpfs_bmap(ap)
  240         struct vop_bmap_args /* {
  241                 struct vnode *a_vp;
  242                 daddr_t  a_bn;
  243                 struct vnode **a_vpp;
  244                 daddr_t *a_bnp;
  245                 int *a_runp;
  246                 int *a_runb;
  247         } */ *ap;
  248 {
  249         register struct hpfsnode *hp = VTOHP(ap->a_vp);
  250         daddr_t blkno;
  251         int error;
  252 
  253         if (ap->a_vpp != NULL) 
  254                 *ap->a_vpp = hp->h_devvp;
  255         if (ap->a_runb != NULL)
  256                 *ap->a_runb = 0;
  257         if (ap->a_bnp == NULL)
  258                 return (0);
  259 
  260         dprintf(("hpfs_bmap(0x%x, 0x%x): ",hp->h_no, ap->a_bn));
  261 
  262         error = hpfs_hpbmap (hp, ap->a_bn, &blkno, ap->a_runp);
  263         *ap->a_bnp = blkno;
  264 
  265         return (error);
  266 }
  267 
  268 static int
  269 hpfs_read(ap)
  270         struct vop_read_args /* {
  271                 struct vnode *a_vp;
  272                 struct uio *a_uio;
  273                 int a_ioflag;
  274                 struct ucred *a_cred;
  275         } */ *ap;
  276 {
  277         register struct vnode *vp = ap->a_vp;
  278         register struct hpfsnode *hp = VTOHP(vp);
  279         struct uio *uio = ap->a_uio;
  280         struct buf *bp;
  281         u_int xfersz, toread;
  282         u_int off;
  283         daddr_t lbn, bn;
  284         int resid;
  285         int runl;
  286         int error = 0;
  287 
  288         resid = min (uio->uio_resid, hp->h_fn.fn_size - uio->uio_offset);
  289 
  290         dprintf(("hpfs_read(0x%x, off: %d resid: %d, segflg: %d): [resid: 0x%x]\n",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg, resid));
  291 
  292         while (resid) {
  293                 lbn = uio->uio_offset >> DEV_BSHIFT;
  294                 off = uio->uio_offset & (DEV_BSIZE - 1);
  295                 dprintf(("hpfs_read: resid: 0x%x lbn: 0x%x off: 0x%x\n",
  296                         uio->uio_resid, lbn, off));
  297                 error = hpfs_hpbmap(hp, lbn, &bn, &runl);
  298                 if (error)
  299                         return (error);
  300 
  301                 toread = min(off + resid, min(DFLTPHYS, (runl+1)*DEV_BSIZE));
  302                 xfersz = (toread + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
  303                 dprintf(("hpfs_read: bn: 0x%x (0x%x) toread: 0x%x (0x%x)\n",
  304                         bn, runl, toread, xfersz));
  305 
  306                 if (toread == 0) 
  307                         break;
  308 
  309                 error = bread(hp->h_devvp, bn, xfersz, NOCRED, &bp);
  310                 if (error) {
  311                         brelse(bp);
  312                         break;
  313                 }
  314 
  315                 error = uiomove(bp->b_data + off, toread - off, uio);
  316                 if(error) {
  317                         brelse(bp);
  318                         break;
  319                 }
  320                 brelse(bp);
  321                 resid -= toread;
  322         }
  323         dprintf(("hpfs_read: successful\n"));
  324         return (error);
  325 }
  326 
  327 static int
  328 hpfs_write(ap)
  329         struct vop_write_args /* {
  330                 struct vnode *a_vp;
  331                 struct uio *a_uio;
  332                 int  a_ioflag;
  333                 struct ucred *a_cred;
  334         } */ *ap;
  335 {
  336         register struct vnode *vp = ap->a_vp;
  337         register struct hpfsnode *hp = VTOHP(vp);
  338         struct uio *uio = ap->a_uio;
  339         struct buf *bp;
  340         u_int xfersz, towrite;
  341         u_int off;
  342         daddr_t lbn, bn;
  343         int runl;
  344         int error = 0;
  345 
  346         dprintf(("hpfs_write(0x%x, off: %d resid: %d, segflg: %d):\n",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg));
  347 
  348         if (ap->a_ioflag & IO_APPEND) {
  349                 dprintf(("hpfs_write: APPEND mode\n"));
  350                 uio->uio_offset = hp->h_fn.fn_size;
  351         }
  352         if (uio->uio_offset + uio->uio_resid > hp->h_fn.fn_size) {
  353                 error = hpfs_extend (hp, uio->uio_offset + uio->uio_resid);
  354                 if (error) {
  355                         printf("hpfs_write: hpfs_extend FAILED %d\n", error);
  356                         return (error);
  357                 }
  358         }
  359 
  360         while (uio->uio_resid) {
  361                 lbn = uio->uio_offset >> DEV_BSHIFT;
  362                 off = uio->uio_offset & (DEV_BSIZE - 1);
  363                 dprintf(("hpfs_write: resid: 0x%x lbn: 0x%x off: 0x%x\n",
  364                         uio->uio_resid, lbn, off));
  365                 error = hpfs_hpbmap(hp, lbn, &bn, &runl);
  366                 if (error)
  367                         return (error);
  368 
  369                 towrite = min(off + uio->uio_resid, min(DFLTPHYS, (runl+1)*DEV_BSIZE));
  370                 xfersz = (towrite + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
  371                 dprintf(("hpfs_write: bn: 0x%x (0x%x) towrite: 0x%x (0x%x)\n",
  372                         bn, runl, towrite, xfersz));
  373 
  374                 if ((off == 0) && (towrite == xfersz)) {
  375                         bp = getblk(hp->h_devvp, bn, xfersz, 0, 0, 0);
  376                         clrbuf(bp);
  377                 } else {
  378                         error = bread(hp->h_devvp, bn, xfersz, NOCRED, &bp);
  379                         if (error) {
  380                                 brelse(bp);
  381                                 return (error);
  382                         }
  383                 }
  384 
  385                 error = uiomove(bp->b_data + off, towrite - off, uio);
  386                 if(error) {
  387                         brelse(bp);
  388                         return (error);
  389                 }
  390 
  391                 if (ap->a_ioflag & IO_SYNC)
  392                         bwrite(bp);
  393                 else
  394                         bawrite(bp);
  395         }
  396 
  397         dprintf(("hpfs_write: successful\n"));
  398         return (0);
  399 }
  400 
  401 /*
  402  * XXXXX do we need hpfsnode locking inside?
  403  */
  404 static int
  405 hpfs_getattr(ap)
  406         struct vop_getattr_args /* {
  407                 struct vnode *a_vp;
  408                 struct vattr *a_vap;
  409                 struct ucred *a_cred;
  410                 struct thread *a_td;
  411         } */ *ap;
  412 {
  413         register struct vnode *vp = ap->a_vp;
  414         register struct hpfsnode *hp = VTOHP(vp);
  415         register struct vattr *vap = ap->a_vap;
  416         int error;
  417 
  418         dprintf(("hpfs_getattr(0x%x):\n", hp->h_no));
  419 
  420         vap->va_fsid = dev2udev(hp->h_dev);
  421         vap->va_fileid = hp->h_no;
  422         vap->va_mode = hp->h_mode;
  423         vap->va_nlink = 1;
  424         vap->va_uid = hp->h_uid;
  425         vap->va_gid = hp->h_gid;
  426         vap->va_rdev = 0;                               /* XXX UNODEV ? */
  427         vap->va_size = hp->h_fn.fn_size;
  428         vap->va_bytes = ((hp->h_fn.fn_size + DEV_BSIZE-1) & ~(DEV_BSIZE-1)) +
  429                         DEV_BSIZE;
  430 
  431         if (!(hp->h_flag & H_PARVALID)) {
  432                 error = hpfs_validateparent(hp);
  433                 if (error) 
  434                         return (error);
  435         }
  436         vap->va_atime = hpfstimetounix(hp->h_atime);
  437         vap->va_mtime = hpfstimetounix(hp->h_mtime);
  438         vap->va_ctime = hpfstimetounix(hp->h_ctime);
  439 
  440         vap->va_flags = 0;
  441         vap->va_gen = 0;
  442         vap->va_blocksize = DEV_BSIZE;
  443         vap->va_type = vp->v_type;
  444         vap->va_filerev = 0;
  445 
  446         return (0);
  447 }
  448 
  449 /*
  450  * XXXXX do we need hpfsnode locking inside?
  451  */
  452 static int
  453 hpfs_setattr(ap)
  454         struct vop_setattr_args /* {
  455                 struct vnode *a_vp;
  456                 struct vattr *a_vap;
  457                 struct ucred *a_cred;
  458                 struct thread *a_td;
  459         } */ *ap;
  460 {
  461         struct vnode *vp = ap->a_vp;
  462         struct hpfsnode *hp = VTOHP(vp);
  463         struct vattr *vap = ap->a_vap;
  464         struct ucred *cred = ap->a_cred;
  465         struct thread *td = ap->a_td;
  466         int error;
  467 
  468         dprintf(("hpfs_setattr(0x%x):\n", hp->h_no));
  469 
  470         /*
  471          * Check for unsettable attributes.
  472          */
  473         if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
  474             (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
  475             (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
  476             (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
  477                 dprintf(("hpfs_setattr: changing nonsettable attr\n"));
  478                 return (EINVAL);
  479         }
  480 
  481         /* Can't change flags XXX Could be implemented */
  482         if (vap->va_flags != VNOVAL) {
  483                 printf("hpfs_setattr: FLAGS CANNOT BE SET\n");
  484                 return (EINVAL);
  485         }
  486 
  487         /* Can't change uid/gid XXX Could be implemented */
  488         if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
  489                 printf("hpfs_setattr: UID/GID CANNOT BE SET\n");
  490                 return (EINVAL);
  491         }
  492 
  493         /* Can't change mode XXX Could be implemented */
  494         if (vap->va_mode != (mode_t)VNOVAL) {
  495                 printf("hpfs_setattr: MODE CANNOT BE SET\n");
  496                 return (EINVAL);
  497         }
  498 
  499         /* Update times */
  500         if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
  501                 if (vp->v_mount->mnt_flag & MNT_RDONLY)
  502                         return (EROFS);
  503                 if (cred->cr_uid != hp->h_uid &&
  504                     (error = suser_cred(cred, SUSER_ALLOWJAIL)) &&
  505                     ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
  506                     (error = VOP_ACCESS(vp, VWRITE, cred, td))))
  507                         return (error);
  508                 if (vap->va_atime.tv_sec != VNOVAL)
  509                         hp->h_atime = vap->va_atime.tv_sec;
  510                 if (vap->va_mtime.tv_sec != VNOVAL)
  511                         hp->h_mtime = vap->va_mtime.tv_sec;
  512 
  513                 hp->h_flag |= H_PARCHANGE;
  514         }
  515 
  516         if (vap->va_size != VNOVAL) {
  517                 switch (vp->v_type) {
  518                 case VDIR:
  519                         return (EISDIR);
  520                 case VREG:
  521                         if (vp->v_mount->mnt_flag & MNT_RDONLY)
  522                                 return (EROFS);
  523                         break;
  524                 default:
  525                         printf("hpfs_setattr: WRONG v_type\n");
  526                         return (EINVAL);
  527                 }
  528 
  529                 if (vap->va_size < hp->h_fn.fn_size) {
  530                         error = vtruncbuf(vp, cred, td, vap->va_size, DEV_BSIZE);
  531                         if (error)
  532                                 return (error);
  533                         error = hpfs_truncate(hp, vap->va_size);
  534                         if (error)
  535                                 return (error);
  536 
  537                 } else if (vap->va_size > hp->h_fn.fn_size) {
  538                         vnode_pager_setsize(vp, vap->va_size);
  539                         error = hpfs_extend(hp, vap->va_size);
  540                         if (error)
  541                                 return (error);
  542                 }
  543         }
  544 
  545         return (0);
  546 }
  547 
  548 /*
  549  * Last reference to a node.  If necessary, write or delete it.
  550  */
  551 int
  552 hpfs_inactive(ap)
  553         struct vop_inactive_args /* {
  554                 struct vnode *a_vp;
  555         } */ *ap;
  556 {
  557         register struct vnode *vp = ap->a_vp;
  558         register struct hpfsnode *hp = VTOHP(vp);
  559         int error;
  560 
  561         dprintf(("hpfs_inactive(0x%x): \n", hp->h_no));
  562 
  563         if (hp->h_flag & H_CHANGE) {
  564                 dprintf(("hpfs_inactive: node changed, update\n"));
  565                 error = hpfs_update (hp);
  566                 if (error)
  567                         return (error);
  568         }
  569 
  570         if (hp->h_flag & H_PARCHANGE) {
  571                 dprintf(("hpfs_inactive: parent node changed, update\n"));
  572                 error = hpfs_updateparent (hp);
  573                 if (error)
  574                         return (error);
  575         }
  576 
  577         if (prtactive && vrefcnt(vp) != 0)
  578                 vprint("hpfs_inactive: pushing active", vp);
  579 
  580         if (hp->h_flag & H_INVAL) {
  581                 VOP_UNLOCK(vp,0,ap->a_td);
  582                 vrecycle(vp, NULL, ap->a_td);
  583                 return (0);
  584         }
  585 
  586         VOP_UNLOCK(vp,0,ap->a_td);
  587         return (0);
  588 }
  589 
  590 /*
  591  * Reclaim an inode so that it can be used for other purposes.
  592  */
  593 int
  594 hpfs_reclaim(ap)
  595         struct vop_reclaim_args /* {
  596                 struct vnode *a_vp;
  597         } */ *ap;
  598 {
  599         register struct vnode *vp = ap->a_vp;
  600         register struct hpfsnode *hp = VTOHP(vp);
  601 
  602         dprintf(("hpfs_reclaim(0x%x0): \n", hp->h_no));
  603 
  604         hpfs_hphashrem(hp);
  605 
  606         /* Purge old data structures associated with the inode. */
  607         if (hp->h_devvp) {
  608                 vrele(hp->h_devvp);
  609                 hp->h_devvp = NULL;
  610         }
  611 
  612         mtx_destroy(&hp->h_interlock);
  613 
  614         vp->v_data = NULL;
  615 
  616         FREE(hp, M_HPFSNO);
  617 
  618         return (0);
  619 }
  620 
  621 static int
  622 hpfs_print(ap)
  623         struct vop_print_args /* {
  624                 struct vnode *a_vp;
  625         } */ *ap;
  626 {
  627         register struct vnode *vp = ap->a_vp;
  628         register struct hpfsnode *hp = VTOHP(vp);
  629 
  630         printf("\tino 0x%x\n", hp->h_no);
  631         return (0);
  632 }
  633 
  634 /*
  635  * Calculate the logical to physical mapping if not done already,
  636  * then call the device strategy routine.
  637  *
  638  * In order to be able to swap to a file, the hpfs_hpbmap operation may not
  639  * deadlock on memory.  See hpfs_bmap() for details. XXXXXXX (not impl)
  640  */
  641 int
  642 hpfs_strategy(ap)
  643         struct vop_strategy_args /* {
  644                 struct buf *a_bp;
  645         } */ *ap;
  646 {
  647         register struct buf *bp = ap->a_bp;
  648         register struct vnode *vp = ap->a_vp;
  649         register struct hpfsnode *hp = VTOHP(ap->a_vp);
  650         daddr_t blkno;
  651         int error;
  652 
  653         KASSERT(ap->a_vp == ap->a_bp->b_vp, ("%s(%p != %p)",
  654             __func__, ap->a_vp, ap->a_bp->b_vp));
  655         dprintf(("hpfs_strategy(): \n"));
  656 
  657         if (vp->v_type == VBLK || vp->v_type == VCHR)
  658                 panic("hpfs_strategy: spec");
  659         if (bp->b_blkno == bp->b_lblkno) {
  660                 error = hpfs_hpbmap (hp, bp->b_lblkno, &blkno, NULL);
  661                 bp->b_blkno = blkno;
  662                 if (error) {
  663                         printf("hpfs_strategy: hpfs_bpbmap FAILED %d\n", error);
  664                         bp->b_error = error;
  665                         bp->b_ioflags |= BIO_ERROR;
  666                         bufdone(bp);
  667                         return (error);
  668                 }
  669                 if ((long)bp->b_blkno == -1)
  670                         vfs_bio_clrbuf(bp);
  671         }
  672         if ((long)bp->b_blkno == -1) {
  673                 bufdone(bp);
  674                 return (0);
  675         }
  676         bp->b_dev = hp->h_devvp->v_rdev;
  677         bp->b_iooffset = dbtob(bp->b_blkno);
  678         VOP_SPECSTRATEGY(hp->h_devvp, bp);
  679         return (0);
  680 }
  681 
  682 /*
  683  * XXXXX do we need hpfsnode locking inside?
  684  */
  685 int
  686 hpfs_access(ap)
  687         struct vop_access_args /* {
  688                 struct vnode *a_vp;
  689                 int  a_mode;
  690                 struct ucred *a_cred;
  691                 struct thread *a_td;
  692         } */ *ap;
  693 {
  694         struct vnode *vp = ap->a_vp;
  695         struct hpfsnode *hp = VTOHP(vp);
  696         mode_t mode = ap->a_mode;
  697 
  698         dprintf(("hpfs_access(0x%x):\n", hp->h_no));
  699 
  700         /*
  701          * Disallow write attempts on read-only filesystems;
  702          * unless the file is a socket, fifo, or a block or
  703          * character device resident on the filesystem.
  704          */
  705         if (mode & VWRITE) {
  706                 switch ((int)vp->v_type) {
  707                 case VDIR:
  708                 case VLNK:
  709                 case VREG:
  710                         if (vp->v_mount->mnt_flag & MNT_RDONLY)
  711                                 return (EROFS);
  712                         break;
  713                 }
  714         }
  715 
  716         return (vaccess(vp->v_type, hp->h_mode, hp->h_uid, hp->h_gid,
  717             ap->a_mode, ap->a_cred, NULL));
  718 }
  719 
  720 /*
  721  * Open called.
  722  *
  723  * Nothing to do.
  724  */
  725 /* ARGSUSED */
  726 static int
  727 hpfs_open(ap)
  728         struct vop_open_args /* {
  729                 struct vnode *a_vp;
  730                 int  a_mode;
  731                 struct ucred *a_cred;
  732                 struct thread *a_td;
  733         } */ *ap;
  734 {
  735 #if HPFS_DEBUG
  736         register struct vnode *vp = ap->a_vp;
  737         register struct hpfsnode *hp = VTOHP(vp);
  738 
  739         printf("hpfs_open(0x%x):\n",hp->h_no);
  740 #endif
  741 
  742         /*
  743          * Files marked append-only must be opened for appending.
  744          */
  745 
  746         return (0);
  747 }
  748 
  749 /*
  750  * Close called.
  751  *
  752  * Update the times on the inode.
  753  */
  754 /* ARGSUSED */
  755 static int
  756 hpfs_close(ap)
  757         struct vop_close_args /* {
  758                 struct vnode *a_vp;
  759                 int  a_fflag;
  760                 struct ucred *a_cred;
  761                 struct thread *a_td;
  762         } */ *ap;
  763 {
  764 #if HPFS_DEBUG
  765         register struct vnode *vp = ap->a_vp;
  766         register struct hpfsnode *hp = VTOHP(vp);
  767 
  768         printf("hpfs_close: %d\n",hp->h_no);
  769 #endif
  770 
  771         return (0);
  772 }
  773 
  774 static int
  775 hpfs_de_uiomove (
  776         struct hpfsmount *hpmp,
  777         struct hpfsdirent *dep,
  778         struct uio *uio)
  779 {
  780         struct dirent cde;
  781         int i, error;
  782 
  783         dprintf(("[no: 0x%x, size: %d, name: %2d:%.*s, flag: 0x%x] ",
  784                 dep->de_fnode, dep->de_size, dep->de_namelen,
  785                 dep->de_namelen, dep->de_name, dep->de_flag));
  786 
  787         /*strncpy(cde.d_name, dep->de_name, dep->de_namelen);*/
  788         for (i=0; i<dep->de_namelen; i++) 
  789                 cde.d_name[i] = hpfs_d2u(hpmp, dep->de_name[i]);
  790 
  791         cde.d_name[dep->de_namelen] = '\0';
  792         cde.d_namlen = dep->de_namelen;
  793         cde.d_fileno = dep->de_fnode;
  794         cde.d_type = (dep->de_flag & DE_DIR) ? DT_DIR : DT_REG;
  795         cde.d_reclen = sizeof(struct dirent);
  796 
  797         error = uiomove((char *)&cde, sizeof(struct dirent), uio);
  798         if (error)
  799                 return (error);
  800         
  801         dprintf(("[0x%x] ", uio->uio_resid));
  802         return (error);
  803 }
  804 
  805 
  806 static struct dirent hpfs_de_dot =
  807         { 0, sizeof(struct dirent), DT_DIR, 1, "." };
  808 static struct dirent hpfs_de_dotdot =
  809         { 0, sizeof(struct dirent), DT_DIR, 2, ".." };
  810 int
  811 hpfs_readdir(ap)
  812         struct vop_readdir_args /* {
  813                 struct vnode *a_vp;
  814                 struct uio *a_uio;
  815                 struct ucred *a_cred;
  816                 int *a_ncookies;
  817                 u_int **cookies;
  818         } */ *ap;
  819 {
  820         register struct vnode *vp = ap->a_vp;
  821         register struct hpfsnode *hp = VTOHP(vp);
  822         struct hpfsmount *hpmp = hp->h_hpmp;
  823         struct uio *uio = ap->a_uio;
  824         int ncookies = 0, i, num, cnum;
  825         int error = 0;
  826         off_t off;
  827         struct buf *bp;
  828         struct dirblk *dp;
  829         struct hpfsdirent *dep;
  830         lsn_t olsn;
  831         lsn_t lsn;
  832         int level;
  833 
  834         dprintf(("hpfs_readdir(0x%x, 0x%x, 0x%x): ",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid));
  835 
  836         off = uio->uio_offset;
  837 
  838         if( uio->uio_offset < sizeof(struct dirent) ) {
  839                 dprintf((". faked, "));
  840                 hpfs_de_dot.d_fileno = hp->h_no;
  841                 error = uiomove((char *)&hpfs_de_dot,sizeof(struct dirent),uio);
  842                 if(error) {
  843                         return (error);
  844                 }
  845 
  846                 ncookies ++;
  847         }
  848 
  849         if( uio->uio_offset < 2 * sizeof(struct dirent) ) {
  850                 dprintf((".. faked, "));
  851                 hpfs_de_dotdot.d_fileno = hp->h_fn.fn_parent;
  852 
  853                 error = uiomove((char *)&hpfs_de_dotdot, sizeof(struct dirent),
  854                                 uio);
  855                 if(error) {
  856                         return (error);
  857                 }
  858 
  859                 ncookies ++;
  860         }
  861 
  862         num = uio->uio_offset / sizeof(struct dirent) - 2;
  863         cnum = 0;
  864 
  865         lsn = ((alleaf_t *)hp->h_fn.fn_abd)->al_lsn;
  866 
  867         olsn = 0;
  868         level = 1;
  869 
  870 dive:
  871         dprintf(("[dive 0x%x] ", lsn));
  872         error = bread(hp->h_devvp, lsn, D_BSIZE, NOCRED, &bp);
  873         if (error) {
  874                 brelse(bp);
  875                 return (error);
  876         }
  877 
  878         dp = (struct dirblk *) bp->b_data;
  879         if (dp->d_magic != D_MAGIC) {
  880                 printf("hpfs_readdir: MAGIC DOESN'T MATCH\n");
  881                 brelse(bp);
  882                 return (EINVAL);
  883         }
  884 
  885         dep = D_DIRENT(dp);
  886 
  887         if (olsn) {
  888                 dprintf(("[restore 0x%x] ", olsn));
  889 
  890                 while(!(dep->de_flag & DE_END) ) {
  891                         if((dep->de_flag & DE_DOWN) &&
  892                            (olsn == DE_DOWNLSN(dep)))
  893                                          break;
  894                         dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  895                 }
  896 
  897                 if((dep->de_flag & DE_DOWN) && (olsn == DE_DOWNLSN(dep))) {
  898                         if (dep->de_flag & DE_END)
  899                                 goto blockdone;
  900 
  901                         if (!(dep->de_flag & DE_SPECIAL)) {
  902                                 if (num <= cnum) {
  903                                         if (uio->uio_resid < sizeof(struct dirent)) {
  904                                                 brelse(bp);
  905                                                 dprintf(("[resid] "));
  906                                                 goto readdone;
  907                                         }
  908 
  909                                         error = hpfs_de_uiomove(hpmp, dep, uio);
  910                                         if (error) {
  911                                                 brelse (bp);
  912                                                 return (error);
  913                                         }
  914                                         ncookies++;
  915 
  916                                         if (uio->uio_resid < sizeof(struct dirent)) {
  917                                                 brelse(bp);
  918                                                 dprintf(("[resid] "));
  919                                                 goto readdone;
  920                                         }
  921                                 }
  922                                 cnum++;
  923                         }
  924 
  925                         dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  926                 } else {
  927                         printf("hpfs_readdir: ERROR! oLSN not found\n");
  928                         brelse(bp);
  929                         return (EINVAL);
  930                 }
  931         }
  932 
  933         olsn = 0;
  934 
  935         while(!(dep->de_flag & DE_END)) {
  936                 if(dep->de_flag & DE_DOWN) {
  937                         lsn = DE_DOWNLSN(dep);
  938                         brelse(bp);
  939                         level++;
  940                         goto dive;
  941                 }
  942 
  943                 if (!(dep->de_flag & DE_SPECIAL)) {
  944                         if (num <= cnum) {
  945                                 if (uio->uio_resid < sizeof(struct dirent)) {
  946                                         brelse(bp);
  947                                         dprintf(("[resid] "));
  948                                         goto readdone;
  949                                 }
  950 
  951                                 error = hpfs_de_uiomove(hpmp, dep, uio);
  952                                 if (error) {
  953                                         brelse (bp);
  954                                         return (error);
  955                                 }
  956                                 ncookies++;
  957                                 
  958                                 if (uio->uio_resid < sizeof(struct dirent)) {
  959                                         brelse(bp);
  960                                         dprintf(("[resid] "));
  961                                         goto readdone;
  962                                 }
  963                         }
  964                         cnum++;
  965                 }
  966 
  967                 dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  968         }
  969 
  970         if(dep->de_flag & DE_DOWN) {
  971                 dprintf(("[enddive] "));
  972                 lsn = DE_DOWNLSN(dep);
  973                 brelse(bp);
  974                 level++;
  975                 goto dive;
  976         }
  977 
  978 blockdone:
  979         dprintf(("[EOB] "));
  980         olsn = lsn;
  981         lsn = dp->d_parent;
  982         brelse(bp);
  983         level--;
  984 
  985         dprintf(("[level %d] ", level));
  986 
  987         if (level > 0)
  988                 goto dive;      /* undive really */
  989 
  990         if (ap->a_eofflag) {
  991             dprintf(("[EOF] "));
  992             *ap->a_eofflag = 1;
  993         }
  994 
  995 readdone:
  996         dprintf(("[readdone]\n"));
  997         if (!error && ap->a_ncookies != NULL) {
  998                 struct dirent* dpStart;
  999                 struct dirent* dp;
 1000                 u_long *cookies;
 1001                 u_long *cookiep;
 1002 
 1003                 dprintf(("%d cookies, ",ncookies));
 1004                 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
 1005                         panic("hpfs_readdir: unexpected uio from NFS server");
 1006                 dpStart = (struct dirent *)
 1007                      ((caddr_t)uio->uio_iov->iov_base -
 1008                          (uio->uio_offset - off));
 1009                 MALLOC(cookies, u_long *, ncookies * sizeof(u_long),
 1010                        M_TEMP, M_WAITOK);
 1011                 for (dp = dpStart, cookiep = cookies, i=0;
 1012                      i < ncookies;
 1013                      dp = (struct dirent *)((caddr_t) dp + dp->d_reclen), i++) {
 1014                         off += dp->d_reclen;
 1015                         *cookiep++ = (u_int) off;
 1016                 }
 1017                 *ap->a_ncookies = ncookies;
 1018                 *ap->a_cookies = cookies;
 1019         }
 1020 
 1021         return (0);
 1022 }
 1023 
 1024 int
 1025 hpfs_lookup(ap)
 1026         struct vop_lookup_args /* {
 1027                 struct vnode *a_dvp;
 1028                 struct vnode **a_vpp;
 1029                 struct componentname *a_cnp;
 1030         } */ *ap;
 1031 {
 1032         register struct vnode *dvp = ap->a_dvp;
 1033         register struct hpfsnode *dhp = VTOHP(dvp);
 1034         struct hpfsmount *hpmp = dhp->h_hpmp;
 1035         struct componentname *cnp = ap->a_cnp;
 1036         struct ucred *cred = cnp->cn_cred;
 1037         int error;
 1038         int nameiop = cnp->cn_nameiop;
 1039         int flags = cnp->cn_flags;
 1040         int lockparent = flags & LOCKPARENT;
 1041 #if HPFS_DEBUG
 1042         int wantparent = flags & (LOCKPARENT|WANTPARENT);
 1043 #endif
 1044         dprintf(("hpfs_lookup(0x%x, %s, %ld, %d, %d): \n",
 1045                 dhp->h_no, cnp->cn_nameptr, cnp->cn_namelen,
 1046                 lockparent, wantparent));
 1047 
 1048         if (nameiop != CREATE && nameiop != DELETE && nameiop != LOOKUP) {
 1049                 printf("hpfs_lookup: LOOKUP, DELETE and CREATE are only supported\n");
 1050                 return (EOPNOTSUPP);
 1051         }
 1052 
 1053         error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_thread);
 1054         if(error)
 1055                 return (error);
 1056 
 1057         if( (cnp->cn_namelen == 1) &&
 1058             !strncmp(cnp->cn_nameptr,".",1) ) {
 1059                 dprintf(("hpfs_lookup(0x%x,...): . faked\n",dhp->h_no));
 1060 
 1061                 VREF(dvp);
 1062                 *ap->a_vpp = dvp;
 1063 
 1064                 return (0);
 1065         } else if( (cnp->cn_namelen == 2) &&
 1066             !strncmp(cnp->cn_nameptr,"..",2) && (flags & ISDOTDOT) ) {
 1067                 dprintf(("hpfs_lookup(0x%x,...): .. faked (0x%x)\n",
 1068                         dhp->h_no, dhp->h_fn.fn_parent));
 1069 
 1070                 if (VFS_VGET(hpmp->hpm_mp, dhp->h_fn.fn_parent,
 1071                     LK_NOWAIT | LK_EXCLUSIVE, ap->a_vpp)) {
 1072                         VOP_UNLOCK(dvp,0,cnp->cn_thread);
 1073                         error = VFS_VGET(hpmp->hpm_mp,
 1074                                  dhp->h_fn.fn_parent, LK_EXCLUSIVE, ap->a_vpp); 
 1075                         VOP_LOCK(dvp, 0, cnp->cn_thread);
 1076                         if(error)
 1077                                 return(error);
 1078                 }
 1079                 if (!lockparent || !(flags & ISLASTCN))
 1080                         VOP_UNLOCK(dvp,0,cnp->cn_thread);
 1081                 return (0);
 1082         } else {
 1083                 struct buf *bp;
 1084                 struct hpfsdirent *dep;
 1085                 struct hpfsnode *hp;
 1086 
 1087                 error = hpfs_genlookupbyname(dhp,
 1088                                 cnp->cn_nameptr, cnp->cn_namelen, &bp, &dep);
 1089                 if (error) {
 1090                         if ((error == ENOENT) && (flags & ISLASTCN) &&
 1091                             (nameiop == CREATE || nameiop == RENAME)) {
 1092                                 if(!lockparent)
 1093                                         VOP_UNLOCK(dvp, 0, cnp->cn_thread);
 1094                                 cnp->cn_flags |= SAVENAME;
 1095                                 return (EJUSTRETURN);
 1096                         }
 1097 
 1098                         return (error);
 1099                 }
 1100 
 1101                 dprintf(("hpfs_lookup: fnode: 0x%x, CPID: 0x%x\n",
 1102                          dep->de_fnode, dep->de_cpid));
 1103 
 1104                 if (nameiop == DELETE && (flags & ISLASTCN)) {
 1105                         error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_thread);
 1106                         if (error) {
 1107                                 brelse(bp);
 1108                                 return (error);
 1109                         }
 1110                 }
 1111 
 1112                 if (dhp->h_no == dep->de_fnode) {
 1113                         brelse(bp);
 1114                         VREF(dvp);
 1115                         *ap->a_vpp = dvp;
 1116                         return (0);
 1117                 }
 1118 
 1119                 error = VFS_VGET(hpmp->hpm_mp, dep->de_fnode, LK_EXCLUSIVE,
 1120                                  ap->a_vpp);
 1121                 if (error) {
 1122                         printf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
 1123                         brelse(bp);
 1124                         return(error);
 1125                 }
 1126 
 1127                 hp = VTOHP(*ap->a_vpp);
 1128 
 1129                 hp->h_mtime = dep->de_mtime;
 1130                 hp->h_ctime = dep->de_ctime;
 1131                 hp->h_atime = dep->de_atime;
 1132                 bcopy(dep->de_name, hp->h_name, dep->de_namelen);
 1133                 hp->h_name[dep->de_namelen] = '\0';
 1134                 hp->h_namelen = dep->de_namelen;
 1135                 hp->h_flag |= H_PARVALID;
 1136 
 1137                 brelse(bp);
 1138 
 1139                 if(!lockparent || !(flags & ISLASTCN))
 1140                         VOP_UNLOCK(dvp, 0, cnp->cn_thread);
 1141                 if ((flags & MAKEENTRY) &&
 1142                     (!(flags & ISLASTCN) || 
 1143                      (nameiop != DELETE && nameiop != CREATE)))
 1144                         cache_enter(dvp, *ap->a_vpp, cnp);
 1145         }
 1146         return (error);
 1147 }
 1148 
 1149 int
 1150 hpfs_remove(ap)
 1151         struct vop_remove_args /* {
 1152                 struct vnode *a_dvp;
 1153                 struct vnode *a_vp;
 1154                 struct componentname *a_cnp;
 1155         } */ *ap;
 1156 {
 1157         int error;
 1158 
 1159         dprintf(("hpfs_remove(0x%x, %s, %ld): \n", VTOHP(ap->a_vp)->h_no,
 1160                 ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen));
 1161 
 1162         if (ap->a_vp->v_type == VDIR)
 1163                 return (EPERM);
 1164 
 1165         error = hpfs_removefnode (ap->a_dvp, ap->a_vp, ap->a_cnp);
 1166         return (error);
 1167 }
 1168 
 1169 int
 1170 hpfs_create(ap)
 1171         struct vop_create_args /* {
 1172                 struct vnode *a_dvp;
 1173                 struct vnode **a_vpp;
 1174                 struct componentname *a_cnp;
 1175                 struct vattr *a_vap;
 1176         } */ *ap;
 1177 {
 1178         int error;
 1179 
 1180         dprintf(("hpfs_create(0x%x, %s, %ld): \n", VTOHP(ap->a_dvp)->h_no,
 1181                 ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen));
 1182 
 1183         if (!(ap->a_cnp->cn_flags & HASBUF)) 
 1184                 panic ("hpfs_create: no name\n");
 1185 
 1186         error = hpfs_makefnode (ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
 1187 
 1188         return (error);
 1189 }
 1190 
 1191 /*
 1192  * Return POSIX pathconf information applicable to NTFS filesystem
 1193  */
 1194 int
 1195 hpfs_pathconf(ap)
 1196         struct vop_pathconf_args /* {
 1197                 struct vnode *a_vp;
 1198                 int a_name;
 1199                 register_t *a_retval;
 1200         } */ *ap;
 1201 {
 1202         switch (ap->a_name) {
 1203         case _PC_LINK_MAX:
 1204                 *ap->a_retval = 1;
 1205                 return (0);
 1206         case _PC_NAME_MAX:
 1207                 *ap->a_retval = HPFS_MAXFILENAME;
 1208                 return (0);
 1209         case _PC_PATH_MAX:
 1210                 *ap->a_retval = PATH_MAX;
 1211                 return (0);
 1212         case _PC_CHOWN_RESTRICTED:
 1213                 *ap->a_retval = 1;
 1214                 return (0);
 1215         case _PC_NO_TRUNC:
 1216                 *ap->a_retval = 0;
 1217                 return (0);
 1218         default:
 1219                 return (EINVAL);
 1220         }
 1221         /* NOTREACHED */
 1222 }
 1223 
 1224 
 1225 /*
 1226  * Global vfs data structures
 1227  */
 1228 vop_t **hpfs_vnodeop_p;
 1229 struct vnodeopv_entry_desc hpfs_vnodeop_entries[] = {
 1230         { &vop_default_desc, (vop_t *)vop_defaultop },
 1231 
 1232         { &vop_getattr_desc, (vop_t *)hpfs_getattr },
 1233         { &vop_setattr_desc, (vop_t *)hpfs_setattr },
 1234         { &vop_inactive_desc, (vop_t *)hpfs_inactive },
 1235         { &vop_reclaim_desc, (vop_t *)hpfs_reclaim },
 1236         { &vop_print_desc, (vop_t *)hpfs_print },
 1237         { &vop_create_desc, (vop_t *)hpfs_create },
 1238         { &vop_remove_desc, (vop_t *)hpfs_remove },
 1239         { &vop_cachedlookup_desc, (vop_t *)hpfs_lookup },
 1240         { &vop_lookup_desc, (vop_t *)vfs_cache_lookup },
 1241         { &vop_access_desc, (vop_t *)hpfs_access },
 1242         { &vop_close_desc, (vop_t *)hpfs_close },
 1243         { &vop_open_desc, (vop_t *)hpfs_open },
 1244         { &vop_readdir_desc, (vop_t *)hpfs_readdir },
 1245         { &vop_fsync_desc, (vop_t *)hpfs_fsync },
 1246         { &vop_bmap_desc, (vop_t *)hpfs_bmap },
 1247         { &vop_strategy_desc, (vop_t *)hpfs_strategy },
 1248         { &vop_read_desc, (vop_t *)hpfs_read },
 1249         { &vop_write_desc, (vop_t *)hpfs_write },
 1250         { &vop_ioctl_desc, (vop_t *)hpfs_ioctl },
 1251         { &vop_pathconf_desc, (vop_t *)hpfs_pathconf },
 1252         { NULL, NULL }
 1253 };
 1254 
 1255 static
 1256 struct vnodeopv_desc hpfs_vnodeop_opv_desc =
 1257         { &hpfs_vnodeop_p, hpfs_vnodeop_entries };
 1258 
 1259 VNODEOP_SET(hpfs_vnodeop_opv_desc);

Cache object: c25c1aa7bf905e0c78da2dd5effc8d93


[ 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.