root/lib/libsa/ufs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. read_inode
  2. block_map
  3. buf_read_file
  4. search_directory
  5. ufs_open
  6. ufs_close
  7. ufs_read
  8. ufs_write
  9. ufs_seek
  10. ufs_stat
  11. ufs_readdir
  12. ffs_oldfscompat

    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

/* [<][>][^][v][top][bottom][index][help] */