Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / fs / sysvbfs / bfs.c
bloba62f135014fc101f132e71752180db5741b0d330
1 /* $NetBSD: bfs.c,v 1.11 2008/04/28 20:24:02 martin Exp $ */
3 /*-
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
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.
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.
32 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: bfs.c,v 1.11 2008/04/28 20:24:02 martin Exp $");
35 #define BFS_DEBUG
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/types.h>
40 #include <sys/systm.h>
41 #include <sys/errno.h>
42 #include <sys/malloc.h>
43 #include <sys/time.h>
45 #ifdef _KERNEL
46 MALLOC_JUSTDEFINE(M_BFS, "sysvbfs core", "sysvbfs internal structures");
47 #define __MALLOC(s, t, f) malloc(s, t, f)
48 #define __FREE(a, s, t) free(a, t)
49 #elif defined _STANDALONE
50 #include <lib/libsa/stand.h>
51 #include <lib/libkern/libkern.h>
52 #define __MALLOC(s, t, f) alloc(s)
53 #define __FREE(a, s, t) dealloc(a, s)
54 #else
55 #include "local.h"
56 #define __MALLOC(s, t, f) malloc(s)
57 #define __FREE(a, s, t) free(a)
58 #endif
59 #include <fs/sysvbfs/bfs.h>
61 #ifdef BFS_DEBUG
62 #define DPRINTF(on, fmt, args...) if (on) printf(fmt, ##args)
63 #else
64 #define DPRINTF(arg...) ((void)0)
65 #endif
67 #define ROUND_SECTOR(x) (((x) + 511) & ~511)
68 #define TRUNC_SECTOR(x) ((x) & ~511)
70 #define STATIC
72 STATIC int bfs_init_superblock(struct bfs *, int, size_t *);
73 STATIC int bfs_init_inode(struct bfs *, uint8_t *, size_t *);
74 STATIC int bfs_init_dirent(struct bfs *, uint8_t *);
76 /* super block ops. */
77 STATIC bool bfs_superblock_valid(const struct bfs_super_block *);
78 STATIC bool bfs_writeback_dirent(const struct bfs *, struct bfs_dirent *,
79 bool);
80 STATIC bool bfs_writeback_inode(const struct bfs *, struct bfs_inode *);
82 int
83 bfs_init2(struct bfs **bfsp, int bfs_sector, struct sector_io_ops *io,
84 bool debug)
86 struct bfs *bfs;
87 size_t memsize;
88 uint8_t *p;
89 int err;
91 /* 1. */
92 DPRINTF(debug, "bfs sector = %d\n", bfs_sector);
93 if ((bfs = (void *)__MALLOC(sizeof(struct bfs), M_BFS, M_NOWAIT)) == 0)
94 return ENOMEM;
95 memset(bfs, 0, sizeof *bfs);
96 bfs->io = io;
97 bfs->debug = debug;
99 /* 2. */
100 if ((err = bfs_init_superblock(bfs, bfs_sector, &memsize)) != 0) {
101 bfs_fini(bfs);
102 return err;
104 DPRINTF(debug, "bfs super block + inode area = %zd\n", memsize);
105 bfs->super_block_size = memsize;
106 if ((p = (void *)__MALLOC(memsize, M_BFS, M_NOWAIT)) == 0) {
107 bfs_fini(bfs);
108 return ENOMEM;
110 /* 3. */
111 if ((err = bfs_init_inode(bfs, p, &memsize)) != 0) {
112 bfs_fini(bfs);
113 return err;
115 DPRINTF(debug, "bfs dirent area = %zd\n", memsize);
116 bfs->dirent_size = memsize;
117 if ((p = (void *)__MALLOC(memsize, M_BFS, M_NOWAIT)) == 0) {
118 bfs_fini(bfs);
119 return ENOMEM;
121 /* 4. */
122 if ((err = bfs_init_dirent(bfs, p)) != 0) {
123 bfs_fini(bfs);
124 return err;
127 #ifdef BFS_DEBUG
128 bfs_dump(bfs);
129 #endif
130 *bfsp = bfs;
132 return 0;
135 void
136 bfs_fini(struct bfs *bfs)
139 if (bfs == 0)
140 return;
141 if (bfs->super_block)
142 __FREE(bfs->super_block, bfs->super_block_size, M_BFS);
143 if (bfs->dirent)
144 __FREE(bfs->dirent, bfs->dirent_size, M_BFS);
145 __FREE(bfs, sizeof(struct bfs), M_BFS);
148 STATIC int
149 bfs_init_superblock(struct bfs *bfs, int bfs_sector, size_t *required_memory)
151 struct bfs_super_block super;
153 bfs->start_sector = bfs_sector;
155 /* Read super block */
156 if (!bfs->io->read(bfs->io, (uint8_t *)&super, bfs_sector))
157 return EIO;
159 if (!bfs_superblock_valid(&super))
160 return EINVAL;
162 /* i-node table size */
163 bfs->data_start = super.header.data_start_byte;
164 bfs->data_end = super.header.data_end_byte;
166 bfs->max_inode = (bfs->data_start - sizeof(struct bfs_super_block)) /
167 sizeof(struct bfs_inode);
169 *required_memory = ROUND_SECTOR(bfs->data_start);
171 return 0;
174 STATIC int
175 bfs_init_inode(struct bfs *bfs, uint8_t *p, size_t *required_memory)
177 struct bfs_inode *inode, *root_inode;
178 int i;
180 if (!bfs->io->read_n(bfs->io, p, bfs->start_sector,
181 bfs->data_start >> DEV_BSHIFT))
182 return EIO;
184 bfs->super_block = (struct bfs_super_block *)p;
185 bfs->inode = (struct bfs_inode *)(p + sizeof(struct bfs_super_block));
186 p += bfs->data_start;
188 bfs->n_inode = 0;
189 inode = bfs->inode;
190 root_inode = 0;
191 for (i = 0; i < bfs->max_inode; i++, inode++) {
192 if (inode->number != 0) {
193 bfs->n_inode++;
194 if (inode->number == BFS_ROOT_INODE)
195 root_inode = inode;
198 DPRINTF(bfs->debug, "inode: %d/%d\n", bfs->n_inode, bfs->max_inode);
200 if (root_inode == 0) {
201 DPRINTF(bfs->debug, "no root directory.\n");
202 return ENOTDIR;
204 /* dirent table size */
205 DPRINTF(bfs->debug, "root inode: %d-%d\n", root_inode->start_sector,
206 root_inode->end_sector);
207 bfs->root_inode = root_inode;
209 *required_memory = (root_inode->end_sector -
210 root_inode->start_sector + 1) << DEV_BSHIFT;
212 return 0;
215 STATIC int
216 bfs_init_dirent(struct bfs *bfs, uint8_t *p)
218 struct bfs_dirent *file;
219 struct bfs_inode *inode = bfs->root_inode;
220 int i, n;
222 n = inode->end_sector - inode->start_sector + 1;
224 if (!bfs->io->read_n(bfs->io, p,
225 bfs->start_sector + inode->start_sector, n))
226 return EIO;
228 bfs->dirent = (struct bfs_dirent *)p;
229 bfs->max_dirent = (n << DEV_BSHIFT) / sizeof(struct bfs_dirent);
231 file = bfs->dirent;
232 bfs->n_dirent = 0;
233 for (i = 0; i < bfs->max_dirent; i++, file++)
234 if (file->inode != 0)
235 bfs->n_dirent++;
237 DPRINTF(bfs->debug, "dirent: %d/%d\n", bfs->n_dirent, bfs->max_dirent);
239 return 0;
243 bfs_file_read(const struct bfs *bfs, const char *fname, void *buf, size_t bufsz,
244 size_t *read_size)
246 int start, end, n;
247 size_t sz;
248 uint8_t tmpbuf[DEV_BSIZE];
249 uint8_t *p;
251 if (!bfs_file_lookup(bfs, fname, &start, &end, &sz))
252 return ENOENT;
254 if (sz > bufsz)
255 return ENOMEM;
257 p = buf;
258 n = end - start;
259 if (!bfs->io->read_n(bfs->io, p, start, n))
260 return EIO;
261 /* last sector */
262 n *= DEV_BSIZE;
263 if (!bfs->io->read(bfs->io, tmpbuf, end))
264 return EIO;
265 memcpy(p + n, tmpbuf, sz - n);
267 if (read_size)
268 *read_size = sz;
270 return 0;
274 bfs_file_write(struct bfs *bfs, const char *fname, void *buf,
275 size_t bufsz)
277 struct bfs_fileattr attr;
278 struct bfs_dirent *dirent;
279 char name[BFS_FILENAME_MAXLEN];
280 int err;
282 strncpy(name, fname, BFS_FILENAME_MAXLEN);
284 if (bfs_dirent_lookup_by_name(bfs, name, &dirent)) {
285 struct bfs_inode *inode;
286 if (!bfs_inode_lookup(bfs, dirent->inode, &inode)) {
287 DPRINTF(bfs->debug, "%s: dirent found, but inode "
288 "not found. inconsistent filesystem.\n",
289 __func__);
290 return ENOENT;
292 attr = inode->attr; /* copy old attribute */
293 bfs_file_delete(bfs, name);
294 if ((err = bfs_file_create(bfs, name, buf, bufsz, &attr)) != 0)
295 return err;
296 } else {
297 memset(&attr, 0xff, sizeof attr); /* Set VNOVAL all */
298 #ifdef _KERNEL
299 attr.atime = time_second;
300 attr.ctime = time_second;
301 attr.mtime = time_second;
302 #endif
303 if ((err = bfs_file_create(bfs, name, buf, bufsz, &attr)) != 0)
304 return err;
307 return 0;
311 bfs_file_delete(struct bfs *bfs, const char *fname)
313 struct bfs_inode *inode;
314 struct bfs_dirent *dirent;
316 if (!bfs_dirent_lookup_by_name(bfs, fname, &dirent))
317 return ENOENT;
319 if (!bfs_inode_lookup(bfs, dirent->inode, &inode))
320 return ENOENT;
322 memset(dirent, 0, sizeof *dirent);
323 memset(inode, 0, sizeof *inode);
324 bfs->n_inode--;
325 bfs->n_dirent--;
327 bfs_writeback_dirent(bfs, dirent, false);
328 bfs_writeback_inode(bfs, inode);
329 DPRINTF(bfs->debug, "%s: \"%s\" deleted.\n", __func__, fname);
331 return 0;
335 bfs_file_rename(struct bfs *bfs, const char *from_name, const char *to_name)
337 struct bfs_dirent *dirent;
338 int err = 0;
340 if (strlen(to_name) > BFS_FILENAME_MAXLEN) {
341 err = ENAMETOOLONG;
342 goto out;
344 if (!bfs_dirent_lookup_by_name(bfs, from_name, &dirent)) {
345 err = ENOENT;
346 goto out;
349 bfs_file_delete(bfs, to_name);
350 strncpy(dirent->name, to_name, BFS_FILENAME_MAXLEN);
351 bfs_writeback_dirent(bfs, dirent, false);
353 out:
354 DPRINTF(bfs->debug, "%s: \"%s\" -> \"%s\" error=%d.\n", __func__,
355 from_name, to_name, err);
357 return err;
361 bfs_file_create(struct bfs *bfs, const char *fname, void *buf, size_t bufsz,
362 const struct bfs_fileattr *attr)
364 struct bfs_inode *inode;
365 struct bfs_dirent *file;
366 int i, j, n, start;
367 uint8_t *p, tmpbuf[DEV_BSIZE];
368 int err;
370 /* Find free i-node and data block */
371 if ((err = bfs_inode_alloc(bfs, &inode, &j, &start)) != 0)
372 return err;
374 /* File size (unit block) */
375 n = (ROUND_SECTOR(bufsz) >> DEV_BSHIFT) - 1;
376 if (n < 0) /* bufsz == 0 */
377 n = 0;
379 if ((start + n) * DEV_BSIZE >= bfs->data_end) {
380 DPRINTF(bfs->debug, "disk full.\n");
381 return ENOSPC;
384 /* Find free dirent */
385 for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
386 if (file->inode == 0)
387 break;
388 if (i == bfs->max_dirent) {
389 DPRINTF(bfs->debug, "dirent full.\n");
390 return ENOSPC;
393 /* i-node */
394 memset(inode, 0, sizeof *inode);
395 inode->number = j;
396 inode->start_sector = start;
397 inode->end_sector = start + n;
398 inode->eof_offset_byte = start * DEV_BSIZE + bufsz - 1;
399 /* i-node attribute */
400 inode->attr.type = 1;
401 inode->attr.mode = 0;
402 inode->attr.nlink = 1;
403 bfs_inode_set_attr(bfs, inode, attr);
405 /* Dirent */
406 memset(file, 0, sizeof *file);
407 file->inode = inode->number;
408 strncpy(file->name, fname, BFS_FILENAME_MAXLEN);
410 DPRINTF(bfs->debug, "%s: start %d end %d\n", __func__,
411 inode->start_sector, inode->end_sector);
413 if (buf != 0) {
414 p = (uint8_t *)buf;
415 /* Data block */
416 n = 0;
417 for (i = inode->start_sector; i < inode->end_sector; i++) {
418 if (!bfs->io->write(bfs->io, p, bfs->start_sector + i))
419 return EIO;
420 p += DEV_BSIZE;
421 n += DEV_BSIZE;
423 /* last sector */
424 memset(tmpbuf, 0, DEV_BSIZE);
425 memcpy(tmpbuf, p, bufsz - n);
426 if (!bfs->io->write(bfs->io, tmpbuf, bfs->start_sector + i))
427 return EIO;
429 /* Update */
430 bfs->n_inode++;
431 bfs->n_dirent++;
432 bfs_writeback_dirent(bfs, file, true);
433 bfs_writeback_inode(bfs, inode);
435 return 0;
438 STATIC bool
439 bfs_writeback_dirent(const struct bfs *bfs, struct bfs_dirent *dir,
440 bool create)
442 struct bfs_dirent *dir_base = bfs->dirent;
443 struct bfs_inode *root_inode = bfs->root_inode;
444 uintptr_t eof;
445 int i;
447 i = ((dir - dir_base) * sizeof *dir) >> DEV_BSHIFT;
449 eof = (uintptr_t)(dir + 1) - 1;
450 eof = eof - (uintptr_t)dir_base +
451 (root_inode->start_sector << DEV_BSHIFT);
453 /* update root directory inode */
454 #if 0
455 printf("eof new=%d old=%d\n", eof, root_inode->eof_offset_byte);
456 #endif
457 if (create) {
458 if (eof > root_inode->eof_offset_byte) {
459 root_inode->eof_offset_byte = eof;
461 } else {
462 /* delete the last entry */
463 if (eof == root_inode->eof_offset_byte) {
464 root_inode->eof_offset_byte = eof - sizeof *dir;
467 bfs_writeback_inode(bfs, root_inode);
469 /* update dirent */
470 return bfs->io->write(bfs->io, (uint8_t *)dir_base + (i << DEV_BSHIFT),
471 bfs->start_sector + bfs->root_inode->start_sector + i);
474 STATIC bool
475 bfs_writeback_inode(const struct bfs *bfs, struct bfs_inode *inode)
477 struct bfs_inode *inode_base = bfs->inode;
478 int i;
480 i = ((inode - inode_base) * sizeof *inode) >> DEV_BSHIFT;
482 return bfs->io->write(bfs->io,
483 (uint8_t *)inode_base + (i << DEV_BSHIFT),
484 bfs->start_sector + 1/*super block*/ + i);
487 bool
488 bfs_file_lookup(const struct bfs *bfs, const char *fname, int *start, int *end,
489 size_t *size)
491 struct bfs_inode *inode;
492 struct bfs_dirent *dirent;
494 if (!bfs_dirent_lookup_by_name(bfs, fname, &dirent))
495 return false;
496 if (!bfs_inode_lookup(bfs, dirent->inode, &inode))
497 return false;
499 if (start)
500 *start = inode->start_sector + bfs->start_sector;
501 if (end)
502 *end = inode->end_sector + bfs->start_sector;
503 if (size)
504 *size = bfs_file_size(inode);
506 DPRINTF(bfs->debug, "%s: %d + %d -> %d (%zd)\n",
507 fname, bfs->start_sector, inode->start_sector,
508 inode->end_sector, *size);
510 return true;
513 bool
514 bfs_dirent_lookup_by_inode(const struct bfs *bfs, int inode,
515 struct bfs_dirent **dirent)
517 struct bfs_dirent *file;
518 int i;
520 for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
521 if (file->inode == inode)
522 break;
524 if (i == bfs->max_dirent)
525 return false;
527 *dirent = file;
529 return true;
532 bool
533 bfs_dirent_lookup_by_name(const struct bfs *bfs, const char *fname,
534 struct bfs_dirent **dirent)
536 struct bfs_dirent *file;
537 int i;
539 for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
540 if ((file->inode != 0) &&
541 (strncmp(file->name, fname, BFS_FILENAME_MAXLEN) ==0))
542 break;
544 if (i == bfs->max_dirent)
545 return false;
547 *dirent = file;
549 return true;
552 bool
553 bfs_inode_lookup(const struct bfs *bfs, ino_t n, struct bfs_inode **iinode)
555 struct bfs_inode *inode;
556 int i;
558 for (inode = bfs->inode, i = 0; i < bfs->max_inode; i++, inode++)
559 if (inode->number == n)
560 break;
562 if (i == bfs->max_inode)
563 return false;
565 *iinode = inode;
567 return true;
570 size_t
571 bfs_file_size(const struct bfs_inode *inode)
574 return inode->eof_offset_byte - inode->start_sector * DEV_BSIZE + 1;
577 STATIC int
578 bfs_inode_alloc(const struct bfs *bfs, struct bfs_inode **free_inode,
579 int *free_inode_number, int *free_block)
581 struct bfs_inode *jnode, *inode;
582 int i, j, start;
584 j = start = 0;
585 inode = bfs->inode;
586 jnode = 0;
588 for (i = BFS_ROOT_INODE; i < bfs->max_inode; i++, inode++) {
589 /* Steal i-node # */
590 if (j == 0)
591 j = i;
593 /* Get free i-node */
594 if (jnode == 0 && (inode->number == 0))
595 jnode = inode;
597 /* Get free i-node # and data block */
598 if (inode->number != 0) {
599 if (inode->end_sector > start)
600 start = inode->end_sector;
601 if (inode->number == j)
602 j = 0; /* conflict */
605 start++;
607 if (jnode == 0) {
608 DPRINTF(bfs->debug, "i-node full.\n");
609 return ENOSPC;
612 if (start * DEV_BSIZE >= bfs->data_end) {
613 DPRINTF(bfs->debug, "data block full.\n");
614 /* compaction here ? */
615 return ENOSPC;
617 if (free_inode)
618 *free_inode = jnode;
619 if (free_inode_number)
620 *free_inode_number = j;
621 if (free_block)
622 *free_block = start;
624 return 0;
627 void
628 bfs_inode_set_attr(const struct bfs *bfs, struct bfs_inode *inode,
629 const struct bfs_fileattr *from)
631 struct bfs_fileattr *to = &inode->attr;
633 if (from != NULL) {
634 if (from->uid != (uid_t)-1)
635 to->uid = from->uid;
636 if (from->gid != (uid_t)-1)
637 to->gid = from->gid;
638 if (from->mode != (mode_t)-1)
639 to->mode = from->mode;
640 if (from->atime != -1)
641 to->atime = from->atime;
642 if (from->ctime != -1)
643 to->ctime = from->ctime;
644 if (from->mtime != -1)
645 to->mtime = from->mtime;
647 bfs_writeback_inode(bfs, inode);
650 STATIC bool
651 bfs_superblock_valid(const struct bfs_super_block *super)
654 return super->header.magic == BFS_MAGIC;
657 bool
658 bfs_dump(const struct bfs *bfs)
660 const struct bfs_super_block_header *h;
661 const struct bfs_compaction *compaction;
662 const struct bfs_inode *inode;
663 struct bfs_dirent *file;
664 int i, j, s, e;
665 size_t bytes;
667 if (!bfs_superblock_valid(bfs->super_block)) {
668 DPRINTF(bfs->debug, "invalid bfs super block.\n");
669 return false;
671 h = &bfs->super_block->header;
672 compaction = &bfs->super_block->compaction;
674 DPRINTF(bfs->debug, "super block %zdbyte, inode %zdbyte, dirent %zdbyte\n",
675 sizeof *bfs->super_block, sizeof *inode, sizeof *file);
677 DPRINTF(bfs->debug, "magic=%x\n", h->magic);
678 DPRINTF(bfs->debug, "data_start_byte=0x%x\n", h->data_start_byte);
679 DPRINTF(bfs->debug, "data_end_byte=0x%x\n", h->data_end_byte);
680 DPRINTF(bfs->debug, "from=%#x\n", compaction->from);
681 DPRINTF(bfs->debug, "to=%#x\n", compaction->to);
682 DPRINTF(bfs->debug, "from_backup=%#x\n", compaction->from_backup);
683 DPRINTF(bfs->debug, "to_backup=%#x\n", compaction->to_backup);
684 DPRINTF(bfs->debug, "fsname=%s\n", bfs->super_block->fsname);
685 DPRINTF(bfs->debug, "volume=%s\n", bfs->super_block->volume);
687 /* inode list */
688 DPRINTF(bfs->debug, "[inode index list]\n");
689 for (inode = bfs->inode, i = j = 0; i < bfs->max_inode; inode++, i++) {
690 if (inode->number != 0) {
691 const struct bfs_fileattr *attr = &inode->attr;
692 DPRINTF(bfs->debug, "%3d %8d %8d %8d (%d) ",
693 inode->number,
694 inode->eof_offset_byte -
695 (inode->start_sector * DEV_BSIZE) + 1,/* file size*/
696 inode->start_sector,
697 inode->end_sector, i);
699 DPRINTF(bfs->debug, "%d %d %d %d %d %08x %08x %08x\n",
700 attr->type, attr->mode, attr->uid, attr->gid,
701 attr->nlink, attr->atime, attr->mtime, attr->ctime);
702 j++;
705 if (j != bfs->n_inode) {
706 DPRINTF(bfs->debug, "inconsistent cached data. (i-node)\n");
707 return false;
709 DPRINTF(bfs->debug, "total %d i-node.\n", j);
711 /* file list */
712 DPRINTF(bfs->debug, "[dirent index list]\n");
713 DPRINTF(bfs->debug, "%d file entries.\n", bfs->max_dirent);
714 file = bfs->dirent;
715 for (i = j = 0; i < bfs->max_dirent; i++, file++) {
716 if (file->inode != 0) {
717 if (bfs_file_lookup(bfs, file->name, &s, &e, &bytes))
718 DPRINTF(bfs->debug, "%3d %14s %8d %8d %8zd\n",
719 file->inode, file->name, s, e, bytes);
720 j++;
723 if (j != bfs->n_dirent) {
724 DPRINTF(bfs->debug, "inconsistent cached data. (dirent)\n");
725 return false;
727 DPRINTF(bfs->debug, "%d files.\n", j);
729 return true;