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

Cache object: ab63700c192b935873861baf02c4bbb4


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