[BACK]Return to tunefs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / tunefs

Annotation of src/sbin/tunefs/tunefs.c, Revision 1.38

1.38    ! ad          1: /*     $NetBSD: tunefs.c,v 1.37 2008/07/31 15:55:41 simonb Exp $       */
1.10      cgd         2:
1.1       cgd         3: /*
1.8       mycroft     4:  * Copyright (c) 1983, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.28      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
1.11      lukem      32: #include <sys/cdefs.h>
1.1       cgd        33: #ifndef lint
1.34      lukem      34: __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
                     35:  The Regents of the University of California.  All rights reserved.");
1.1       cgd        36: #endif /* not lint */
                     37:
                     38: #ifndef lint
1.10      cgd        39: #if 0
1.12      lukem      40: static char sccsid[] = "@(#)tunefs.c   8.3 (Berkeley) 5/3/95";
1.10      cgd        41: #else
1.38    ! ad         42: __RCSID("$NetBSD: tunefs.c,v 1.37 2008/07/31 15:55:41 simonb Exp $");
1.10      cgd        43: #endif
1.1       cgd        44: #endif /* not lint */
                     45:
                     46: /*
                     47:  * tunefs: change layout parameters to an existing file system.
                     48:  */
                     49: #include <sys/param.h>
1.8       mycroft    50:
                     51: #include <ufs/ffs/fs.h>
1.13      bouyer     52: #include <ufs/ffs/ffs_extern.h>
1.35      simonb     53: #include <ufs/ufs/ufs_wapbl.h>
1.18      bouyer     54:
                     55: #include <machine/bswap.h>
1.8       mycroft    56:
1.22      lukem      57: #include <err.h>
1.8       mycroft    58: #include <errno.h>
1.6       cgd        59: #include <fcntl.h>
1.1       cgd        60: #include <fstab.h>
1.22      lukem      61: #include <paths.h>
1.1       cgd        62: #include <stdio.h>
1.6       cgd        63: #include <stdlib.h>
1.14      thorpej    64: #include <string.h>
1.6       cgd        65: #include <unistd.h>
1.25      lukem      66: #include <util.h>
1.6       cgd        67:
                     68: /* the optimization warning string template */
1.8       mycroft    69: #define        OPTWARN "should optimize for %s with minfree %s %d%%"
1.1       cgd        70:
                     71: union {
                     72:        struct  fs sb;
                     73:        char pad[MAXBSIZE];
                     74: } sbun;
                     75: #define        sblock sbun.sb
1.13      bouyer     76: char buf[MAXBSIZE];
1.1       cgd        77:
1.22      lukem      78: int    fi;
1.27      fvdl       79: long   dev_bsize = 512;
1.22      lukem      80: int    needswap = 0;
1.27      fvdl       81: int    is_ufs2 = 0;
                     82: off_t  sblockloc;
                     83:
                     84: static off_t sblock_try[] = SBLOCKSEARCH;
1.22      lukem      85:
1.25      lukem      86: static void    bwrite(daddr_t, char *, int, const char *);
                     87: static void    bread(daddr_t, char *, int, const char *);
1.35      simonb     88: static void    change_log_info(long long);
1.22      lukem      89: static void    getsb(struct fs *, const char *);
1.26      lukem      90: static int     openpartition(const char *, int, char *, size_t);
1.35      simonb     91: static void    show_log_info(void);
1.22      lukem      92: static void    usage(void);
1.6       cgd        93:
                     94: int
1.22      lukem      95: main(int argc, char *argv[])
1.1       cgd        96: {
1.25      lukem      97:        int             i, ch, Aflag, Fflag, Nflag, openflags;
1.22      lukem      98:        const char      *special, *chg[2];
1.26      lukem      99:        char            device[MAXPATHLEN];
1.27      fvdl      100:        int             maxbpg, minfree, optim;
1.24      lukem     101:        int             avgfilesize, avgfpdir;
1.35      simonb    102:        long long       logfilesize;
1.22      lukem     103:
                    104:        Aflag = Fflag = Nflag = 0;
1.27      fvdl      105:        maxbpg = minfree = optim = -1;
1.24      lukem     106:        avgfilesize = avgfpdir = -1;
1.35      simonb    107:        logfilesize = -1;
1.22      lukem     108:        chg[FS_OPTSPACE] = "space";
                    109:        chg[FS_OPTTIME] = "time";
                    110:
1.38    ! ad        111:        while ((ch = getopt(argc, argv, "AFNe:g:h:l:m:o:")) != -1) {
1.22      lukem     112:                switch (ch) {
                    113:
                    114:                case 'A':
                    115:                        Aflag++;
                    116:                        break;
                    117:
                    118:                case 'F':
                    119:                        Fflag++;
                    120:                        break;
                    121:
                    122:                case 'N':
                    123:                        Nflag++;
                    124:                        break;
                    125:
                    126:                case 'e':
1.35      simonb    127:                        maxbpg = strsuftoll(
1.22      lukem     128:                            "maximum blocks per file in a cylinder group",
1.35      simonb    129:                            optarg, 1, INT_MAX);
1.22      lukem     130:                        break;
                    131:
1.24      lukem     132:                case 'g':
1.35      simonb    133:                        avgfilesize = strsuftoll("average file size", optarg,
                    134:                            1, INT_MAX);
1.24      lukem     135:                        break;
                    136:
                    137:                case 'h':
1.35      simonb    138:                        avgfpdir = strsuftoll(
1.24      lukem     139:                            "expected number of files per directory",
1.35      simonb    140:                            optarg, 1, INT_MAX);
                    141:                        break;
                    142:
                    143:                case 'l':
                    144:                        logfilesize = strsuftoll("journal log file size",
                    145:                            optarg, 0, INT_MAX);
1.24      lukem     146:                        break;
1.22      lukem     147:
                    148:                case 'm':
1.35      simonb    149:                        minfree = strsuftoll("minimum percentage of free space",
                    150:                            optarg, 0, 99);
1.22      lukem     151:                        break;
                    152:
                    153:                case 'o':
                    154:                        if (strcmp(optarg, chg[FS_OPTSPACE]) == 0)
                    155:                                optim = FS_OPTSPACE;
                    156:                        else if (strcmp(optarg, chg[FS_OPTTIME]) == 0)
                    157:                                optim = FS_OPTTIME;
                    158:                        else
                    159:                                errx(10,
                    160:                                    "bad %s (options are `space' or `time')",
                    161:                                    "optimization preference");
                    162:                        break;
                    163:
                    164:                default:
                    165:                        usage();
                    166:                }
                    167:        }
                    168:        argc -= optind;
                    169:        argv += optind;
                    170:        if (argc != 1)
1.6       cgd       171:                usage();
1.22      lukem     172:
                    173:        special = argv[0];
1.25      lukem     174:        openflags = Nflag ? O_RDONLY : O_RDWR;
1.26      lukem     175:        if (Fflag)
1.25      lukem     176:                fi = open(special, openflags);
1.26      lukem     177:        else {
                    178:                fi = openpartition(special, openflags, device, sizeof(device));
1.25      lukem     179:                special = device;
1.1       cgd       180:        }
1.26      lukem     181:        if (fi == -1)
                    182:                err(1, "%s", special);
1.1       cgd       183:        getsb(&sblock, special);
1.22      lukem     184:
1.23      lukem     185: #define CHANGEVAL(old, new, type, suffix) do                           \
                    186:        if ((new) != -1) {                                              \
                    187:                if ((new) == (old))                                     \
                    188:                        warnx("%s remains unchanged at %d%s",           \
                    189:                            (type), (old), (suffix));                   \
                    190:                else {                                                  \
                    191:                        warnx("%s changes from %d%s to %d%s",           \
                    192:                            (type), (old), (suffix), (new), (suffix));  \
                    193:                        (old) = (new);                                  \
                    194:                }                                                       \
                    195:        } while (/* CONSTCOND */0)
                    196:
1.25      lukem     197:        warnx("tuning %s", special);
1.23      lukem     198:        CHANGEVAL(sblock.fs_maxbpg, maxbpg,
                    199:            "maximum blocks per file in a cylinder group", "");
                    200:        CHANGEVAL(sblock.fs_minfree, minfree,
                    201:            "minimum percentage of free space", "%");
1.22      lukem     202:        if (minfree != -1) {
                    203:                if (minfree >= MINFREE &&
                    204:                    sblock.fs_optim == FS_OPTSPACE)
                    205:                        warnx(OPTWARN, "time", ">=", MINFREE);
                    206:                if (minfree < MINFREE &&
                    207:                    sblock.fs_optim == FS_OPTTIME)
                    208:                        warnx(OPTWARN, "space", "<", MINFREE);
                    209:        }
                    210:        if (optim != -1) {
                    211:                if (sblock.fs_optim == optim) {
                    212:                        warnx("%s remains unchanged as %s",
                    213:                            "optimization preference",
                    214:                            chg[optim]);
                    215:                } else {
                    216:                        warnx("%s changes from %s to %s",
                    217:                            "optimization preference",
                    218:                            chg[sblock.fs_optim], chg[optim]);
                    219:                        sblock.fs_optim = optim;
                    220:                        if (sblock.fs_minfree >= MINFREE &&
                    221:                            optim == FS_OPTSPACE)
                    222:                                warnx(OPTWARN, "time", ">=", MINFREE);
                    223:                        if (sblock.fs_minfree < MINFREE &&
                    224:                            optim == FS_OPTTIME)
                    225:                                warnx(OPTWARN, "space", "<", MINFREE);
                    226:                }
                    227:        }
1.24      lukem     228:        CHANGEVAL(sblock.fs_avgfilesize, avgfilesize,
                    229:            "average file size", "");
                    230:        CHANGEVAL(sblock.fs_avgfpdir, avgfpdir,
                    231:            "expected number of files per directory", "");
1.1       cgd       232:
1.35      simonb    233:        if (logfilesize >= 0)
                    234:                change_log_info(logfilesize);
                    235:
1.12      lukem     236:        if (Nflag) {
1.37      simonb    237:                printf("tunefs: current settings of %s\n", special);
                    238:                printf("\tmaximum contiguous block count %d\n",
1.12      lukem     239:                    sblock.fs_maxcontig);
1.37      simonb    240:                printf("\tmaximum blocks per file in a cylinder group %d\n",
1.12      lukem     241:                    sblock.fs_maxbpg);
1.37      simonb    242:                printf("\tminimum percentage of free space %d%%\n",
1.12      lukem     243:                    sblock.fs_minfree);
1.37      simonb    244:                printf("\toptimization preference: %s\n", chg[sblock.fs_optim]);
                    245:                printf("\taverage file size: %d\n", sblock.fs_avgfilesize);
                    246:                printf("\texpected number of files per directory: %d\n",
1.24      lukem     247:                    sblock.fs_avgfpdir);
1.35      simonb    248:                show_log_info();
1.37      simonb    249:                printf("tunefs: no changes made\n");
1.12      lukem     250:                exit(0);
                    251:        }
1.22      lukem     252:
1.27      fvdl      253:        memcpy(buf, (char *)&sblock, SBLOCKSIZE);
1.13      bouyer    254:        if (needswap)
1.21      lukem     255:                ffs_sb_swap((struct fs*)buf, (struct fs*)buf);
1.27      fvdl      256:        bwrite(sblockloc, buf, SBLOCKSIZE, special);
1.1       cgd       257:        if (Aflag)
                    258:                for (i = 0; i < sblock.fs_ncg; i++)
                    259:                        bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)),
1.27      fvdl      260:                            buf, SBLOCKSIZE, special);
1.1       cgd       261:        close(fi);
                    262:        exit(0);
1.6       cgd       263: }
                    264:
1.35      simonb    265: static void
                    266: show_log_info(void)
                    267: {
                    268:        const char *loc;
1.36      simonb    269:        uint64_t size, blksize, logsize;
1.35      simonb    270:        int print;
                    271:
                    272:        switch (sblock.fs_journal_location) {
                    273:        case UFS_WAPBL_JOURNALLOC_NONE:
                    274:                print = blksize = 0;
                    275:                /* nothing */
                    276:                break;
                    277:        case UFS_WAPBL_JOURNALLOC_END_PARTITION:
                    278:                loc = "end of partition";
                    279:                size = sblock.fs_journallocs[UFS_WAPBL_EPART_COUNT];
                    280:                blksize = sblock.fs_journallocs[UFS_WAPBL_EPART_BLKSZ];
                    281:                print = 1;
                    282:                break;
                    283:        case UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM:
                    284:                loc = "in filesystem";
                    285:                size = sblock.fs_journallocs[UFS_WAPBL_INFS_COUNT];
                    286:                blksize = sblock.fs_journallocs[UFS_WAPBL_INFS_BLKSZ];
                    287:                print = 1;
                    288:                break;
                    289:        default:
                    290:                loc = "unknown";
                    291:                size = blksize = 0;
                    292:                print = 1;
                    293:                break;
                    294:        }
                    295:
                    296:        if (print) {
1.36      simonb    297:                logsize = size * blksize;
                    298:
1.37      simonb    299:                printf("\tjournal log file location: %s\n", loc);
                    300:                printf("\tjournal log file size: ");
1.36      simonb    301:                if (logsize == 0)
1.37      simonb    302:                        printf("0\n");
1.36      simonb    303:                else {
                    304:                        char sizebuf[8];
                    305:                        humanize_number(sizebuf, 6, size * blksize, "B",
                    306:                            HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1.37      simonb    307:                        printf("%s (%" PRId64 " bytes)", sizebuf, logsize);
1.36      simonb    308:                }
1.37      simonb    309:                printf("\n");
                    310:                printf("\tjournal log flags:");
1.35      simonb    311:                if (sblock.fs_journal_flags & UFS_WAPBL_FLAGS_CREATE_LOG)
1.37      simonb    312:                        printf(" clear-log");
1.35      simonb    313:                if (sblock.fs_journal_flags & UFS_WAPBL_FLAGS_CLEAR_LOG)
1.37      simonb    314:                        printf(" clear-log");
                    315:                printf("\n");
1.35      simonb    316:        }
                    317: }
                    318:
                    319: static void
                    320: change_log_info(long long logfilesize)
1.6       cgd       321: {
1.35      simonb    322:        /*
                    323:         * NOTES:
                    324:         *  - only operate on in-filesystem log sizes
                    325:         *  - can't change size of existing log
                    326:         *  - if current is same, no action
                    327:         *  - if current is zero and new is non-zero, set flag to create log
                    328:         *    on next mount
                    329:         *  - if current is non-zero and new is zero, set flag to clear log
                    330:         *    on next mount
                    331:         */
                    332:        int in_fs_log;
                    333:        uint64_t old_size;
                    334:
                    335:        old_size = 0;
                    336:        switch (sblock.fs_journal_location) {
                    337:        case UFS_WAPBL_JOURNALLOC_END_PARTITION:
                    338:                in_fs_log = 0;
                    339:                old_size = sblock.fs_journallocs[UFS_WAPBL_EPART_COUNT] *
                    340:                    sblock.fs_journallocs[UFS_WAPBL_EPART_BLKSZ];
                    341:                break;
                    342:
                    343:        case UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM:
                    344:                in_fs_log = 1;
                    345:                old_size = sblock.fs_journallocs[UFS_WAPBL_INFS_COUNT] *
                    346:                    sblock.fs_journallocs[UFS_WAPBL_INFS_BLKSZ];
                    347:                break;
                    348:
                    349:        case UFS_WAPBL_JOURNALLOC_NONE:
                    350:        default:
                    351:                in_fs_log = 0;
                    352:                old_size = 0;
                    353:                break;
                    354:        }
                    355:
                    356:        if (!in_fs_log)
                    357:                errx(1, "Can't change size of non-in-filesystem log");
                    358:
                    359:        if (old_size == logfilesize && logfilesize > 0) {
                    360:                /* no action */
                    361:                warnx("log file size remains unchanged at %lld", logfilesize);
                    362:                return;
                    363:        }
                    364:
                    365:        if (logfilesize == 0) {
                    366:                /*
                    367:                 * Don't clear out the locators - the kernel might need
                    368:                 * these to find the log!  Just set the "clear the log"
                    369:                 * flag and let the kernel do the rest.
                    370:                 */
                    371:                sblock.fs_journal_flags |= UFS_WAPBL_FLAGS_CLEAR_LOG;
                    372:                sblock.fs_journal_flags &= ~UFS_WAPBL_FLAGS_CREATE_LOG;
                    373:                warnx("log file size cleared from %" PRIu64 "", old_size);
                    374:                return;
                    375:        }
1.8       mycroft   376:
1.35      simonb    377:        if (old_size == 0) {
                    378:                /* create new log of desired size next mount */
                    379:                sblock.fs_journal_location = UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM;
                    380:                sblock.fs_journallocs[UFS_WAPBL_INFS_ADDR] = 0;
                    381:                sblock.fs_journallocs[UFS_WAPBL_INFS_COUNT] = logfilesize;
                    382:                sblock.fs_journallocs[UFS_WAPBL_INFS_BLKSZ] = 0;
                    383:                sblock.fs_journallocs[UFS_WAPBL_INFS_INO] = 0;
                    384:                sblock.fs_journal_flags |= UFS_WAPBL_FLAGS_CREATE_LOG;
                    385:                sblock.fs_journal_flags &= ~UFS_WAPBL_FLAGS_CLEAR_LOG;
                    386:                warnx("log file size set to %lld", logfilesize);
                    387:        } else {
                    388:                errx(1,
                    389:                    "Can't change existing log size from %" PRIu64 " to %lld",
                    390:                     old_size, logfilesize);
                    391:        }
1.22      lukem     392: }
                    393:
                    394: static void
                    395: usage(void)
                    396: {
                    397:
1.29      jmmv      398:        fprintf(stderr, "usage: tunefs [-AFN] tuneup-options special-device\n");
1.1       cgd       399:        fprintf(stderr, "where tuneup-options are:\n");
                    400:        fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n");
1.24      lukem     401:        fprintf(stderr, "\t-g average file size\n");
                    402:        fprintf(stderr, "\t-h expected number of files per directory\n");
1.35      simonb    403:        fprintf(stderr, "\t-l journal log file size (`0' to clear journal)\n");
1.1       cgd       404:        fprintf(stderr, "\t-m minimum percentage of free space\n");
1.23      lukem     405:        fprintf(stderr, "\t-o optimization preference (`space' or `time')\n");
1.8       mycroft   406:        exit(2);
1.1       cgd       407: }
                    408:
1.22      lukem     409: static void
                    410: getsb(struct fs *fs, const char *file)
1.1       cgd       411: {
1.27      fvdl      412:        int i;
1.1       cgd       413:
1.30      dsl       414:        for (i = 0; ; i++) {
                    415:                if (sblock_try[i] == -1)
                    416:                        errx(5, "cannot find filesystem superblock");
1.27      fvdl      417:                bread(sblock_try[i] / dev_bsize, (char *)fs, SBLOCKSIZE, file);
                    418:                switch(fs->fs_magic) {
                    419:                case FS_UFS2_MAGIC:
                    420:                        is_ufs2 = 1;
                    421:                        /*FALLTHROUGH*/
                    422:                case FS_UFS1_MAGIC:
1.30      dsl       423:                        break;
1.27      fvdl      424:                case FS_UFS2_MAGIC_SWAPPED:
                    425:                        is_ufs2 = 1;
                    426:                        /*FALLTHROUGH*/
                    427:                case FS_UFS1_MAGIC_SWAPPED:
1.22      lukem     428:                        warnx("%s: swapping byte order", file);
1.13      bouyer    429:                        needswap = 1;
1.21      lukem     430:                        ffs_sb_swap(fs, fs);
1.30      dsl       431:                        break;
1.27      fvdl      432:                default:
1.30      dsl       433:                        continue;
1.27      fvdl      434:                }
1.30      dsl       435:                if (!is_ufs2 && sblock_try[i] == SBLOCK_UFS2)
                    436:                        continue;
1.31      dsl       437:                if ((is_ufs2 || fs->fs_old_flags & FS_FLAGS_UPDATED)
1.30      dsl       438:                    && fs->fs_sblockloc != sblock_try[i])
                    439:                        continue;
                    440:                break;
1.17      ross      441:        }
1.30      dsl       442:
1.1       cgd       443:        dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
1.27      fvdl      444:        sblockloc = sblock_try[i] / dev_bsize;
1.1       cgd       445: }
                    446:
1.22      lukem     447: static void
1.25      lukem     448: bwrite(daddr_t blk, char *buffer, int size, const char *file)
1.1       cgd       449: {
1.25      lukem     450:        off_t   offset;
1.8       mycroft   451:
1.25      lukem     452:        offset = (off_t)blk * dev_bsize;
                    453:        if (lseek(fi, offset, SEEK_SET) == -1)
                    454:                err(6, "%s: seeking to %lld", file, (long long)offset);
1.22      lukem     455:        if (write(fi, buffer, size) != size)
1.25      lukem     456:                err(7, "%s: writing %d bytes", file, size);
1.1       cgd       457: }
                    458:
1.25      lukem     459: static void
                    460: bread(daddr_t blk, char *buffer, int cnt, const char *file)
1.1       cgd       461: {
1.25      lukem     462:        off_t   offset;
                    463:        int     i;
1.1       cgd       464:
1.25      lukem     465:        offset = (off_t)blk * dev_bsize;
                    466:        if (lseek(fi, offset, SEEK_SET) == -1)
                    467:                err(4, "%s: seeking to %lld", file, (long long)offset);
                    468:        if ((i = read(fi, buffer, cnt)) != cnt)
                    469:                errx(5, "%s: short read", file);
1.26      lukem     470: }
                    471:
                    472: static int
                    473: openpartition(const char *name, int flags, char *device, size_t devicelen)
                    474: {
                    475:        char            rawspec[MAXPATHLEN], *p;
                    476:        struct fstab    *fs;
                    477:        int             fd, oerrno;
                    478:
                    479:        fs = getfsfile(name);
                    480:        if (fs) {
                    481:                if ((p = strrchr(fs->fs_spec, '/')) != NULL) {
                    482:                        snprintf(rawspec, sizeof(rawspec), "%.*s/r%s",
                    483:                            (int)(p - fs->fs_spec), fs->fs_spec, p + 1);
                    484:                        name = rawspec;
                    485:                } else
                    486:                        name = fs->fs_spec;
                    487:        }
                    488:        fd = opendisk(name, flags, device, devicelen, 0);
                    489:        if (fd == -1 && errno == ENOENT) {
                    490:                oerrno = errno;
                    491:                strlcpy(device, name, devicelen);
                    492:                errno = oerrno;
                    493:        }
                    494:        return (fd);
1.1       cgd       495: }

CVSweb <webmaster@jp.NetBSD.org>