Lines Matching defs:fat
1 /* $NetBSD: fat.c,v 1.30 2019/06/04 00:08:00 christos Exp $ */
31 __RCSID("$NetBSD: fat.c,v 1.30 2019/06/04 00:08:00 christos Exp $");
52 checkclnum(struct bootblock *boot, u_int fat, cl_t cl, cl_t *next)
66 pwarn("Cluster %u in FAT %u continues with %s cluster number %u\n",
67 cl, fat,
80 * Read a FAT from disk. Returns 1 if successful, 0 otherwise.
90 perr("No space for FAT sectors (%zu)", len);
98 perr("Unable to read FAT");
104 perr("Unable to read FAT");
116 * Read a FAT and decode it into internal format
121 struct fatEntry *fat;
132 fat = malloc(len = boot->NumClusters * sizeof(struct fatEntry));
133 if (fat == NULL) {
134 perr("No space for FAT clusters (%zu)", len);
138 (void)memset(fat, 0, len);
149 * the FAT signature to 0xXXffff7f for FAT16 and to
163 /* just some odd byte sequence in FAT */
168 "FAT starts with odd byte sequence",
174 "FAT starts with odd byte sequence",
179 "FAT starts with odd byte sequence",
203 fat[cl].next = p[0] + (p[1] << 8)
205 fat[cl].next &= boot->ClustMask;
206 ret |= checkclnum(boot, no, cl, &fat[cl].next);
211 fat[cl].next = p[0] + (p[1] << 8);
212 ret |= checkclnum(boot, no, cl, &fat[cl].next);
217 fat[cl].next = (p[0] + (p[1] << 8)) & 0x0fff;
218 ret |= checkclnum(boot, no, cl, &fat[cl].next);
222 fat[cl].next = ((p[1] >> 4) + (p[2] << 4)) & 0x0fff;
223 ret |= checkclnum(boot, no, cl, &fat[cl].next);
232 free(fat);
235 *fp = fat;
270 pwarn("Cluster %u is marked %s in FAT 0, %s in FAT %u\n",
272 if (ask(0, "use FAT 0's entry")) {
276 if (ask(0, "use FAT %u's entry", fatnum)) {
282 pwarn("Cluster %u is marked %s in FAT 0, but continues with cluster %u in FAT %u\n",
284 if (ask(0, "Use continuation from FAT %u", fatnum)) {
288 if (ask(0, "Use mark from FAT 0")) {
295 pwarn("Cluster %u continues with cluster %u in FAT 0, but is marked %s in FAT %u\n",
297 if (ask(0, "Use continuation from FAT 0")) {
301 if (ask(0, "Use mark from FAT %u", fatnum)) {
307 pwarn("Cluster %u continues with cluster %u in FAT 0, but with cluster %u in FAT %u\n",
309 if (ask(0, "Use continuation from FAT 0")) {
313 if (ask(0, "Use continuation from FAT %u", fatnum)) {
321 * Compare two FAT copies in memory. Resolve any conflicts and merge them
338 clearchain(struct bootblock *boot, struct fatEntry *fat, cl_t head)
343 if (fat[p].head != head)
345 q = fat[p].next;
346 fat[p].next = fat[p].head = CLUST_FREE;
347 fat[p].length = 0;
352 tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *truncp)
355 clearchain(boot, fat, head);
363 p = fat[p].next, len++)
366 fat[head].length = len;
373 * Check a complete FAT in-memory for crosslinks
376 checkfat(struct bootblock *boot, struct fatEntry *fat)
388 if (fat[head].head != 0 /* cluster already belongs to some chain */
389 || fat[head].next == CLUST_FREE
390 || fat[head].next == CLUST_BAD)
396 fat[p].head != head;
397 p = fat[p].next) {
398 fat[p].head = head;
403 fat[head].length = fat[head].next == CLUST_FREE ? 0 : len;
413 if (fat[head].head != head)
417 for (len = fat[head].length, p = head;
418 (n = fat[p].next) >= CLUST_FIRST && n < boot->NumClusters;
420 if (fat[n].head != head || len-- < 2)
429 ret |= tryclear(boot, fat, head, &fat[p].next);
437 if (head == fat[n].head) {
444 head, fat[n].head, n);
445 conf = tryclear(boot, fat, head, &fat[p].next);
446 if (ask(0, "Clear chain starting at %u", h = fat[n].head)) {
453 p = fat[p].next) {
454 if (h != fat[p].head) {
461 fat[p].head = head;
464 clearchain(boot, fat, h);
477 writefat(int fs, struct bootblock *boot, struct fatEntry *fat, int correct_fat)
488 perr("No space for FAT sectors (%zu)", fatsz);
511 /* use same FAT signature as the old FAT has */
541 if (fat[cl].next == CLUST_FREE)
543 *p++ = (u_char)fat[cl].next;
544 *p++ = (u_char)(fat[cl].next >> 8);
545 *p++ = (u_char)(fat[cl].next >> 16);
547 *p++ |= (fat[cl].next >> 24)&0x0f;
550 if (fat[cl].next == CLUST_FREE)
552 *p++ = (u_char)fat[cl].next;
553 *p++ = (u_char)(fat[cl].next >> 8);
556 if (fat[cl].next == CLUST_FREE)
558 *p++ = (u_char)fat[cl].next;
559 *p = (u_char)((fat[cl].next >> 8) & 0xf);
563 if (fat[cl].next == CLUST_FREE)
565 *p++ |= (u_char)(fat[cl].next << 4);
566 *p++ = (u_char)(fat[cl].next >> 4);
575 perr("Unable to write FAT");
584 * Check a complete in-memory FAT for lost cluster chains
587 checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
595 if (fat[head].head != head
596 || fat[head].next == CLUST_FREE
597 || (fat[head].next >= CLUST_RSRVD
598 && fat[head].next < CLUST_EOFS)
599 || (fat[head].flags & FAT_USED))
603 head, fat[head].length);
604 mod |= ret = reconnect(dosfs, boot, fat, head);
608 clearchain(boot, fat, head);
627 (boot->NumFree && fat[boot->FSNext].next != CLUST_FREE))) {
633 if (fat[head].next == CLUST_FREE) {