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

Annotation of src/sbin/dump/ffs_inode.c, Revision 1.16

1.16    ! dsl         1: /*     $NetBSD: ffs_inode.c,v 1.15 2004/03/24 17:07:12 ws Exp $ */
1.1       perseant    2:
                      3: /*-
                      4:  * Copyright (c) 1980, 1991, 1993, 1994
1.9       lukem       5:  *     The Regents of the University of California.  All rights reserved.
1.1       perseant    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.13      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       perseant   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:
                     32: #include <sys/cdefs.h>
                     33: #ifndef lint
                     34: __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\n\
1.9       lukem      35:        The Regents of the University of California.  All rights reserved.\n");
1.1       perseant   36: #endif /* not lint */
                     37:
                     38: #ifndef lint
1.16    ! dsl        39: __RCSID("$NetBSD: ffs_inode.c,v 1.15 2004/03/24 17:07:12 ws Exp $");
1.1       perseant   40: #endif /* not lint */
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/time.h>
                     44: #include <sys/stat.h>
                     45: #include <ufs/ufs/dir.h>
                     46: #include <ufs/ufs/dinode.h>
                     47: #include <ufs/ffs/fs.h>
                     48: #include <ufs/ffs/ffs_extern.h>
1.12      fvdl       49: #include <ufs/ufs/ufs_bswap.h>
1.1       perseant   50:
                     51: #include <protocols/dumprestore.h>
                     52:
                     53: #include <ctype.h>
                     54: #include <errno.h>
                     55: #include <fts.h>
                     56: #include <stdio.h>
1.12      fvdl       57: #include <stdlib.h>
1.1       perseant   58: #include <string.h>
                     59: #include <unistd.h>
                     60:
                     61: #include "dump.h"
                     62:
1.12      fvdl       63: struct fs *sblock;
                     64:
                     65: static off_t sblock_try[] = SBLOCKSEARCH;
                     66: off_t sblockloc;
1.1       perseant   67:
1.12      fvdl       68: int is_ufs2;
1.1       perseant   69:
                     70: /*
                     71:  * Read the superblock from disk, and check its magic number.
1.6       lukem      72:  * Determine whether byte-swapping needs to be done on this file system.
1.1       perseant   73:  */
                     74: int
1.8       lukem      75: fs_read_sblock(char *superblock)
1.1       perseant   76: {
1.12      fvdl       77:        int i;
1.8       lukem      78:        int ns = 0;
1.1       perseant   79:
1.8       lukem      80:        sblock = (struct fs *)superblock;
1.14      dsl        81:        for (i = 0; ; i++) {
                     82:                if (sblock_try[i] == -1)
                     83:                        quit("can't find superblock\n");
1.12      fvdl       84:                rawread(sblock_try[i], (char *)superblock, MAXBSIZE);
                     85:
                     86:                switch(sblock->fs_magic) {
                     87:                case FS_UFS2_MAGIC:
                     88:                        is_ufs2 = 1;
                     89:                        /*FALLTHROUGH*/
                     90:                case FS_UFS1_MAGIC:
1.14      dsl        91:                        break;
1.12      fvdl       92:                case FS_UFS2_MAGIC_SWAPPED:
                     93:                        is_ufs2 = 1;
                     94:                        /*FALLTHROUGH*/
                     95:                case FS_UFS1_MAGIC_SWAPPED:
                     96:                        ns = 1;
1.7       lukem      97:                        ffs_sb_swap(sblock, sblock);
1.14      dsl        98:                        break;
1.12      fvdl       99:                 default:
                    100:                         continue;
                    101:                 }
1.14      dsl       102:                if (!is_ufs2 && sblock_try[i] == SBLOCK_UFS2)
                    103:                        continue;
1.16    ! dsl       104:                if ((is_ufs2 || sblock->fs_old_flags & FS_FLAGS_UPDATED)
1.14      dsl       105:                    && sblock_try[i] != sblock->fs_sblockloc)
                    106:                        continue;
                    107:                break;
1.12      fvdl      108:         }
1.15      ws        109:        return ns;
1.1       perseant  110: }
                    111:
                    112: /*
                    113:  * Fill in the ufsi struct, as well as the maxino and dev_bsize global
                    114:  * variables.
                    115:  */
                    116: struct ufsi *
                    117: fs_parametrize(void)
                    118: {
                    119:        static struct ufsi ufsi;
                    120:
                    121: #ifdef FS_44INODEFMT
1.12      fvdl      122:        if (is_ufs2 || sblock->fs_old_inodefmt >= FS_44INODEFMT) {
1.1       perseant  123:                spcl.c_flags = iswap32(iswap32(spcl.c_flags) | DR_NEWINODEFMT);
                    124:        } else {
                    125:                /*
1.6       lukem     126:                 * Determine parameters for older file systems. From
1.1       perseant  127:                 *      /sys/ufs/ffs/ffs_vfsops.c::ffs_oldfscompat()
                    128:                 *
                    129:                 * XXX: not sure if other variables (fs_npsect, fs_interleave,
                    130:                 * fs_nrpos, fs_maxfilesize) need to be fudged too.
                    131:                 */
                    132:                sblock->fs_qbmask = ~sblock->fs_bmask;
                    133:                sblock->fs_qfmask = ~sblock->fs_fmask;
                    134:        }
                    135: #endif
                    136:
                    137:        /* Fill out ufsi struct */
                    138:        ufsi.ufs_dsize = fsbtodb(sblock,sblock->fs_size);
                    139:        ufsi.ufs_bsize = sblock->fs_bsize;
                    140:        ufsi.ufs_bshift = sblock->fs_bshift;
                    141:        ufsi.ufs_fsize = sblock->fs_fsize;
                    142:        ufsi.ufs_frag = sblock->fs_frag;
                    143:        ufsi.ufs_fsatoda = sblock->fs_fsbtodb;
                    144:        ufsi.ufs_nindir = sblock->fs_nindir;
                    145:        ufsi.ufs_inopb = sblock->fs_inopb;
                    146:        ufsi.ufs_maxsymlinklen = sblock->fs_maxsymlinklen;
                    147:        ufsi.ufs_bmask = sblock->fs_bmask;
                    148:        ufsi.ufs_fmask = sblock->fs_fmask;
                    149:        ufsi.ufs_qbmask = sblock->fs_qbmask;
                    150:        ufsi.ufs_qfmask = sblock->fs_qfmask;
                    151:
                    152:        dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
                    153:
                    154:        return &ufsi;
1.3       perseant  155: }
                    156:
                    157: ino_t
                    158: fs_maxino(void)
                    159: {
1.4       lukem     160:
1.3       perseant  161:        return sblock->fs_ipg * sblock->fs_ncg;
1.1       perseant  162: }
                    163:
1.12      fvdl      164: void
                    165: fs_mapinodes(ino_t maxino, u_int64_t *tape_size, int *anydirskipped)
                    166: {
                    167:        int i, cg, inosused;
                    168:        struct cg *cgp;
                    169:        ino_t ino;
                    170:        char *cp;
                    171:
                    172:        if ((cgp = malloc(sblock->fs_cgsize)) == NULL)
                    173:                quit("fs_mapinodes: cannot allocate memory.\n");
                    174:
                    175:        for (cg = 0; cg < sblock->fs_ncg; cg++) {
                    176:                ino = cg * sblock->fs_ipg;
                    177:                bread(fsbtodb(sblock, cgtod(sblock, cg)), (char *)cgp,
                    178:                    sblock->fs_cgsize);
                    179:                if (needswap)
                    180:                        ffs_cg_swap(cgp, cgp, sblock);
                    181:                if (sblock->fs_magic == FS_UFS2_MAGIC)
                    182:                        inosused = cgp->cg_initediblk;
                    183:                else
                    184:                        inosused = sblock->fs_ipg;
                    185:                /*
                    186:                 * If we are using soft updates, then we can trust the
                    187:                 * cylinder group inode allocation maps to tell us which
                    188:                 * inodes are allocated. We will scan the used inode map
                    189:                 * to find the inodes that are really in use, and then
                    190:                 * read only those inodes in from disk.
                    191:                 */
                    192:                if (sblock->fs_flags & FS_DOSOFTDEP) {
                    193:                        if (!cg_chkmagic(cgp, 0))
                    194:                                quit("mapfiles: cg %d: bad magic number\n", cg);
                    195:                        cp = &cg_inosused(cgp, 0)[(inosused - 1) / CHAR_BIT];
                    196:                        for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
                    197:                                if (*cp == 0)
                    198:                                        continue;
                    199:                                for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
                    200:                                        if (*cp & i)
                    201:                                                break;
                    202:                                        inosused--;
                    203:                                }
                    204:                                break;
                    205:                        }
                    206:                        if (inosused <= 0)
                    207:                                continue;
                    208:                }
                    209:                for (i = 0; i < inosused; i++, ino++) {
                    210:                        if (ino < ROOTINO)
                    211:                                continue;
                    212:                        mapfileino(ino, tape_size, anydirskipped);
                    213:                }
                    214:        }
                    215:
                    216:        free(cgp);
                    217: }
                    218:
                    219: union dinode *
1.4       lukem     220: getino(ino_t inum)
1.1       perseant  221: {
1.11      fvdl      222:        static ino_t minino, maxino;
1.12      fvdl      223:        static caddr_t inoblock;
                    224:        int ntoswap, i;
                    225:        struct ufs1_dinode *dp1;
                    226:        struct ufs2_dinode *dp2;
1.1       perseant  227:
1.12      fvdl      228:        if (inoblock == NULL && (inoblock = malloc(ufsib->ufs_bsize)) == NULL)
                    229:                quit("cannot allocate inode memory.\n");
1.1       perseant  230:        curino = inum;
                    231:        if (inum >= minino && inum < maxino)
1.12      fvdl      232:                goto gotit;
1.1       perseant  233:        bread(fsatoda(ufsib, ino_to_fsba(sblock, inum)), (char *)inoblock,
                    234:            (int)ufsib->ufs_bsize);
                    235:        minino = inum - (inum % INOPB(sblock));
                    236:        maxino = minino + INOPB(sblock);
1.12      fvdl      237:        if (needswap) {
                    238:                if (is_ufs2) {
                    239:                        dp2 = (struct ufs2_dinode *)inoblock;
                    240:                        ntoswap = ufsib->ufs_bsize / sizeof(struct ufs2_dinode);
                    241:                        for (i = 0; i < ntoswap; i++)
                    242:                                ffs_dinode2_swap(&dp2[i], &dp2[i]);
                    243:                } else {
                    244:                        dp1 = (struct ufs1_dinode *)inoblock;
                    245:                        ntoswap = ufsib->ufs_bsize / sizeof(struct ufs1_dinode);
                    246:                        for (i = 0; i < ntoswap; i++)
                    247:                                ffs_dinode1_swap(&dp1[i], &dp1[i]);
                    248:                }
                    249:        }
                    250: gotit:
                    251:        if (is_ufs2) {
                    252:                dp2 = &((struct ufs2_dinode *)inoblock)[inum - minino];
                    253:                return (union dinode *)dp2;
                    254:        }
                    255:        dp1 = &((struct ufs1_dinode *)inoblock)[inum - minino];
                    256:        return ((union dinode *)dp1);
1.1       perseant  257: }

CVSweb <webmaster@jp.NetBSD.org>