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/dev/dksubr.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: dksubr.c,v 1.14 2004/10/28 07:07:39 yamt Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe and Roland C. Dowdeswell.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.14 2004/10/28 07:07:39 yamt Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/stat.h>
   45 #include <sys/proc.h>
   46 #include <sys/ioctl.h>
   47 #include <sys/device.h>
   48 #include <sys/disk.h>
   49 #include <sys/disklabel.h>
   50 #include <sys/buf.h>
   51 #include <sys/bufq.h>
   52 #include <sys/vnode.h>
   53 #include <sys/fcntl.h>
   54 #include <sys/namei.h>
   55 
   56 #include <dev/dkvar.h>
   57 
   58 int     dkdebug = 0;
   59 
   60 #ifdef DEBUG
   61 #define DKDB_FOLLOW     0x1
   62 #define DKDB_INIT       0x2
   63 #define DKDB_VNODE      0x4
   64 
   65 #define IFDEBUG(x,y)            if (dkdebug & (x)) y
   66 #define DPRINTF(x,y)            IFDEBUG(x, printf y)
   67 #define DPRINTF_FOLLOW(y)       DPRINTF(DKDB_FOLLOW, y)
   68 #else
   69 #define IFDEBUG(x,y)
   70 #define DPRINTF(x,y)
   71 #define DPRINTF_FOLLOW(y)
   72 #endif
   73 
   74 #define DKLABELDEV(dev) \
   75         (MAKEDISKDEV(major((dev)), DISKUNIT((dev)), RAW_PART))
   76 
   77 static void     dk_makedisklabel(struct dk_intf *, struct dk_softc *);
   78 
   79 void
   80 dk_sc_init(struct dk_softc *dksc, void *osc, char *xname)
   81 {
   82 
   83         memset(dksc, 0x0, sizeof(*dksc));
   84         dksc->sc_osc = osc;
   85         strncpy(dksc->sc_xname, xname, DK_XNAME_SIZE);
   86         dksc->sc_dkdev.dk_name = dksc->sc_xname;
   87         lockinit(&dksc->sc_lock, PRIBIO, "dklk", 0, 0);
   88 }
   89 
   90 /* ARGSUSED */
   91 int
   92 dk_open(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
   93            int flags, int fmt, struct proc *p)
   94 {
   95         struct  disklabel *lp = dksc->sc_dkdev.dk_label;
   96         int     part = DISKPART(dev);
   97         int     pmask = 1 << part;
   98         int     ret = 0;
   99 
  100         DPRINTF_FOLLOW(("dk_open(%s, %p, 0x%x, 0x%x)\n",
  101             di->di_dkname, dksc, dev, flags));
  102 
  103         if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
  104                 return ret;
  105 
  106         part = DISKPART(dev);
  107         pmask = 1 << part;
  108 
  109         /*
  110          * If we're init'ed and there are no other open partitions then
  111          * update the in-core disklabel.
  112          */
  113         if ((dksc->sc_flags & DKF_INITED) && dksc->sc_dkdev.dk_openmask == 0)
  114                 dk_getdisklabel(di, dksc, dev);
  115 
  116         /* Fail if we can't find the partition. */
  117         if ((part != RAW_PART) &&
  118             (((dksc->sc_flags & DKF_INITED) == 0) ||
  119             ((part >= lp->d_npartitions) ||
  120             (lp->d_partitions[part].p_fstype == FS_UNUSED)))) {
  121                 ret = ENXIO;
  122                 goto done;
  123         }
  124 
  125         /* Mark our unit as open. */
  126         switch (fmt) {
  127         case S_IFCHR:
  128                 dksc->sc_dkdev.dk_copenmask |= pmask;
  129                 break;
  130         case S_IFBLK:
  131                 dksc->sc_dkdev.dk_bopenmask |= pmask;
  132                 break;
  133         }
  134 
  135         dksc->sc_dkdev.dk_openmask =
  136             dksc->sc_dkdev.dk_copenmask | dksc->sc_dkdev.dk_bopenmask;
  137 
  138 done:
  139         lockmgr(&dksc->sc_lock, LK_RELEASE, NULL);
  140         return ret;
  141 }
  142 
  143 /* ARGSUSED */
  144 int
  145 dk_close(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
  146             int flags, int fmt, struct proc *p)
  147 {
  148         int     part = DISKPART(dev);
  149         int     pmask = 1 << part;
  150         int     ret;
  151 
  152         DPRINTF_FOLLOW(("dk_close(%s, %p, 0x%x, 0x%x)\n",
  153             di->di_dkname, dksc, dev, flags));
  154 
  155         if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
  156                 return ret;
  157 
  158         switch (fmt) {
  159         case S_IFCHR:
  160                 dksc->sc_dkdev.dk_copenmask &= ~pmask;
  161                 break;
  162         case S_IFBLK:
  163                 dksc->sc_dkdev.dk_bopenmask &= ~pmask;
  164                 break;
  165         }
  166         dksc->sc_dkdev.dk_openmask =
  167             dksc->sc_dkdev.dk_copenmask | dksc->sc_dkdev.dk_bopenmask;
  168 
  169         lockmgr(&dksc->sc_lock, LK_RELEASE, NULL);
  170         return 0;
  171 }
  172 
  173 void
  174 dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp)
  175 {
  176         int     s;
  177         int     wlabel;
  178 
  179         DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n",
  180             di->di_dkname, dksc, bp));
  181 
  182         if (!(dksc->sc_flags & DKF_INITED)) {
  183                 DPRINTF_FOLLOW(("dk_stragy: not inited\n"));
  184                 bp->b_error  = ENXIO;
  185                 bp->b_flags |= B_ERROR;
  186                 biodone(bp);
  187                 return;
  188         }
  189 
  190         /* XXX look for some more errors, c.f. ld.c */
  191 
  192         bp->b_resid = bp->b_bcount;
  193 
  194         /* If there is nothing to do, then we are done */
  195         if (bp->b_bcount == 0) {
  196                 biodone(bp);
  197                 return;
  198         }
  199 
  200         wlabel = dksc->sc_flags & (DKF_WLABEL|DKF_LABELLING);
  201         if (DISKPART(bp->b_dev) != RAW_PART &&
  202             bounds_check_with_label(&dksc->sc_dkdev, bp, wlabel) <= 0) {
  203                 biodone(bp);
  204                 return;
  205         }
  206 
  207         /*
  208          * Start the unit by calling the start routine
  209          * provided by the individual driver.
  210          */
  211         s = splbio();
  212         BUFQ_PUT(&dksc->sc_bufq, bp);
  213         dk_start(di, dksc);
  214         splx(s);
  215         return;
  216 }
  217 
  218 void
  219 dk_start(struct dk_intf *di, struct dk_softc *dksc)
  220 {
  221         struct  buf *bp;
  222 
  223         DPRINTF_FOLLOW(("dk_start(%s, %p)\n", di->di_dkname, dksc));
  224 
  225         /* Process the work queue */
  226         while ((bp = BUFQ_GET(&dksc->sc_bufq)) != NULL) {
  227                 if (di->di_diskstart(dksc, bp) != 0) {
  228                         BUFQ_PUT(&dksc->sc_bufq, bp);
  229                         break;
  230                 }
  231         }
  232 }
  233 
  234 void
  235 dk_iodone(struct dk_intf *di, struct dk_softc *dksc)
  236 {
  237 
  238         DPRINTF_FOLLOW(("dk_iodone(%s, %p)\n", di->di_dkname, dksc));
  239 
  240         /* We kick the queue in case we are able to get more work done */
  241         dk_start(di, dksc);
  242 }
  243 
  244 int
  245 dk_size(struct dk_intf *di, struct dk_softc *dksc, dev_t dev)
  246 {
  247         struct  disklabel *lp;
  248         int     is_open;
  249         int     part;
  250         int     size;
  251 
  252         if ((dksc->sc_flags & DKF_INITED) == 0)
  253                 return -1;
  254 
  255         part = DISKPART(dev);
  256         is_open = dksc->sc_dkdev.dk_openmask & (1 << part);
  257 
  258         if (!is_open && di->di_open(dev, 0, S_IFBLK, curproc))
  259                 return -1;
  260 
  261         lp = dksc->sc_dkdev.dk_label;
  262         if (lp->d_partitions[part].p_fstype != FS_SWAP)
  263                 size = -1;
  264         else
  265                 size = lp->d_partitions[part].p_size *
  266                     (lp->d_secsize / DEV_BSIZE);
  267 
  268         if (!is_open && di->di_close(dev, 0, S_IFBLK, curproc))
  269                 return 1;
  270 
  271         return size;
  272 }
  273 
  274 int
  275 dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
  276             u_long cmd, caddr_t data, int flag, struct proc *p)
  277 {
  278         struct  disklabel *lp;
  279 #ifdef __HAVE_OLD_DISKLABEL
  280         struct  disklabel newlabel;
  281 #endif
  282         int     error = 0;
  283 
  284         DPRINTF_FOLLOW(("dk_ioctl(%s, %p, 0x%x, 0x%lx)\n",
  285             di->di_dkname, dksc, dev, cmd));
  286 
  287         /* ensure that the pseudo disk is open for writes for these commands */
  288         switch (cmd) {
  289         case DIOCSDINFO:
  290         case DIOCWDINFO:
  291 #ifdef __HAVE_OLD_DISKLABEL
  292         case ODIOCSDINFO:
  293         case ODIOCWDINFO:
  294 #endif
  295         case DIOCWLABEL:
  296                 if ((flag & FWRITE) == 0)
  297                         return EBADF;
  298         }
  299 
  300         /* ensure that the pseudo-disk is initialized for these */
  301         switch (cmd) {
  302         case DIOCGDINFO:
  303         case DIOCSDINFO:
  304         case DIOCWDINFO:
  305         case DIOCGPART:
  306         case DIOCWLABEL:
  307         case DIOCGDEFLABEL:
  308 #ifdef __HAVE_OLD_DISKLABEL
  309         case ODIOCGDINFO:
  310         case ODIOCSDINFO:
  311         case ODIOCWDINFO:
  312         case ODIOCGDEFLABEL:
  313 #endif
  314                 if ((dksc->sc_flags & DKF_INITED) == 0)
  315                         return ENXIO;
  316         }
  317 
  318         switch (cmd) {
  319         case DIOCGDINFO:
  320                 *(struct disklabel *)data = *(dksc->sc_dkdev.dk_label);
  321                 break;
  322 
  323 #ifdef __HAVE_OLD_DISKLABEL
  324         case ODIOCGDINFO:
  325                 newlabel = *(dksc->sc_dkdev.dk_label);
  326                 if (newlabel.d_npartitions > OLDMAXPARTITIONS)
  327                         return ENOTTY;
  328                 memcpy(data, &newlabel, sizeof (struct olddisklabel));
  329                 break;
  330 #endif
  331 
  332         case DIOCGPART:
  333                 ((struct partinfo *)data)->disklab = dksc->sc_dkdev.dk_label;
  334                 ((struct partinfo *)data)->part =
  335                     &dksc->sc_dkdev.dk_label->d_partitions[DISKPART(dev)];
  336                 break;
  337 
  338         case DIOCWDINFO:
  339         case DIOCSDINFO:
  340 #ifdef __HAVE_OLD_DISKLABEL
  341         case ODIOCWDINFO:
  342         case ODIOCSDINFO:
  343 #endif
  344 #ifdef __HAVE_OLD_DISKLABEL
  345                 if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
  346                         memset(&newlabel, 0, sizeof newlabel);
  347                         memcpy(&newlabel, data, sizeof (struct olddisklabel));
  348                         lp = &newlabel;
  349                 } else
  350 #endif
  351                 lp = (struct disklabel *)data;
  352 
  353                 dksc->sc_flags |= DKF_LABELLING;
  354 
  355                 error = setdisklabel(dksc->sc_dkdev.dk_label,
  356                     lp, 0, dksc->sc_dkdev.dk_cpulabel);
  357                 if (error == 0) {
  358                         if (cmd == DIOCWDINFO
  359 #ifdef __HAVE_OLD_DISKLABEL
  360                             || cmd == ODIOCWDINFO
  361 #endif
  362                            )
  363                                 error = writedisklabel(DKLABELDEV(dev),
  364                                     di->di_strategy, dksc->sc_dkdev.dk_label,
  365                                     dksc->sc_dkdev.dk_cpulabel);
  366                 }
  367 
  368                 dksc->sc_flags &= ~DKF_LABELLING;
  369                 break;
  370 
  371         case DIOCWLABEL:
  372                 if (*(int *)data != 0)
  373                         dksc->sc_flags |= DKF_WLABEL;
  374                 else
  375                         dksc->sc_flags &= ~DKF_WLABEL;
  376                 break;
  377 
  378         case DIOCGDEFLABEL:
  379                 dk_getdefaultlabel(di, dksc, (struct disklabel *)data);
  380                 break;
  381 
  382 #ifdef __HAVE_OLD_DISKLABEL
  383         case ODIOCGDEFLABEL:
  384                 dk_getdefaultlabel(di, dksc, &newlabel);
  385                 if (newlabel.d_npartitions > OLDMAXPARTITIONS)
  386                         return ENOTTY;
  387                 memcpy(data, &newlabel, sizeof (struct olddisklabel));
  388                 break;
  389 #endif
  390 
  391         default:
  392                 error = ENOTTY;
  393         }
  394 
  395         return error;
  396 }
  397 
  398 /*
  399  * dk_dump dumps all of physical memory into the partition specified.
  400  * This requires substantially more framework than {s,w}ddump, and hence
  401  * is probably much more fragile.
  402  *
  403  * XXX: we currently do not implement this.
  404  */
  405 
  406 #define DKF_READYFORDUMP        (DKF_INITED|DKF_TAKEDUMP)
  407 #define DKFF_READYFORDUMP(x)    (((x) & DKF_READYFORDUMP) == DKF_READYFORDUMP)
  408 static volatile int     dk_dumping = 0;
  409 
  410 /* ARGSUSED */
  411 int
  412 dk_dump(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
  413            daddr_t blkno, caddr_t va, size_t size)
  414 {
  415 
  416         /*
  417          * ensure that we consider this device to be safe for dumping,
  418          * and that the device is configured.
  419          */
  420         if (!DKFF_READYFORDUMP(dksc->sc_flags))
  421                 return ENXIO;
  422 
  423         /* ensure that we are not already dumping */
  424         if (dk_dumping)
  425                 return EFAULT;
  426         dk_dumping = 1;
  427 
  428         /* XXX: unimplemented */
  429 
  430         dk_dumping = 0;
  431 
  432         /* XXX: actually for now, we are going to leave this alone */
  433         return ENXIO;
  434 }
  435 
  436 /* ARGSUSED */
  437 void
  438 dk_getdefaultlabel(struct dk_intf *di, struct dk_softc *dksc,
  439                       struct disklabel *lp)
  440 {
  441         struct dk_geom *pdg = &dksc->sc_geom;
  442 
  443         memset(lp, 0, sizeof(*lp));
  444 
  445         lp->d_secperunit = dksc->sc_size;
  446         lp->d_secsize = pdg->pdg_secsize;
  447         lp->d_nsectors = pdg->pdg_nsectors;
  448         lp->d_ntracks = pdg->pdg_ntracks;
  449         lp->d_ncylinders = pdg->pdg_ncylinders;
  450         lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
  451 
  452         strncpy(lp->d_typename, di->di_dkname, sizeof(lp->d_typename));
  453         lp->d_type = di->di_dtype;
  454         strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
  455         lp->d_rpm = 3600;
  456         lp->d_interleave = 1;
  457         lp->d_flags = 0;
  458 
  459         lp->d_partitions[RAW_PART].p_offset = 0;
  460         lp->d_partitions[RAW_PART].p_size = dksc->sc_size;
  461         lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
  462         lp->d_npartitions = RAW_PART + 1;
  463 
  464         lp->d_magic = DISKMAGIC;
  465         lp->d_magic2 = DISKMAGIC;
  466         lp->d_checksum = dkcksum(dksc->sc_dkdev.dk_label);
  467 }
  468 
  469 /* ARGSUSED */
  470 void
  471 dk_getdisklabel(struct dk_intf *di, struct dk_softc *dksc, dev_t dev)
  472 {
  473         struct   disklabel *lp = dksc->sc_dkdev.dk_label;
  474         struct   cpu_disklabel *clp = dksc->sc_dkdev.dk_cpulabel;
  475         struct   partition *pp;
  476         int      i;
  477         const char      *errstring;
  478 
  479         memset(clp, 0x0, sizeof(*clp));
  480         dk_getdefaultlabel(di, dksc, lp);
  481         errstring = readdisklabel(DKLABELDEV(dev), di->di_strategy,
  482             dksc->sc_dkdev.dk_label, dksc->sc_dkdev.dk_cpulabel);
  483         if (errstring) {
  484                 dk_makedisklabel(di, dksc);
  485                 if (dksc->sc_flags & DKF_WARNLABEL)
  486                         printf("%s: %s\n", dksc->sc_xname, errstring);
  487                 return;
  488         }
  489 
  490         if ((dksc->sc_flags & DKF_LABELSANITY) == 0)
  491                 return;
  492 
  493         /* Sanity check */
  494         if (lp->d_secperunit != dksc->sc_size)
  495                 printf("WARNING: %s: total sector size in disklabel (%d) "
  496                     "!= the size of %s (%lu)\n", dksc->sc_xname,
  497                     lp->d_secperunit, di->di_dkname, (u_long)dksc->sc_size);
  498 
  499         for (i=0; i < lp->d_npartitions; i++) {
  500                 pp = &lp->d_partitions[i];
  501                 if (pp->p_offset + pp->p_size > dksc->sc_size)
  502                         printf("WARNING: %s: end of partition `%c' exceeds "
  503                             "the size of %s (%lu)\n", dksc->sc_xname,
  504                             'a' + i, di->di_dkname, (u_long)dksc->sc_size);
  505         }
  506 }
  507 
  508 /* ARGSUSED */
  509 static void
  510 dk_makedisklabel(struct dk_intf *di, struct dk_softc *dksc)
  511 {
  512         struct  disklabel *lp = dksc->sc_dkdev.dk_label;
  513 
  514         lp->d_partitions[RAW_PART].p_fstype = FS_BSDFFS;
  515         strncpy(lp->d_packname, "default label", sizeof(lp->d_packname));
  516         lp->d_checksum = dkcksum(lp);
  517 }
  518 
  519 /* This function is taken from ccd.c:1.76  --rcd */
  520 
  521 /*
  522  * XXX this function looks too generic for dksubr.c, shouldn't we
  523  *     put it somewhere better?
  524  */
  525 
  526 /*
  527  * Lookup the provided name in the filesystem.  If the file exists,
  528  * is a valid block device, and isn't being used by anyone else,
  529  * set *vpp to the file's vnode.
  530  */
  531 int
  532 dk_lookup(path, p, vpp)
  533         char *path;
  534         struct proc *p;
  535         struct vnode **vpp;     /* result */
  536 {
  537         struct nameidata nd;
  538         struct vnode *vp;
  539         struct vattr va;
  540         int error;
  541 
  542         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, path, p);
  543         if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
  544                 DPRINTF((DKDB_FOLLOW|DKDB_INIT),
  545                     ("dk_lookup: vn_open error = %d\n", error));
  546                 return (error);
  547         }
  548         vp = nd.ni_vp;
  549 
  550         if (vp->v_usecount > 1) {
  551                 VOP_UNLOCK(vp, 0);
  552                 (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
  553                 return (EBUSY);
  554         }
  555 
  556         if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) != 0) {
  557                 DPRINTF((DKDB_FOLLOW|DKDB_INIT),
  558                     ("dk_lookup: getattr error = %d\n", error));
  559                 VOP_UNLOCK(vp, 0);
  560                 (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
  561                 return (error);
  562         }
  563 
  564         /* XXX: eventually we should handle VREG, too. */
  565         if (va.va_type != VBLK) {
  566                 VOP_UNLOCK(vp, 0);
  567                 (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
  568                 return (ENOTBLK);
  569         }
  570 
  571         IFDEBUG(DKDB_VNODE, vprint("dk_lookup: vnode info", vp));
  572 
  573         VOP_UNLOCK(vp, 0);
  574         *vpp = vp;
  575         return (0);
  576 }

Cache object: d163501eed62022c5b1286e7b990f325


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