FreeBSD/Linux Kernel Cross Reference
sys/fs/sysvbfs/bfs.c
1 /* $NetBSD: bfs.c,v 1.6 2006/08/26 14:04:55 tsutsui Exp $ */
2
3 /*-
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40
41 __KERNEL_RCSID(0, "$NetBSD: bfs.c,v 1.6 2006/08/26 14:04:55 tsutsui Exp $");
42 #define BFS_DEBUG
43
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/types.h>
47 #include <sys/systm.h>
48 #include <sys/errno.h>
49 #include <sys/malloc.h>
50 #include <sys/time.h>
51
52 #ifdef _KERNEL
53 MALLOC_DEFINE(M_BFS, "sysvbfs core", "sysvbfs internal structures");
54 #define __MALLOC(s, t, f) malloc(s, t, f)
55 #define __FREE(a, s, t) free(a, t)
56 #elif defined _STANDALONE
57 #include <lib/libsa/stand.h>
58 #include <lib/libkern/libkern.h>
59 #define __MALLOC(s, t, f) alloc(s)
60 #define __FREE(a, s, t) dealloc(a, s)
61 #else
62 #include "local.h"
63 #define __MALLOC(s, t, f) malloc(s)
64 #define __FREE(a, s, t) free(a)
65 #endif
66 #include <fs/sysvbfs/bfs.h>
67
68 #ifdef BFS_DEBUG
69 #define DPRINTF(on, fmt, args...) if (on) printf(fmt, ##args)
70 #else
71 #define DPRINTF(arg...) ((void)0)
72 #endif
73
74 #define ROUND_SECTOR(x) (((x) + 511) & ~511)
75 #define TRUNC_SECTOR(x) ((x) & ~511)
76
77 #define STATIC
78
79 STATIC int bfs_init_superblock(struct bfs *, int, size_t *);
80 STATIC int bfs_init_inode(struct bfs *, uint8_t *, size_t *);
81 STATIC int bfs_init_dirent(struct bfs *, uint8_t *);
82
83 /* super block ops. */
84 STATIC boolean_t bfs_superblock_valid(const struct bfs_super_block *);
85 STATIC boolean_t bfs_writeback_dirent(const struct bfs *, struct bfs_dirent *,
86 boolean_t);
87 STATIC boolean_t bfs_writeback_inode(const struct bfs *, struct bfs_inode *);
88
89 int
90 bfs_init2(struct bfs **bfsp, int bfs_sector, struct sector_io_ops *io,
91 boolean_t debug)
92 {
93 struct bfs *bfs;
94 size_t memsize;
95 uint8_t *p;
96 int err;
97
98 /* 1. */
99 DPRINTF(debug, "bfs sector = %d\n", bfs_sector);
100 if ((bfs = (void *)__MALLOC(sizeof(struct bfs), M_BFS, M_NOWAIT)) == 0)
101 return ENOMEM;
102 memset(bfs, 0, sizeof *bfs);
103 bfs->io = io;
104 bfs->debug = debug;
105
106 /* 2. */
107 if ((err = bfs_init_superblock(bfs, bfs_sector, &memsize)) != 0) {
108 bfs_fini(bfs);
109 return err;
110 }
111 DPRINTF(debug, "bfs super block + inode area = %zd\n", memsize);
112 bfs->super_block_size = memsize;
113 if ((p = (void *)__MALLOC(memsize, M_BFS, M_NOWAIT)) == 0) {
114 bfs_fini(bfs);
115 return ENOMEM;
116 }
117 /* 3. */
118 if ((err = bfs_init_inode(bfs, p, &memsize)) != 0) {
119 bfs_fini(bfs);
120 return err;
121 }
122 DPRINTF(debug, "bfs dirent area = %zd\n", memsize);
123 bfs->dirent_size = memsize;
124 if ((p = (void *)__MALLOC(memsize, M_BFS, M_NOWAIT)) == 0) {
125 bfs_fini(bfs);
126 return ENOMEM;
127 }
128 /* 4. */
129 if ((err = bfs_init_dirent(bfs, p)) != 0) {
130 bfs_fini(bfs);
131 return err;
132 }
133
134 #ifdef BFS_DEBUG
135 bfs_dump(bfs);
136 #endif
137 *bfsp = bfs;
138
139 return 0;
140 }
141
142 void
143 bfs_fini(struct bfs *bfs)
144 {
145
146 if (bfs == 0)
147 return;
148 if (bfs->super_block)
149 __FREE(bfs->super_block, bfs->super_block_size, M_BFS);
150 if (bfs->dirent)
151 __FREE(bfs->dirent, bfs->dirent_size, M_BFS);
152 __FREE(bfs, sizeof(struct bfs), M_BFS);
153 }
154
155 STATIC int
156 bfs_init_superblock(struct bfs *bfs, int bfs_sector, size_t *required_memory)
157 {
158 struct bfs_super_block super;
159
160 bfs->start_sector = bfs_sector;
161
162 /* Read super block */
163 if (!bfs->io->read(bfs->io, (uint8_t *)&super, bfs_sector))
164 return EIO;
165
166 if (!bfs_superblock_valid(&super))
167 return EINVAL;
168
169 /* i-node table size */
170 bfs->data_start = super.header.data_start_byte;
171 bfs->data_end = super.header.data_end_byte;
172
173 bfs->max_inode = (bfs->data_start - sizeof(struct bfs_super_block)) /
174 sizeof(struct bfs_inode);
175
176 *required_memory = ROUND_SECTOR(bfs->data_start);
177
178 return 0;
179 }
180
181 STATIC int
182 bfs_init_inode(struct bfs *bfs, uint8_t *p, size_t *required_memory)
183 {
184 struct bfs_inode *inode, *root_inode;
185 int i;
186
187 if (!bfs->io->read_n(bfs->io, p, bfs->start_sector,
188 bfs->data_start >> DEV_BSHIFT))
189 return EIO;
190
191 bfs->super_block = (struct bfs_super_block *)p;
192 bfs->inode = (struct bfs_inode *)(p + sizeof(struct bfs_super_block));
193 p += bfs->data_start;
194
195 bfs->n_inode = 0;
196 inode = bfs->inode;
197 root_inode = 0;
198 for (i = 0; i < bfs->max_inode; i++, inode++) {
199 if (inode->number != 0) {
200 bfs->n_inode++;
201 if (inode->number == BFS_ROOT_INODE)
202 root_inode = inode;
203 }
204 }
205 DPRINTF(bfs->debug, "inode: %d/%d\n", bfs->n_inode, bfs->max_inode);
206
207 if (root_inode == 0) {
208 DPRINTF(bfs->debug, "no root directory.\n");
209 return ENOTDIR;
210 }
211 /* dirent table size */
212 DPRINTF(bfs->debug, "root inode: %d-%d\n", root_inode->start_sector,
213 root_inode->end_sector);
214 bfs->root_inode = root_inode;
215
216 *required_memory = (root_inode->end_sector -
217 root_inode->start_sector + 1) << DEV_BSHIFT;
218
219 return 0;
220 }
221
222 STATIC int
223 bfs_init_dirent(struct bfs *bfs, uint8_t *p)
224 {
225 struct bfs_dirent *file;
226 struct bfs_inode *inode = bfs->root_inode;
227 int i, n;
228
229 n = inode->end_sector - inode->start_sector + 1;
230
231 if (!bfs->io->read_n(bfs->io, p,
232 bfs->start_sector + inode->start_sector, n))
233 return EIO;
234
235 bfs->dirent = (struct bfs_dirent *)p;
236 bfs->max_dirent = (n << DEV_BSHIFT) / sizeof(struct bfs_dirent);
237
238 file = bfs->dirent;
239 bfs->n_dirent = 0;
240 for (i = 0; i < bfs->max_dirent; i++, file++)
241 if (file->inode != 0)
242 bfs->n_dirent++;
243
244 DPRINTF(bfs->debug, "dirent: %d/%d\n", bfs->n_dirent, bfs->max_dirent);
245
246 return 0;
247 }
248
249 int
250 bfs_file_read(const struct bfs *bfs, const char *fname, void *buf, size_t bufsz,
251 size_t *read_size)
252 {
253 int start, end, n;
254 size_t sz;
255 uint8_t tmpbuf[DEV_BSIZE];
256 uint8_t *p;
257
258 if (!bfs_file_lookup(bfs, fname, &start, &end, &sz))
259 return ENOENT;
260
261 if (sz > bufsz)
262 return ENOMEM;
263
264 p = buf;
265 n = end - start;
266 bfs->io->read_n(bfs->io, p, start, n);
267 /* last sector */
268 n *= DEV_BSIZE;
269 bfs->io->read(bfs->io, tmpbuf, end);
270 memcpy(p + n, tmpbuf, sz - n);
271
272 if (read_size)
273 *read_size = sz;
274
275 return 0;
276 }
277
278 int
279 bfs_file_write(struct bfs *bfs, const char *fname, void *buf,
280 size_t bufsz)
281 {
282 struct bfs_fileattr attr;
283 struct bfs_dirent *dirent;
284 char name[BFS_FILENAME_MAXLEN];
285 int err;
286
287 strncpy(name, fname, BFS_FILENAME_MAXLEN);
288
289 if (bfs_dirent_lookup_by_name(bfs, name, &dirent)) {
290 struct bfs_inode *inode;
291 if (!bfs_inode_lookup(bfs, dirent->inode, &inode)) {
292 DPRINTF(bfs->debug, "%s: dirent found, but inode "
293 "not found. inconsistent filesystem.\n",
294 __FUNCTION__);
295 return ENOENT;
296 }
297 attr = inode->attr; /* copy old attribute */
298 bfs_file_delete(bfs, name);
299 if ((err = bfs_file_create(bfs, name, buf, bufsz, &attr)) != 0)
300 return err;
301 } else {
302 memset(&attr, 0xff, sizeof attr); /* Set VNOVAL all */
303 #ifdef _KERNEL
304 attr.atime = time_second;
305 attr.ctime = time_second;
306 attr.mtime = time_second;
307 #endif
308 if ((err = bfs_file_create(bfs, name, buf, bufsz, &attr)) != 0)
309 return err;
310 }
311
312 return 0;
313 }
314
315 int
316 bfs_file_delete(struct bfs *bfs, const char *fname)
317 {
318 struct bfs_inode *inode;
319 struct bfs_dirent *dirent;
320
321 if (!bfs_dirent_lookup_by_name(bfs, fname, &dirent))
322 return ENOENT;
323
324 if (!bfs_inode_lookup(bfs, dirent->inode, &inode))
325 return ENOENT;
326
327 memset(dirent, 0, sizeof *dirent);
328 memset(inode, 0, sizeof *inode);
329 bfs->n_inode--;
330 bfs->n_dirent--;
331
332 bfs_writeback_dirent(bfs, dirent, FALSE);
333 bfs_writeback_inode(bfs, inode);
334 DPRINTF(bfs->debug, "%s: \"%s\" deleted.\n", __FUNCTION__, fname);
335
336 return 0;
337 }
338
339 int
340 bfs_file_rename(struct bfs *bfs, const char *from_name, const char *to_name)
341 {
342 struct bfs_dirent *dirent;
343 int err = 0;
344
345 if (strlen(to_name) > BFS_FILENAME_MAXLEN) {
346 err = ENAMETOOLONG;
347 goto out;
348 }
349 if (!bfs_dirent_lookup_by_name(bfs, from_name, &dirent)) {
350 err = ENOENT;
351 goto out;
352 }
353
354 bfs_file_delete(bfs, to_name);
355 strncpy(dirent->name, to_name, BFS_FILENAME_MAXLEN);
356 bfs_writeback_dirent(bfs, dirent, FALSE);
357
358 out:
359 DPRINTF(bfs->debug, "%s: \"%s\" -> \"%s\" error=%d.\n", __FUNCTION__,
360 from_name, to_name, err);
361
362 return err;
363 }
364
365 int
366 bfs_file_create(struct bfs *bfs, const char *fname, void *buf, size_t bufsz,
367 const struct bfs_fileattr *attr)
368 {
369 struct bfs_inode *inode;
370 struct bfs_dirent *file;
371 int i, j, n, start;
372 uint8_t *p, tmpbuf[DEV_BSIZE];
373 int err;
374
375 /* Find free i-node and data block */
376 if ((err = bfs_inode_alloc(bfs, &inode, &j, &start)) != 0)
377 return err;
378
379 /* File size (unit block) */
380 n = (ROUND_SECTOR(bufsz) >> DEV_BSHIFT) - 1;
381 if (n < 0) /* bufsz == 0 */
382 n = 0;
383
384 if ((start + n) * DEV_BSIZE >= bfs->data_end) {
385 DPRINTF(bfs->debug, "disk full.\n");
386 return ENOSPC;
387 }
388
389 /* Find free dirent */
390 for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
391 if (file->inode == 0)
392 break;
393 if (i == bfs->max_dirent) {
394 DPRINTF(bfs->debug, "dirent full.\n");
395 return ENOSPC;
396 }
397
398 /* i-node */
399 memset(inode, 0, sizeof *inode);
400 inode->number = j;
401 inode->start_sector = start;
402 inode->end_sector = start + n;
403 inode->eof_offset_byte = start * DEV_BSIZE + bufsz - 1;
404 /* i-node attribute */
405 inode->attr.type = 1;
406 inode->attr.mode = 0;
407 inode->attr.nlink = 1;
408 bfs_inode_set_attr(bfs, inode, attr);
409
410 /* Dirent */
411 memset(file, 0, sizeof *file);
412 file->inode = inode->number;
413 strncpy(file->name, fname, BFS_FILENAME_MAXLEN);
414
415 DPRINTF(bfs->debug, "%s: start %d end %d\n", __FUNCTION__,
416 inode->start_sector, inode->end_sector);
417
418 if (buf != 0) {
419 p = (uint8_t *)buf;
420 /* Data block */
421 n = 0;
422 for (i = inode->start_sector; i < inode->end_sector; i++) {
423 if (!bfs->io->write(bfs->io, p, bfs->start_sector + i))
424 return EIO;
425 p += DEV_BSIZE;
426 n += DEV_BSIZE;
427 }
428 /* last sector */
429 memset(tmpbuf, 0, DEV_BSIZE);
430 memcpy(tmpbuf, p, bufsz - n);
431 if (!bfs->io->write(bfs->io, tmpbuf, bfs->start_sector + i))
432 return EIO;
433 }
434 /* Update */
435 bfs->n_inode++;
436 bfs->n_dirent++;
437 bfs_writeback_dirent(bfs, file, TRUE);
438 bfs_writeback_inode(bfs, inode);
439
440 return 0;
441 }
442
443 STATIC boolean_t
444 bfs_writeback_dirent(const struct bfs *bfs, struct bfs_dirent *dir,
445 boolean_t create)
446 {
447 struct bfs_dirent *dir_base = bfs->dirent;
448 struct bfs_inode *root_inode = bfs->root_inode;
449 uintptr_t eof;
450 int i;
451
452 i = ((dir - dir_base) * sizeof *dir) >> DEV_BSHIFT;
453
454 eof = (uintptr_t)(dir + 1) - 1;
455 eof = eof - (uintptr_t)dir_base +
456 (root_inode->start_sector << DEV_BSHIFT);
457
458 /* update root directory inode */
459 #if 0
460 printf("eof new=%d old=%d\n", eof, root_inode->eof_offset_byte);
461 #endif
462 if (create) {
463 if (eof > root_inode->eof_offset_byte) {
464 root_inode->eof_offset_byte = eof;
465 }
466 } else {
467 /* delete the last entry */
468 if (eof == root_inode->eof_offset_byte) {
469 root_inode->eof_offset_byte = eof - sizeof *dir;
470 }
471 }
472 bfs_writeback_inode(bfs, root_inode);
473
474 /* update dirent */
475 return bfs->io->write(bfs->io, (uint8_t *)dir_base + (i << DEV_BSHIFT),
476 bfs->start_sector + bfs->root_inode->start_sector + i);
477 }
478
479 STATIC boolean_t
480 bfs_writeback_inode(const struct bfs *bfs, struct bfs_inode *inode)
481 {
482 struct bfs_inode *inode_base = bfs->inode;
483 int i;
484
485 i = ((inode - inode_base) * sizeof *inode) >> DEV_BSHIFT;
486
487 return bfs->io->write(bfs->io,
488 (uint8_t *)inode_base + (i << DEV_BSHIFT),
489 bfs->start_sector + 1/*super block*/ + i);
490 }
491
492 boolean_t
493 bfs_file_lookup(const struct bfs *bfs, const char *fname, int *start, int *end,
494 size_t *size)
495 {
496 struct bfs_inode *inode;
497 struct bfs_dirent *dirent;
498
499 if (!bfs_dirent_lookup_by_name(bfs, fname, &dirent))
500 return FALSE;
501 if (!bfs_inode_lookup(bfs, dirent->inode, &inode))
502 return FALSE;
503
504 if (start)
505 *start = inode->start_sector + bfs->start_sector;
506 if (end)
507 *end = inode->end_sector + bfs->start_sector;
508 if (size)
509 *size = bfs_file_size(inode);
510
511 DPRINTF(bfs->debug, "%s: %d + %d -> %d (%zd)\n",
512 fname, bfs->start_sector, inode->start_sector,
513 inode->end_sector, *size);
514
515 return TRUE;
516 }
517
518 boolean_t
519 bfs_dirent_lookup_by_inode(const struct bfs *bfs, int inode,
520 struct bfs_dirent **dirent)
521 {
522 struct bfs_dirent *file;
523 int i;
524
525 for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
526 if (file->inode == inode)
527 break;
528
529 if (i == bfs->max_dirent)
530 return FALSE;
531
532 *dirent = file;
533
534 return TRUE;
535 }
536
537 boolean_t
538 bfs_dirent_lookup_by_name(const struct bfs *bfs, const char *fname,
539 struct bfs_dirent **dirent)
540 {
541 struct bfs_dirent *file;
542 int i;
543
544 for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
545 if ((file->inode != 0) &&
546 (strncmp(file->name, fname, BFS_FILENAME_MAXLEN) ==0))
547 break;
548
549 if (i == bfs->max_dirent)
550 return FALSE;
551
552 *dirent = file;
553
554 return TRUE;
555 }
556
557 boolean_t
558 bfs_inode_lookup(const struct bfs *bfs, ino_t n, struct bfs_inode **iinode)
559 {
560 struct bfs_inode *inode;
561 int i;
562
563 for (inode = bfs->inode, i = 0; i < bfs->max_inode; i++, inode++)
564 if (inode->number == n)
565 break;
566
567 if (i == bfs->max_inode)
568 return FALSE;
569
570 *iinode = inode;
571
572 return TRUE;
573 }
574
575 size_t
576 bfs_file_size(const struct bfs_inode *inode)
577 {
578
579 return inode->eof_offset_byte - inode->start_sector * DEV_BSIZE + 1;
580 }
581
582 STATIC int
583 bfs_inode_alloc(const struct bfs *bfs, struct bfs_inode **free_inode,
584 int *free_inode_number, int *free_block)
585 {
586 struct bfs_inode *jnode, *inode;
587 int i, j, start;
588
589 j = start = 0;
590 inode = bfs->inode;
591 jnode = 0;
592
593 for (i = BFS_ROOT_INODE; i < bfs->max_inode; i++, inode++) {
594 /* Steal i-node # */
595 if (j == 0)
596 j = i;
597
598 /* Get free i-node */
599 if (jnode == 0 && (inode->number == 0))
600 jnode = inode;
601
602 /* Get free i-node # and data block */
603 if (inode->number != 0) {
604 if (inode->end_sector > start)
605 start = inode->end_sector;
606 if (inode->number == j)
607 j = 0; /* conflict */
608 }
609 }
610 start++;
611
612 if (jnode == 0) {
613 DPRINTF(bfs->debug, "i-node full.\n");
614 return ENOSPC;
615 }
616
617 if (start * DEV_BSIZE >= bfs->data_end) {
618 DPRINTF(bfs->debug, "data block full.\n");
619 /* compaction here ? */
620 return ENOSPC;
621 }
622 if (free_inode)
623 *free_inode = jnode;
624 if (free_inode_number)
625 *free_inode_number = j;
626 if (free_block)
627 *free_block = start;
628
629 return 0;
630 }
631
632 void
633 bfs_inode_set_attr(const struct bfs *bfs, struct bfs_inode *inode,
634 const struct bfs_fileattr *from)
635 {
636 struct bfs_fileattr *to = &inode->attr;
637
638 if (from != NULL) {
639 if (from->uid != (uid_t)-1)
640 to->uid = from->uid;
641 if (from->gid != (uid_t)-1)
642 to->gid = from->gid;
643 if (from->mode != (mode_t)-1)
644 to->mode = from->mode;
645 if (from->atime != -1)
646 to->atime = from->atime;
647 if (from->ctime != -1)
648 to->ctime = from->ctime;
649 if (from->mtime != -1)
650 to->mtime = from->mtime;
651 }
652 bfs_writeback_inode(bfs, inode);
653 }
654
655 STATIC boolean_t
656 bfs_superblock_valid(const struct bfs_super_block *super)
657 {
658
659 return super->header.magic == BFS_MAGIC;
660 }
661
662 boolean_t
663 bfs_dump(const struct bfs *bfs)
664 {
665 const struct bfs_super_block_header *h;
666 const struct bfs_compaction *compaction;
667 const struct bfs_inode *inode;
668 struct bfs_dirent *file;
669 int i, j, s, e;
670 size_t bytes;
671
672 if (!bfs_superblock_valid(bfs->super_block)) {
673 DPRINTF(bfs->debug, "invalid bfs super block.\n");
674 return FALSE;
675 }
676 h = &bfs->super_block->header;
677 compaction = &bfs->super_block->compaction;
678
679 DPRINTF(bfs->debug, "super block %zdbyte, inode %zdbyte, dirent %zdbyte\n",
680 sizeof *bfs->super_block, sizeof *inode, sizeof *file);
681
682 DPRINTF(bfs->debug, "magic=%x\n", h->magic);
683 DPRINTF(bfs->debug, "data_start_byte=0x%x\n", h->data_start_byte);
684 DPRINTF(bfs->debug, "data_end_byte=0x%x\n", h->data_end_byte);
685 DPRINTF(bfs->debug, "from=%#x\n", compaction->from);
686 DPRINTF(bfs->debug, "to=%#x\n", compaction->to);
687 DPRINTF(bfs->debug, "from_backup=%#x\n", compaction->from_backup);
688 DPRINTF(bfs->debug, "to_backup=%#x\n", compaction->to_backup);
689 DPRINTF(bfs->debug, "fsname=%s\n", bfs->super_block->fsname);
690 DPRINTF(bfs->debug, "volume=%s\n", bfs->super_block->volume);
691
692 /* inode list */
693 DPRINTF(bfs->debug, "[inode index list]\n");
694 for (inode = bfs->inode, i = j = 0; i < bfs->max_inode; inode++, i++) {
695 if (inode->number != 0) {
696 const struct bfs_fileattr *attr = &inode->attr;
697 DPRINTF(bfs->debug, "%3d %8d %8d %8d (%d) ",
698 inode->number,
699 inode->eof_offset_byte -
700 (inode->start_sector * DEV_BSIZE) + 1,/* file size*/
701 inode->start_sector,
702 inode->end_sector, i);
703
704 DPRINTF(bfs->debug, "%d %d %d %d %d %08x %08x %08x\n",
705 attr->type, attr->mode, attr->uid, attr->gid,
706 attr->nlink, attr->atime, attr->mtime, attr->ctime);
707 j++;
708 }
709 }
710 if (j != bfs->n_inode) {
711 DPRINTF(bfs->debug, "inconsistent cached data. (i-node)\n");
712 return FALSE;
713 }
714 DPRINTF(bfs->debug, "total %d i-node.\n", j);
715
716 /* file list */
717 DPRINTF(bfs->debug, "[dirent index list]\n");
718 DPRINTF(bfs->debug, "%d file entries.\n", bfs->max_dirent);
719 file = bfs->dirent;
720 for (i = j = 0; i < bfs->max_dirent; i++, file++) {
721 if (file->inode != 0) {
722 if (bfs_file_lookup(bfs, file->name, &s, &e, &bytes))
723 DPRINTF(bfs->debug, "%3d %14s %8d %8d %8zd\n",
724 file->inode, file->name, s, e, bytes);
725 j++;
726 }
727 }
728 if (j != bfs->n_dirent) {
729 DPRINTF(bfs->debug, "inconsistent cached data. (dirent)\n");
730 return FALSE;
731 }
732 DPRINTF(bfs->debug, "%d files.\n", j);
733
734 return TRUE;
735 }
Cache object: 0fcf6df014d05606f834d3dc975bcb13
|