Annotation of sys/lib/libsa/ufs.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ufs.c,v 1.18 2007/03/16 21:48:59 tsi Exp $ */
! 2: /* $NetBSD: ufs.c,v 1.16 1996/09/30 16:01:22 ws Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to Berkeley by
! 9: * The Mach Operating System project at Carnegie-Mellon University.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: *
! 35: *
! 36: * Copyright (c) 1990, 1991 Carnegie Mellon University
! 37: * All Rights Reserved.
! 38: *
! 39: * Author: David Golub
! 40: *
! 41: * Permission to use, copy, modify and distribute this software and its
! 42: * documentation is hereby granted, provided that both the copyright
! 43: * notice and this permission notice appear in all copies of the
! 44: * software, derivative works or modified versions, and any portions
! 45: * thereof, and that both notices appear in supporting documentation.
! 46: *
! 47: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
! 48: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
! 49: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
! 50: *
! 51: * Carnegie Mellon requests users of this software to return to
! 52: *
! 53: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
! 54: * School of Computer Science
! 55: * Carnegie Mellon University
! 56: * Pittsburgh PA 15213-3890
! 57: *
! 58: * any improvements or extensions that they make and grant Carnegie the
! 59: * rights to redistribute these changes.
! 60: */
! 61:
! 62: /*
! 63: * Stand-alone file reading package.
! 64: */
! 65:
! 66: #include <sys/param.h>
! 67: #include <sys/time.h>
! 68: #include <sys/stat.h>
! 69: #include <ufs/ffs/fs.h>
! 70: #include <ufs/ufs/dinode.h>
! 71: #include <ufs/ufs/dir.h>
! 72: #include <lib/libkern/libkern.h>
! 73:
! 74: #include "stand.h"
! 75: #include "ufs.h"
! 76:
! 77: /*
! 78: * In-core open file.
! 79: */
! 80: struct file {
! 81: off_t f_seekp; /* seek pointer */
! 82: struct fs *f_fs; /* pointer to super-block */
! 83: struct ufs1_dinode f_di; /* copy of on-disk inode */
! 84: int f_nindir[NIADDR];
! 85: /* number of blocks mapped by
! 86: indirect block at level i */
! 87: char *f_blk[NIADDR]; /* buffer for indirect block at
! 88: level i */
! 89: size_t f_blksize[NIADDR];
! 90: /* size of buffer */
! 91: daddr_t f_blkno[NIADDR];/* disk address of block in buffer */
! 92: char *f_buf; /* buffer for data block */
! 93: size_t f_buf_size; /* size of data block */
! 94: daddr_t f_buf_blkno; /* block number of data block */
! 95: };
! 96:
! 97: static int read_inode(ino_t, struct open_file *);
! 98: static int block_map(struct open_file *, daddr_t, daddr_t *);
! 99: static int buf_read_file(struct open_file *, char **, size_t *);
! 100: static int search_directory(char *, struct open_file *, ino_t *);
! 101: #ifdef COMPAT_UFS
! 102: static void ffs_oldfscompat(struct fs *);
! 103: #endif
! 104:
! 105: /*
! 106: * Read a new inode into a file structure.
! 107: */
! 108: static int
! 109: read_inode(ino_t inumber, struct open_file *f)
! 110: {
! 111: struct file *fp = (struct file *)f->f_fsdata;
! 112: struct fs *fs = fp->f_fs;
! 113: char *buf;
! 114: size_t rsize;
! 115: int rc;
! 116:
! 117: /*
! 118: * Read inode and save it.
! 119: */
! 120: buf = alloc(fs->fs_bsize);
! 121: twiddle();
! 122: rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
! 123: fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize,
! 124: buf, &rsize);
! 125: if (rc)
! 126: goto out;
! 127: if (rsize != (size_t)fs->fs_bsize) {
! 128: rc = EIO;
! 129: goto out;
! 130: }
! 131:
! 132: {
! 133: struct ufs1_dinode *dp;
! 134:
! 135: dp = (struct ufs1_dinode *)buf;
! 136: fp->f_di = dp[ino_to_fsbo(fs, inumber)];
! 137: }
! 138:
! 139: /*
! 140: * Clear out the old buffers
! 141: */
! 142: {
! 143: int level;
! 144:
! 145: for (level = 0; level < NIADDR; level++)
! 146: fp->f_blkno[level] = -1;
! 147: fp->f_buf_blkno = -1;
! 148: fp->f_seekp = 0;
! 149: }
! 150: out:
! 151: free(buf, fs->fs_bsize);
! 152: return (rc);
! 153: }
! 154:
! 155: /*
! 156: * Given an offset in a file, find the disk block number that
! 157: * contains that block.
! 158: */
! 159: static int
! 160: block_map(struct open_file *f, daddr_t file_block, daddr_t *disk_block_p)
! 161: {
! 162: struct file *fp = (struct file *)f->f_fsdata;
! 163: daddr_t ind_block_num, *ind_p;
! 164: struct fs *fs = fp->f_fs;
! 165: int level, idx, rc;
! 166:
! 167: /*
! 168: * Index structure of an inode:
! 169: *
! 170: * di_db[0..NDADDR-1] hold block numbers for blocks
! 171: * 0..NDADDR-1
! 172: *
! 173: * di_ib[0] index block 0 is the single indirect block
! 174: * holds block numbers for blocks
! 175: * NDADDR .. NDADDR + NINDIR(fs)-1
! 176: *
! 177: * di_ib[1] index block 1 is the double indirect block
! 178: * holds block numbers for INDEX blocks for blocks
! 179: * NDADDR + NINDIR(fs) ..
! 180: * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
! 181: *
! 182: * di_ib[2] index block 2 is the triple indirect block
! 183: * holds block numbers for double-indirect
! 184: * blocks for blocks
! 185: * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
! 186: * NDADDR + NINDIR(fs) + NINDIR(fs)**2
! 187: * + NINDIR(fs)**3 - 1
! 188: */
! 189:
! 190: if (file_block < NDADDR) {
! 191: /* Direct block. */
! 192: *disk_block_p = fp->f_di.di_db[file_block];
! 193: return (0);
! 194: }
! 195:
! 196: file_block -= NDADDR;
! 197:
! 198: /*
! 199: * nindir[0] = NINDIR
! 200: * nindir[1] = NINDIR**2
! 201: * nindir[2] = NINDIR**3
! 202: * etc
! 203: */
! 204: for (level = 0; level < NIADDR; level++) {
! 205: if (file_block < fp->f_nindir[level])
! 206: break;
! 207: file_block -= fp->f_nindir[level];
! 208: }
! 209: if (level == NIADDR) {
! 210: /* Block number too high */
! 211: return (EFBIG);
! 212: }
! 213:
! 214: ind_block_num = fp->f_di.di_ib[level];
! 215:
! 216: for (; level >= 0; level--) {
! 217: if (ind_block_num == 0) {
! 218: *disk_block_p = 0; /* missing */
! 219: return (0);
! 220: }
! 221:
! 222: if (fp->f_blkno[level] != ind_block_num) {
! 223: if (fp->f_blk[level] == (char *)0)
! 224: fp->f_blk[level] =
! 225: alloc(fs->fs_bsize);
! 226: twiddle();
! 227: rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
! 228: fsbtodb(fp->f_fs, ind_block_num), fs->fs_bsize,
! 229: fp->f_blk[level], &fp->f_blksize[level]);
! 230: if (rc)
! 231: return (rc);
! 232: if (fp->f_blksize[level] != (size_t)fs->fs_bsize)
! 233: return (EIO);
! 234: fp->f_blkno[level] = ind_block_num;
! 235: }
! 236:
! 237: ind_p = (daddr_t *)fp->f_blk[level];
! 238:
! 239: if (level > 0) {
! 240: idx = file_block / fp->f_nindir[level - 1];
! 241: file_block %= fp->f_nindir[level - 1];
! 242: } else
! 243: idx = file_block;
! 244:
! 245: ind_block_num = ind_p[idx];
! 246: }
! 247:
! 248: *disk_block_p = ind_block_num;
! 249: return (0);
! 250: }
! 251:
! 252: /*
! 253: * Read a portion of a file into an internal buffer. Return
! 254: * the location in the buffer and the amount in the buffer.
! 255: */
! 256: static int
! 257: buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
! 258: {
! 259: struct file *fp = (struct file *)f->f_fsdata;
! 260: struct fs *fs = fp->f_fs;
! 261: daddr_t file_block, disk_block;
! 262: size_t block_size;
! 263: long off;
! 264: int rc;
! 265:
! 266: off = blkoff(fs, fp->f_seekp);
! 267: file_block = lblkno(fs, fp->f_seekp);
! 268: block_size = dblksize(fs, &fp->f_di, file_block);
! 269:
! 270: if (file_block != fp->f_buf_blkno) {
! 271: rc = block_map(f, file_block, &disk_block);
! 272: if (rc)
! 273: return (rc);
! 274:
! 275: if (fp->f_buf == (char *)0)
! 276: fp->f_buf = alloc(fs->fs_bsize);
! 277:
! 278: if (disk_block == 0) {
! 279: bzero(fp->f_buf, block_size);
! 280: fp->f_buf_size = block_size;
! 281: } else {
! 282: twiddle();
! 283: rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
! 284: fsbtodb(fs, disk_block),
! 285: block_size, fp->f_buf, &fp->f_buf_size);
! 286: if (rc)
! 287: return (rc);
! 288: }
! 289:
! 290: fp->f_buf_blkno = file_block;
! 291: }
! 292:
! 293: /*
! 294: * Return address of byte in buffer corresponding to
! 295: * offset, and size of remainder of buffer after that
! 296: * byte.
! 297: */
! 298: *buf_p = fp->f_buf + off;
! 299: *size_p = block_size - off;
! 300:
! 301: /*
! 302: * But truncate buffer at end of file.
! 303: */
! 304: if (*size_p > fp->f_di.di_size - fp->f_seekp)
! 305: *size_p = fp->f_di.di_size - fp->f_seekp;
! 306:
! 307: return (0);
! 308: }
! 309:
! 310: /*
! 311: * Search a directory for a name and return its
! 312: * i_number.
! 313: */
! 314: static int
! 315: search_directory(char *name, struct open_file *f, ino_t *inumber_p)
! 316: {
! 317: struct file *fp = (struct file *)f->f_fsdata;
! 318: int namlen, length, rc;
! 319: struct direct *dp, *edp;
! 320: size_t buf_size;
! 321: char *buf;
! 322:
! 323: length = strlen(name);
! 324:
! 325: fp->f_seekp = 0;
! 326: while (fp->f_seekp < fp->f_di.di_size) {
! 327: rc = buf_read_file(f, &buf, &buf_size);
! 328: if (rc)
! 329: return (rc);
! 330:
! 331: dp = (struct direct *)buf;
! 332: edp = (struct direct *)(buf + buf_size);
! 333: while (dp < edp) {
! 334: if (dp->d_ino == (ino_t)0)
! 335: goto next;
! 336: #if BYTE_ORDER == LITTLE_ENDIAN
! 337: if (fp->f_fs->fs_maxsymlinklen <= 0)
! 338: namlen = dp->d_type;
! 339: else
! 340: #endif
! 341: namlen = dp->d_namlen;
! 342: if (namlen == length &&
! 343: !strcmp(name, dp->d_name)) {
! 344: /* found entry */
! 345: *inumber_p = dp->d_ino;
! 346: return (0);
! 347: }
! 348: next:
! 349: dp = (struct direct *)((char *)dp + dp->d_reclen);
! 350: }
! 351: fp->f_seekp += buf_size;
! 352: }
! 353: return (ENOENT);
! 354: }
! 355:
! 356: /*
! 357: * Open a file.
! 358: */
! 359: int
! 360: ufs_open(char *path, struct open_file *f)
! 361: {
! 362: char namebuf[MAXPATHLEN+1], *cp, *ncp, *buf = NULL;
! 363: ino_t inumber, parent_inumber;
! 364: int rc, c, nlinks = 0;
! 365: struct file *fp;
! 366: size_t buf_size;
! 367: struct fs *fs;
! 368:
! 369: /* allocate file system specific data structure */
! 370: fp = alloc(sizeof(struct file));
! 371: bzero(fp, sizeof(struct file));
! 372: f->f_fsdata = (void *)fp;
! 373:
! 374: /* allocate space and read super block */
! 375: fs = alloc(SBSIZE);
! 376: fp->f_fs = fs;
! 377: twiddle();
! 378: rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
! 379: SBLOCK, SBSIZE, (char *)fs, &buf_size);
! 380: if (rc)
! 381: goto out;
! 382:
! 383: if (buf_size != SBSIZE || fs->fs_magic != FS_MAGIC ||
! 384: fs->fs_bsize > MAXBSIZE || fs->fs_bsize < sizeof(struct fs)) {
! 385: rc = EINVAL;
! 386: goto out;
! 387: }
! 388: #ifdef COMPAT_UFS
! 389: ffs_oldfscompat(fs);
! 390: #endif
! 391:
! 392: /*
! 393: * Calculate indirect block levels.
! 394: */
! 395: {
! 396: int mult;
! 397: int level;
! 398:
! 399: mult = 1;
! 400: for (level = 0; level < NIADDR; level++) {
! 401: mult *= NINDIR(fs);
! 402: fp->f_nindir[level] = mult;
! 403: }
! 404: }
! 405:
! 406: inumber = ROOTINO;
! 407: if ((rc = read_inode(inumber, f)) != 0)
! 408: goto out;
! 409:
! 410: cp = path;
! 411: while (*cp) {
! 412:
! 413: /*
! 414: * Remove extra separators
! 415: */
! 416: while (*cp == '/')
! 417: cp++;
! 418: if (*cp == '\0')
! 419: break;
! 420:
! 421: /*
! 422: * Check that current node is a directory.
! 423: */
! 424: if ((fp->f_di.di_mode & IFMT) != IFDIR) {
! 425: rc = ENOTDIR;
! 426: goto out;
! 427: }
! 428:
! 429: /*
! 430: * Get next component of path name.
! 431: */
! 432: {
! 433: int len = 0;
! 434:
! 435: ncp = cp;
! 436: while ((c = *cp) != '\0' && c != '/') {
! 437: if (++len > MAXNAMLEN) {
! 438: rc = ENOENT;
! 439: goto out;
! 440: }
! 441: cp++;
! 442: }
! 443: *cp = '\0';
! 444: }
! 445:
! 446: /*
! 447: * Look up component in current directory.
! 448: * Save directory inumber in case we find a
! 449: * symbolic link.
! 450: */
! 451: parent_inumber = inumber;
! 452: rc = search_directory(ncp, f, &inumber);
! 453: *cp = c;
! 454: if (rc)
! 455: goto out;
! 456:
! 457: /*
! 458: * Open next component.
! 459: */
! 460: if ((rc = read_inode(inumber, f)) != 0)
! 461: goto out;
! 462:
! 463: /*
! 464: * Check for symbolic link.
! 465: */
! 466: if ((fp->f_di.di_mode & IFMT) == IFLNK) {
! 467: int link_len = fp->f_di.di_size;
! 468: int len;
! 469:
! 470: len = strlen(cp);
! 471:
! 472: if (link_len + len > MAXPATHLEN ||
! 473: ++nlinks > MAXSYMLINKS) {
! 474: rc = ENOENT;
! 475: goto out;
! 476: }
! 477:
! 478: bcopy(cp, &namebuf[link_len], len + 1);
! 479:
! 480: if (link_len < fs->fs_maxsymlinklen) {
! 481: bcopy(fp->f_di.di_shortlink, namebuf,
! 482: (unsigned) link_len);
! 483: } else {
! 484: /*
! 485: * Read file for symbolic link
! 486: */
! 487: size_t buf_size;
! 488: daddr_t disk_block;
! 489: struct fs *fs = fp->f_fs;
! 490:
! 491: if (!buf)
! 492: buf = alloc(fs->fs_bsize);
! 493: rc = block_map(f, (daddr_t)0, &disk_block);
! 494: if (rc)
! 495: goto out;
! 496:
! 497: twiddle();
! 498: rc = (f->f_dev->dv_strategy)(f->f_devdata,
! 499: F_READ, fsbtodb(fs, disk_block),
! 500: fs->fs_bsize, buf, &buf_size);
! 501: if (rc)
! 502: goto out;
! 503:
! 504: bcopy((char *)buf, namebuf, (unsigned)link_len);
! 505: }
! 506:
! 507: /*
! 508: * If relative pathname, restart at parent directory.
! 509: * If absolute pathname, restart at root.
! 510: */
! 511: cp = namebuf;
! 512: if (*cp != '/')
! 513: inumber = parent_inumber;
! 514: else
! 515: inumber = (ino_t)ROOTINO;
! 516:
! 517: if ((rc = read_inode(inumber, f)) != 0)
! 518: goto out;
! 519: }
! 520: }
! 521:
! 522: /*
! 523: * Found terminal component.
! 524: */
! 525: rc = 0;
! 526: out:
! 527: if (buf)
! 528: free(buf, fs->fs_bsize);
! 529: if (rc) {
! 530: free(fp->f_fs, SBSIZE);
! 531: free(fp, sizeof(struct file));
! 532: }
! 533: return (rc);
! 534: }
! 535:
! 536: int
! 537: ufs_close(struct open_file *f)
! 538: {
! 539: struct file *fp = (struct file *)f->f_fsdata;
! 540: int level;
! 541:
! 542: f->f_fsdata = (void *)0;
! 543: if (fp == (struct file *)0)
! 544: return (0);
! 545:
! 546: for (level = 0; level < NIADDR; level++) {
! 547: if (fp->f_blk[level])
! 548: free(fp->f_blk[level], fp->f_fs->fs_bsize);
! 549: }
! 550: if (fp->f_buf)
! 551: free(fp->f_buf, fp->f_fs->fs_bsize);
! 552: free(fp->f_fs, SBSIZE);
! 553: free(fp, sizeof(struct file));
! 554: return (0);
! 555: }
! 556:
! 557: /*
! 558: * Copy a portion of a file into kernel memory.
! 559: * Cross block boundaries when necessary.
! 560: */
! 561: int
! 562: ufs_read(struct open_file *f, void *start, size_t size, size_t *resid)
! 563: {
! 564: struct file *fp = (struct file *)f->f_fsdata;
! 565: char *buf, *addr = start;
! 566: size_t csize, buf_size;
! 567: int rc = 0;
! 568:
! 569: while (size != 0) {
! 570: if (fp->f_seekp >= fp->f_di.di_size)
! 571: break;
! 572:
! 573: rc = buf_read_file(f, &buf, &buf_size);
! 574: if (rc)
! 575: break;
! 576:
! 577: csize = size;
! 578: if (csize > buf_size)
! 579: csize = buf_size;
! 580:
! 581: bcopy(buf, addr, csize);
! 582:
! 583: fp->f_seekp += csize;
! 584: addr += csize;
! 585: size -= csize;
! 586: }
! 587: if (resid)
! 588: *resid = size;
! 589: return (rc);
! 590: }
! 591:
! 592: /*
! 593: * Not implemented.
! 594: */
! 595: int
! 596: ufs_write(struct open_file *f, void *start, size_t size, size_t *resid)
! 597: {
! 598:
! 599: return (EROFS);
! 600: }
! 601:
! 602: off_t
! 603: ufs_seek(struct open_file *f, off_t offset, int where)
! 604: {
! 605: struct file *fp = (struct file *)f->f_fsdata;
! 606:
! 607: switch (where) {
! 608: case SEEK_SET:
! 609: fp->f_seekp = offset;
! 610: break;
! 611: case SEEK_CUR:
! 612: fp->f_seekp += offset;
! 613: break;
! 614: case SEEK_END:
! 615: fp->f_seekp = fp->f_di.di_size - offset;
! 616: break;
! 617: default:
! 618: return (-1);
! 619: }
! 620: return (fp->f_seekp);
! 621: }
! 622:
! 623: int
! 624: ufs_stat(struct open_file *f, struct stat *sb)
! 625: {
! 626: struct file *fp = (struct file *)f->f_fsdata;
! 627:
! 628: /* only important stuff */
! 629: sb->st_mode = fp->f_di.di_mode;
! 630: sb->st_uid = fp->f_di.di_uid;
! 631: sb->st_gid = fp->f_di.di_gid;
! 632: sb->st_size = fp->f_di.di_size;
! 633: return (0);
! 634: }
! 635:
! 636: #ifndef NO_READDIR
! 637: int
! 638: ufs_readdir(struct open_file *f, char *name)
! 639: {
! 640: struct file *fp = (struct file *)f->f_fsdata;
! 641: struct direct *dp, *edp;
! 642: size_t buf_size;
! 643: int rc, namlen;
! 644: char *buf;
! 645:
! 646: if (name == NULL)
! 647: fp->f_seekp = 0;
! 648: else {
! 649: /* end of dir */
! 650: if (fp->f_seekp >= fp->f_di.di_size) {
! 651: *name = '\0';
! 652: return -1;
! 653: }
! 654:
! 655: do {
! 656: if ((rc = buf_read_file(f, &buf, &buf_size)) != 0)
! 657: return rc;
! 658:
! 659: dp = (struct direct *)buf;
! 660: edp = (struct direct *)(buf + buf_size);
! 661: while (dp < edp && dp->d_ino == (ino_t)0)
! 662: dp = (struct direct *)((char *)dp + dp->d_reclen);
! 663: fp->f_seekp += buf_size -
! 664: ((u_int8_t *)edp - (u_int8_t *)dp);
! 665: } while (dp >= edp);
! 666:
! 667: #if BYTE_ORDER == LITTLE_ENDIAN
! 668: if (fp->f_fs->fs_maxsymlinklen <= 0)
! 669: namlen = dp->d_type;
! 670: else
! 671: #endif
! 672: namlen = dp->d_namlen;
! 673: strncpy(name, dp->d_name, namlen + 1);
! 674:
! 675: fp->f_seekp += dp->d_reclen;
! 676: }
! 677:
! 678: return 0;
! 679: }
! 680: #endif
! 681:
! 682: #ifdef COMPAT_UFS
! 683: /*
! 684: * Sanity checks for old file systems.
! 685: *
! 686: * XXX - goes away some day.
! 687: */
! 688: static void
! 689: ffs_oldfscompat(struct fs *fs)
! 690: {
! 691: int i;
! 692:
! 693: fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */
! 694: fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */
! 695: if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
! 696: fs->fs_nrpos = 8; /* XXX */
! 697: if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
! 698: quad_t sizepb = fs->fs_bsize; /* XXX */
! 699: /* XXX */
! 700: fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
! 701: for (i = 0; i < NIADDR; i++) { /* XXX */
! 702: sizepb *= NINDIR(fs); /* XXX */
! 703: fs->fs_maxfilesize += sizepb; /* XXX */
! 704: } /* XXX */
! 705: fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
! 706: fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
! 707: } /* XXX */
! 708: }
! 709: #endif
CVSweb