1 /* $NetBSD: inode.c,v 1.39 2008/05/16 09:21:59 hannken Exp $ */
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Konrad E. Schroder <perseant@hhhh.org>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1980, 1986, 1993
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 #include <sys/types.h>
62 #include <sys/param.h>
65 #include <sys/mount.h>
67 #include <ufs/ufs/inode.h>
68 #include <ufs/ufs/dir.h>
70 #include <ufs/lfs/lfs.h>
90 extern SEGUSE
*seg_table
;
91 extern ufs_daddr_t
*din_table
;
93 static int iblock(struct inodesc
*, long, u_int64_t
);
94 int blksreqd(struct lfs
*, int);
98 * Get a dinode of a given inum.
99 * XXX combine this function with vget.
112 if (din_table
[ino
] == 0x0) {
113 LFS_IENTRY(ifp
, fs
, ino
, bp
);
114 din_table
[ino
] = ifp
->if_daddr
;
115 seg_table
[dtosn(fs
, ifp
->if_daddr
)].su_nbytes
+= DINODE1_SIZE
;
118 return (VTOI(vp
)->i_din
.ffs1_din
);
122 * Check validity of held blocks in an inode, recursing through all blocks.
125 ckinode(struct ufs1_dinode
*dp
, struct inodesc
*idesc
)
127 ufs_daddr_t
*ap
, lbn
;
128 long ret
, n
, ndb
, offset
;
129 struct ufs1_dinode dino
;
130 u_int64_t remsize
, sizepb
;
132 char pathbuf
[MAXPATHLEN
+ 1];
133 struct uvnode
*vp
, *thisvp
;
135 if (idesc
->id_fix
!= IGNORE
)
136 idesc
->id_fix
= DONTKNOW
;
137 idesc
->id_entryno
= 0;
138 idesc
->id_filesize
= dp
->di_size
;
139 mode
= dp
->di_mode
& IFMT
;
140 if (mode
== IFBLK
|| mode
== IFCHR
||
141 (mode
== IFLNK
&& (dp
->di_size
< fs
->lfs_maxsymlinklen
||
142 (fs
->lfs_maxsymlinklen
== 0 &&
143 dp
->di_blocks
== 0))))
146 ndb
= howmany(dino
.di_size
, fs
->lfs_bsize
);
148 thisvp
= vget(fs
, idesc
->id_number
);
149 for (lbn
= 0; lbn
< NDADDR
; lbn
++) {
150 ap
= dino
.di_db
+ lbn
;
153 numfrags(fs
, VTOI(thisvp
)->i_lfs_fragsize
[lbn
]);
155 if (--ndb
== 0 && (offset
= blkoff(fs
, dino
.di_size
)) != 0) {
157 numfrags(fs
, fragroundup(fs
, offset
));
159 idesc
->id_numfrags
= fs
->lfs_frag
;
162 if (idesc
->id_type
== DATA
&& ndb
>= 0) {
163 /* An empty block in a directory XXX */
164 getpathname(pathbuf
, sizeof(pathbuf
),
165 idesc
->id_number
, idesc
->id_number
);
166 pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [1]",
167 pathbuf
, (long long)idesc
->id_number
);
168 if (reply("ADJUST LENGTH") == 1) {
169 vp
= vget(fs
, idesc
->id_number
);
171 dp
->di_size
= (ap
- &dino
.di_db
[0]) *
174 "YOU MUST RERUN FSCK AFTERWARDS\n");
182 idesc
->id_blkno
= *ap
;
183 idesc
->id_lblkno
= ap
- &dino
.di_db
[0];
184 if (idesc
->id_type
== ADDR
) {
185 ret
= (*idesc
->id_func
) (idesc
);
187 ret
= dirscan(idesc
);
191 idesc
->id_numfrags
= fs
->lfs_frag
;
192 remsize
= dino
.di_size
- fs
->lfs_bsize
* NDADDR
;
193 sizepb
= fs
->lfs_bsize
;
194 for (ap
= &dino
.di_ib
[0], n
= 1; n
<= NIADDR
; ap
++, n
++) {
196 idesc
->id_blkno
= *ap
;
197 ret
= iblock(idesc
, n
, remsize
);
201 if (idesc
->id_type
== DATA
&& remsize
> 0) {
202 /* An empty block in a directory XXX */
203 getpathname(pathbuf
, sizeof(pathbuf
),
204 idesc
->id_number
, idesc
->id_number
);
205 pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [2]",
206 pathbuf
, (long long)idesc
->id_number
);
207 if (reply("ADJUST LENGTH") == 1) {
208 vp
= vget(fs
, idesc
->id_number
);
210 dp
->di_size
-= remsize
;
213 "YOU MUST RERUN FSCK AFTERWARDS\n");
221 sizepb
*= NINDIR(fs
);
228 iblock(struct inodesc
*idesc
, long ilevel
, u_int64_t isize
)
230 ufs_daddr_t
*ap
, *aplim
;
232 int i
, n
, (*func
) (struct inodesc
*), nif
;
234 char pathbuf
[MAXPATHLEN
+ 1], buf
[BUFSIZ
];
235 struct uvnode
*devvp
, *vp
;
238 if (idesc
->id_type
== ADDR
) {
239 func
= idesc
->id_func
;
241 if ((n
& KEEPON
) == 0)
245 if (chkrange(idesc
->id_blkno
, fragstofsb(fs
, idesc
->id_numfrags
)))
248 devvp
= fs
->lfs_devvp
;
249 bread(devvp
, fsbtodb(fs
, idesc
->id_blkno
), fs
->lfs_bsize
,
252 for (sizepb
= fs
->lfs_bsize
, i
= 0; i
< ilevel
; i
++)
253 sizepb
*= NINDIR(fs
);
254 if (isize
> sizepb
* NINDIR(fs
))
257 nif
= howmany(isize
, sizepb
);
258 if (idesc
->id_func
== pass1check
&& nif
< NINDIR(fs
)) {
259 aplim
= ((ufs_daddr_t
*) bp
->b_data
) + NINDIR(fs
);
260 for (ap
= ((ufs_daddr_t
*) bp
->b_data
) + nif
; ap
< aplim
; ap
++) {
263 (void) sprintf(buf
, "PARTIALLY TRUNCATED INODE I=%llu",
264 (unsigned long long)idesc
->id_number
);
265 if (dofix(idesc
, buf
)) {
271 aplim
= ((ufs_daddr_t
*) bp
->b_data
) + nif
;
272 for (ap
= ((ufs_daddr_t
*) bp
->b_data
); ap
< aplim
; ap
++) {
274 idesc
->id_blkno
= *ap
;
277 * dirscan needs lblkno.
282 n
= iblock(idesc
, ilevel
, isize
);
292 if (idesc
->id_type
== DATA
&& isize
> 0) {
293 /* An empty block in a directory XXX */
294 getpathname(pathbuf
, sizeof(pathbuf
),
295 idesc
->id_number
, idesc
->id_number
);
296 pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [3]",
297 pathbuf
, (long long)idesc
->id_number
);
298 if (reply("ADJUST LENGTH") == 1) {
299 vp
= vget(fs
, idesc
->id_number
);
300 VTOI(vp
)->i_ffs1_size
-= isize
;
303 "YOU MUST RERUN FSCK AFTERWARDS\n");
324 * Check that a block in a legal block number.
325 * Return 0 if in range, 1 if out of range.
328 chkrange(daddr_t blk
, int cnt
)
330 if (blk
< sntod(fs
, 0)) {
333 if (blk
> maxfsblock
) {
336 if (blk
+ cnt
< sntod(fs
, 0)) {
339 if (blk
+ cnt
> maxfsblock
) {
346 * Routines to maintain information about directory inodes.
347 * This is built during the first pass and used during the
348 * second and third passes.
350 * Enter inodes into the cache.
353 cacheino(struct ufs1_dinode
* dp
, ino_t inumber
)
356 struct inoinfo
**inpp
, **ninpsort
;
359 blks
= howmany(dp
->di_size
, fs
->lfs_bsize
);
361 blks
= NDADDR
+ NIADDR
;
362 inp
= emalloc(sizeof(*inp
) + (blks
- 1) * sizeof(ufs_daddr_t
));
363 inpp
= &inphead
[inumber
% numdirs
];
364 inp
->i_nexthash
= *inpp
;
366 inp
->i_child
= inp
->i_sibling
= inp
->i_parentp
= 0;
367 if (inumber
== ROOTINO
)
368 inp
->i_parent
= ROOTINO
;
370 inp
->i_parent
= (ino_t
) 0;
371 inp
->i_dotdot
= (ino_t
) 0;
372 inp
->i_number
= inumber
;
373 inp
->i_isize
= dp
->di_size
;
375 inp
->i_numblks
= blks
* sizeof(ufs_daddr_t
);
376 memcpy(&inp
->i_blks
[0], &dp
->di_db
[0], (size_t) inp
->i_numblks
);
377 if (inplast
== listmax
) {
378 ninpsort
= erealloc(inpsort
,
379 (listmax
+ 100) * sizeof(struct inoinfo
*));
383 inpsort
[inplast
++] = inp
;
387 * Look up an inode cache structure.
390 getinoinfo(ino_t inumber
)
394 for (inp
= inphead
[inumber
% numdirs
]; inp
; inp
= inp
->i_nexthash
) {
395 if (inp
->i_number
!= inumber
)
399 err(EEXIT
, "cannot find inode %llu\n", (unsigned long long)inumber
);
400 return ((struct inoinfo
*) 0);
404 * Clean up all the inode cache structure.
409 struct inoinfo
**inpp
;
413 for (inpp
= &inpsort
[inplast
- 1]; inpp
>= inpsort
; inpp
--)
414 free((char *) (*inpp
));
415 free((char *) inphead
);
416 free((char *) inpsort
);
417 inphead
= inpsort
= NULL
;
421 inodirty(struct inode
*ip
)
423 ip
->i_flag
|= IN_MODIFIED
;
427 clri(struct inodesc
* idesc
, const char *type
, int flag
)
431 vp
= vget(fs
, idesc
->id_number
);
434 (VTOI(vp
)->i_ffs1_mode
& IFMT
) == IFDIR
? "DIR" : "FILE");
435 pinode(idesc
->id_number
);
437 if ((flag
& 0x2) || preen
|| reply("CLEAR") == 1) {
438 if (preen
&& flag
!= 2)
439 printf(" (CLEARED)\n");
441 (void) ckinode(VTOD(vp
), idesc
);
442 clearinode(idesc
->id_number
);
443 statemap
[idesc
->id_number
] = USTATE
;
451 clearinode(ino_t inumber
)
457 /* Send cleared inode to the free list */
459 LFS_IENTRY(ifp
, fs
, inumber
, bp
);
460 daddr
= ifp
->if_daddr
;
461 if (daddr
== LFS_UNUSED_DADDR
) {
465 ifp
->if_daddr
= LFS_UNUSED_DADDR
;
466 ifp
->if_nextfree
= fs
->lfs_freehd
;
467 fs
->lfs_freehd
= inumber
;
472 * update segment usage.
474 if (daddr
!= LFS_UNUSED_DADDR
) {
476 u_int32_t oldsn
= dtosn(fs
, daddr
);
478 seg_table
[oldsn
].su_nbytes
-= DINODE1_SIZE
;
479 LFS_SEGENTRY(sup
, fs
, oldsn
, bp
);
480 sup
->su_nbytes
-= DINODE1_SIZE
;
481 LFS_WRITESEGENTRY(sup
, fs
, oldsn
, bp
); /* Ifile */
486 findname(struct inodesc
* idesc
)
488 struct direct
*dirp
= idesc
->id_dirp
;
492 if (dirp
->d_ino
!= idesc
->id_parent
)
494 if ((len
= dirp
->d_namlen
+ 1) > MAXPATHLEN
) {
495 /* Truncate it but don't overflow the buffer */
498 /* this is namebuf with utils.h */
499 buf
= __UNCONST(idesc
->id_name
);
500 (void)memcpy(buf
, dirp
->d_name
, len
);
501 return (STOP
| FOUND
);
505 findino(struct inodesc
* idesc
)
507 struct direct
*dirp
= idesc
->id_dirp
;
509 if (dirp
->d_ino
== 0)
511 if (strcmp(dirp
->d_name
, idesc
->id_name
) == 0 &&
512 dirp
->d_ino
>= ROOTINO
&& dirp
->d_ino
< maxino
) {
513 idesc
->id_parent
= dirp
->d_ino
;
514 return (STOP
| FOUND
);
522 struct ufs1_dinode
*dp
;
527 printf(" I=%llu ", (unsigned long long)ino
);
528 if (ino
< ROOTINO
|| ino
>= maxino
)
534 if (Uflag
&& (pw
= getpwuid((int) dp
->di_uid
)) != 0)
535 printf("%s ", pw
->pw_name
);
538 printf("%u ", (unsigned) dp
->di_uid
);
539 printf("MODE=%o\n", dp
->di_mode
);
541 printf("%s: ", cdevname());
542 printf("SIZE=%llu ", (unsigned long long) dp
->di_size
);
545 printf("MTIME=%12.12s %4.4s ", &p
[4], &p
[20]);
550 blkerror(ino_t ino
, const char *type
, daddr_t blk
)
553 pfatal("%lld %s I=%llu", (long long) blk
, type
,
554 (unsigned long long)ino
);
558 switch (statemap
[ino
]) {
561 statemap
[ino
] = FCLEAR
;
565 statemap
[ino
] = DCLEAR
;
573 err(EEXIT
, "BAD STATE %d TO BLKERR\n", statemap
[ino
]);
579 * allocate an unused inode
582 allocino(ino_t request
, int type
)
585 struct ufs1_dinode
*dp
;
592 else if (statemap
[request
] != USTATE
)
594 for (ino
= request
; ino
< maxino
; ino
++)
595 if (statemap
[ino
] == USTATE
)
600 switch (type
& IFMT
) {
602 statemap
[ino
] = DSTATE
;
606 statemap
[ino
] = FSTATE
;
611 vp
= lfs_valloc(fs
, ino
);
614 dp
= (VTOI(vp
)->i_din
.ffs1_din
);
615 bp
= getblk(vp
, 0, fs
->lfs_fsize
);
620 dp
->di_mtime
= dp
->di_ctime
= dp
->di_atime
;
621 dp
->di_size
= fs
->lfs_fsize
;
622 dp
->di_blocks
= btofsb(fs
, fs
->lfs_fsize
);
625 typemap
[ino
] = IFTODT(type
);
630 * deallocate an inode
635 struct inodesc idesc
;
638 memset(&idesc
, 0, sizeof(struct inodesc
));
639 idesc
.id_type
= ADDR
;
640 idesc
.id_func
= pass4check
;
641 idesc
.id_number
= ino
;
643 (void) ckinode(VTOD(vp
), &idesc
);
645 statemap
[ino
] = USTATE
;