1 /* $NetBSD: ffs_inode.c,v 1.17 2006/12/18 20:07:32 christos Exp $ */
4 * Copyright (c) 1980, 1991, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
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
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\
35 The Regents of the University of California. All rights reserved.");
39 __RCSID("$NetBSD: ffs_inode.c,v 1.17 2006/12/18 20:07:32 christos Exp $");
42 #include <sys/param.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>
49 #include <ufs/ufs/ufs_bswap.h>
51 #include <protocols/dumprestore.h>
65 static off_t sblock_try
[] = SBLOCKSEARCH
;
71 * Read the superblock from disk, and check its magic number.
72 * Determine whether byte-swapping needs to be done on this file system.
75 fs_read_sblock(char *superblock
)
80 sblock
= (struct fs
*)superblock
;
82 if (sblock_try
[i
] == -1)
83 quit("can't find superblock\n");
84 rawread(sblock_try
[i
], (char *)superblock
, MAXBSIZE
);
86 switch(sblock
->fs_magic
) {
92 case FS_UFS2_MAGIC_SWAPPED
:
95 case FS_UFS1_MAGIC_SWAPPED
:
97 ffs_sb_swap(sblock
, sblock
);
102 if (!is_ufs2
&& sblock_try
[i
] == SBLOCK_UFS2
)
104 if ((is_ufs2
|| sblock
->fs_old_flags
& FS_FLAGS_UPDATED
)
105 && sblock_try
[i
] != sblock
->fs_sblockloc
)
113 * Fill in the ufsi struct, as well as the maxino and dev_bsize global
119 static struct ufsi ufsi
;
122 if (is_ufs2
|| sblock
->fs_old_inodefmt
>= FS_44INODEFMT
) {
123 spcl
.c_flags
= iswap32(iswap32(spcl
.c_flags
) | DR_NEWINODEFMT
);
126 * Determine parameters for older file systems. From
127 * /sys/ufs/ffs/ffs_vfsops.c::ffs_oldfscompat()
129 * XXX: not sure if other variables (fs_npsect, fs_interleave,
130 * fs_nrpos, fs_maxfilesize) need to be fudged too.
132 sblock
->fs_qbmask
= ~sblock
->fs_bmask
;
133 sblock
->fs_qfmask
= ~sblock
->fs_fmask
;
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
;
152 dev_bsize
= sblock
->fs_fsize
/ fsbtodb(sblock
, 1);
161 return sblock
->fs_ipg
* sblock
->fs_ncg
;
165 fs_mapinodes(ino_t maxino __unused
, u_int64_t
*tape_size
, int *anydirskipped
)
172 if ((cgp
= malloc(sblock
->fs_cgsize
)) == NULL
)
173 quit("fs_mapinodes: cannot allocate memory.\n");
175 for (cg
= 0; cg
< sblock
->fs_ncg
; cg
++) {
176 ino
= cg
* sblock
->fs_ipg
;
177 bread(fsbtodb(sblock
, cgtod(sblock
, cg
)), (char *)cgp
,
180 ffs_cg_swap(cgp
, cgp
, sblock
);
181 if (sblock
->fs_magic
== FS_UFS2_MAGIC
)
182 inosused
= cgp
->cg_initediblk
;
184 inosused
= sblock
->fs_ipg
;
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.
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
--) {
199 for (i
= 1 << (CHAR_BIT
- 1); i
> 0; i
>>= 1) {
209 for (i
= 0; i
< inosused
; i
++, ino
++) {
212 mapfileino(ino
, tape_size
, anydirskipped
);
222 static ino_t minino
, maxino
;
223 static caddr_t inoblock
;
225 struct ufs1_dinode
*dp1
;
226 struct ufs2_dinode
*dp2
;
228 if (inoblock
== NULL
&& (inoblock
= malloc(ufsib
->ufs_bsize
)) == NULL
)
229 quit("cannot allocate inode memory.\n");
231 if (inum
>= minino
&& inum
< maxino
)
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
);
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
]);
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
]);
252 dp2
= &((struct ufs2_dinode
*)inoblock
)[inum
- minino
];
253 return (union dinode
*)dp2
;
255 dp1
= &((struct ufs1_dinode
*)inoblock
)[inum
- minino
];
256 return ((union dinode
*)dp1
);