Lines Matching +full:- +full:boot
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
93 assert((lbp->map[i] & ~clearmask) != 0); in bitmap_clear()
94 lbp->map[i] &= clearmask; in bitmap_clear()
95 lbp->count--; in bitmap_clear()
104 return ((lbp->map[i] & usedbit) == usedbit); in bitmap_get()
112 return (lbp->map[i] == 0); in bitmap_none_in_range()
118 return (lbp->count); in bitmap_count()
126 free(lbp->map); in bitmap_ctor()
127 lbp->map = calloc(1, bitmap_size); in bitmap_ctor()
128 if (lbp->map == NULL) in bitmap_ctor()
132 memset(lbp->map, 0xff, bitmap_size); in bitmap_ctor()
133 lbp->count = bits; in bitmap_ctor()
135 lbp->count = 0; in bitmap_ctor()
143 free(lbp->map); in bitmap_dtor()
144 lbp->map = NULL; in bitmap_dtor()
168 struct bootblock *boot; member
188 bitmap_clear(&fat->headbitmap, cl); in fat_clear_cl_head()
194 return (bitmap_get(&fat->headbitmap, cl)); in fat_is_cl_head()
200 return (!(bitmap_none_in_range(&fat->headbitmap, cl))); in fat_is_cl_head_in_range()
206 return (bitmap_count(&fat->headbitmap)); in fat_get_head_count()
217 return (fat->fatbuf + ((cl + (cl >> 1)))); in fat_get_fat12_ptr()
274 return (fat->fatbuf + (cl << 1)); in fat_get_fat16_ptr()
313 return (fat->fatbuf + (cl << 2)); in fat_get_fat32_ptr()
350 if (address == fat->fat32_lastaddr) { in fat_get_iosize()
351 return (fat->fatsize & ((off_t)fat32_cache_chunk_size - 1)); in fat_get_iosize()
367 if (!entry->dirty) in fat_flush_fat32_cache_entry()
370 writesize = fat_get_iosize(fat, entry->addr); in fat_flush_fat32_cache_entry()
372 fat_addr = fat->fat32_offset + entry->addr; in fat_flush_fat32_cache_entry()
374 (size_t)write(fd, entry->chunk, writesize) != writesize) { in fat_flush_fat32_cache_entry()
379 entry->dirty = false; in fat_flush_fat32_cache_entry()
392 addr &= ~(fat32_cache_chunk_size - 1); in fat_get_fat32_cache_entry()
394 first = TAILQ_FIRST(&fat->fat32_cache_head); in fat_get_fat32_cache_entry()
399 TAILQ_FOREACH(entry, &fat->fat32_cache_head, entries) { in fat_get_fat32_cache_entry()
400 if (entry->addr == addr) { in fat_get_fat32_cache_entry()
402 entry->dirty = true; in fat_get_fat32_cache_entry()
406 TAILQ_REMOVE(&fat->fat32_cache_head, entry, entries); in fat_get_fat32_cache_entry()
407 TAILQ_INSERT_HEAD(&fat->fat32_cache_head, entry, entries); in fat_get_fat32_cache_entry()
417 entry = TAILQ_LAST(&fat->fat32_cache_head, cachehead); in fat_get_fat32_cache_entry()
418 TAILQ_REMOVE(&fat->fat32_cache_head, entry, entries); in fat_get_fat32_cache_entry()
424 fat_addr = fat->fat32_offset + addr; in fat_get_fat32_cache_entry()
425 entry->addr = addr; in fat_get_fat32_cache_entry()
428 (size_t)read(fd, entry->chunk, rwsize) != rwsize) { in fat_get_fat32_cache_entry()
433 entry->dirty = true; in fat_get_fat32_cache_entry()
435 TAILQ_INSERT_HEAD(&fat->fat32_cache_head, entry, entries); in fat_get_fat32_cache_entry()
450 off = addr & (fat32_cache_chunk_size - 1); in fat_get_fat32_cached_ptr()
451 return (entry->chunk + off); in fat_get_fat32_cached_ptr()
501 return (fat->get(fat, cl)); in fat_get_cl_next()
517 return (fat->set(fat, cl, nextcl)); in fat_set_cl_next()
523 return (fat->boot); in boot_of_()
535 return (fat->fd); in fd_of_()
557 const struct bootblock *boot = boot_of_(fat); in valid_cl() local
559 return (cl >= CLUST_FIRST && cl < boot->NumClusters); in valid_cl()
563 * The first 2 FAT entries contain pseudo-cluster numbers with the following
580 checkdirty(int fs, struct bootblock *boot) in checkdirty() argument
587 if (boot->ClustMask != CLUST16_MASK && boot->ClustMask != CLUST32_MASK) in checkdirty()
590 off = boot->bpbResSectors; in checkdirty()
591 off *= boot->bpbBytesPerSec; in checkdirty()
593 buffer = malloc(len = boot->bpbBytesPerSec); in checkdirty()
604 if ((size_t)read(fs, buffer, boot->bpbBytesPerSec) != in checkdirty()
605 boot->bpbBytesPerSec) { in checkdirty()
614 if (buffer[0] != boot->bpbMedia || buffer[1] != 0xff) in checkdirty()
616 if (boot->ClustMask == CLUST16_MASK) { in checkdirty()
627 * Now check the actual clean flag (and the no-error flag). in checkdirty()
629 if (boot->ClustMask == CLUST16_MASK) { in checkdirty()
646 struct bootblock *boot; in cleardirty() local
651 boot = boot_of_(fat); in cleardirty()
654 if (boot->ClustMask != CLUST16_MASK && boot->ClustMask != CLUST32_MASK) in cleardirty()
657 off = boot->bpbResSectors; in cleardirty()
658 off *= boot->bpbBytesPerSec; in cleardirty()
660 buffer = malloc(len = boot->bpbBytesPerSec); in cleardirty()
671 if (boot->ClustMask == CLUST16_MASK) { in cleardirty()
699 struct bootblock *boot; in _readfat() local
702 boot = boot_of_(fat); in _readfat()
704 fat->fatsize = boot->FATsecs * boot->bpbBytesPerSec; in _readfat()
706 off = boot->bpbResSectors; in _readfat()
707 off *= boot->bpbBytesPerSec; in _readfat()
709 fat->is_mmapped = false; in _readfat()
710 fat->use_cache = false; in _readfat()
714 fat->fatbuf = mmap(NULL, fat->fatsize, in _readfat()
717 if (fat->fatbuf != MAP_FAILED) { in _readfat()
718 fat->is_mmapped = true; in _readfat()
732 if (boot->ClustMask == CLUST32_MASK && in _readfat()
733 fat->fatsize >= fat32_cache_size) { in _readfat()
735 fat->use_cache = true; in _readfat()
737 fat->fat32_offset = boot->bpbResSectors * boot->bpbBytesPerSec; in _readfat()
738 fat->fat32_lastaddr = fat->fatsize & ~(fat32_cache_chunk_size); in _readfat()
740 readsize = fat->fatsize; in _readfat()
742 fat->fatbuf = malloc(readsize); in _readfat()
743 if (fat->fatbuf == NULL) { in _readfat()
752 if ((size_t)read(fd, fat->fatbuf, readsize) != readsize) { in _readfat()
761 if (fat->use_cache) { in _readfat()
762 TAILQ_INIT(&fat->fat32_cache_head); in _readfat()
771 entry[i].chunk = &fat->fatbuf[entry[i].addr]; in _readfat()
772 TAILQ_INSERT_TAIL(&fat->fat32_cache_head, in _readfat()
775 fat->fat32_cache_allentries = entry; in _readfat()
781 free(fat->fatbuf); in _readfat()
782 fat->fatbuf = NULL; in _readfat()
789 if (fat->is_mmapped) { in releasefat()
790 munmap(fat->fatbuf, fat->fatsize); in releasefat()
792 if (fat->use_cache) { in releasefat()
793 free(fat->fat32_cache_allentries); in releasefat()
794 fat->fat32_cache_allentries = NULL; in releasefat()
796 free(fat->fatbuf); in releasefat()
798 fat->fatbuf = NULL; in releasefat()
799 bitmap_dtor(&fat->headbitmap); in releasefat()
806 readfat(int fs, struct bootblock *boot, struct fat_descriptor **fp) in readfat() argument
813 boot->NumFree = boot->NumBad = 0; in readfat()
821 fat->fd = fs; in readfat()
822 fat->boot = boot; in readfat()
828 buffer = fat->fatbuf; in readfat()
831 switch(boot->ClustMask) { in readfat()
833 fat->get = fat_get_fat12_next; in readfat()
834 fat->set = fat_set_fat12_next; in readfat()
837 fat->get = fat_get_fat16_next; in readfat()
838 fat->set = fat_set_fat16_next; in readfat()
841 if (fat->is_mmapped || !fat->use_cache) { in readfat()
842 fat->get = fat_get_fat32_next; in readfat()
843 fat->set = fat_set_fat32_next; in readfat()
845 fat->get = fat_get_fat32_cached_next; in readfat()
846 fat->set = fat_set_fat32_cached_next; in readfat()
850 pfatal("Invalid ClustMask: %d", boot->ClustMask); in readfat()
856 if (bitmap_ctor(&fat->headbitmap, boot->NumClusters, in readfat()
859 (size_t)boot->NumClusters); in readfat()
865 if (buffer[0] != boot->bpbMedia in readfat()
867 || (boot->ClustMask == CLUST16_MASK && buffer[3] != 0xff) in readfat()
868 || (boot->ClustMask == CLUST32_MASK in readfat()
875 * 0xXXffff0fffffff07 for FAT32 upon boot, to know that the in readfat()
879 if (buffer[0] == boot->bpbMedia && buffer[1] == 0xff in readfat()
881 && ((boot->ClustMask == CLUST16_MASK && buffer[3] == 0x7f) in readfat()
882 || (boot->ClustMask == CLUST32_MASK in readfat()
890 switch (boot->ClustMask) { in readfat()
913 *p++ = (u_char)boot->bpbMedia; in readfat()
916 switch (boot->ClustMask) { in readfat()
938 * by marking every non-head nodes as such (detailed below) and in readfat()
945 * b) An out-of-range value. The only fix would be to truncate at in readfat()
950 * twice, it means a cross-linked chain which should be in readfat()
958 * where these head nodes would be marked as non-head. in readfat()
964 for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++) { in readfat()
970 if (boot->FSNext == 0) { in readfat()
971 boot->FSNext = cl; in readfat()
976 boot->NumFree++; in readfat()
981 boot->NumBad++; in readfat()
986 nextcl & boot->ClustMask); in readfat()
1054 * The allocation of a non-zero sized file or directory is in checkchain()
1081 * The chain ended with an out-of-range cluster number. in checkchain()
1098 next_cl & boot_of_(fat)->ClustMask); in checkchain()
1123 struct bootblock *boot = boot_of_(fat); in clearchain() local
1130 boot->NumFree++; in clearchain()
1137 * Overwrite the n-th FAT with FAT0
1144 struct bootblock *boot; in copyfat() local
1149 boot = boot_of_(fat); in copyfat()
1151 blobs = howmany(fat->fatsize, fat32_cache_size); in copyfat()
1152 tailsize = fat->fatsize % fat32_cache_size; in copyfat()
1158 src_off = fat->fat32_offset; in copyfat()
1159 dst_off = boot->bpbResSectors + n * boot->FATsecs; in copyfat()
1160 dst_off *= boot->bpbBytesPerSec; in copyfat()
1164 if (i == blobs - 1) { in copyfat()
1168 (size_t)read(fd, fat->fatbuf, rwsize) != rwsize) && in copyfat()
1175 (size_t)write(fd, fat->fatbuf, rwsize) != rwsize) && in copyfat()
1194 struct bootblock *boot; in writefat() local
1197 boot = boot_of_(fat); in writefat()
1200 if (fat->use_cache) { in writefat()
1202 * Attempt to flush all in-flight cache, and bail out in writefat()
1207 TAILQ_FOREACH(entry, &fat->fat32_cache_head, entries) { in writefat()
1219 for (i = 1; i < boot->bpbFATs; i++) { in writefat()
1224 writesz = fat->fatsize; in writefat()
1226 for (i = fat->is_mmapped ? 1 : 0; i < boot->bpbFATs; i++) { in writefat()
1227 dst_base = boot->bpbResSectors + i * boot->FATsecs; in writefat()
1228 dst_base *= boot->bpbBytesPerSec; in writefat()
1230 (size_t)write(fd, fat->fatbuf, writesz) != writesz) && in writefat()
1242 * Check a complete in-memory FAT for lost cluster chains
1251 struct bootblock *boot; in checklost() local
1254 boot = boot_of_(fat); in checklost()
1263 chains > 0 && head < boot->NumClusters; in checklost()
1289 chains--; in checklost()
1296 if (boot->bpbFSInfo) { in checklost()
1298 if (boot->FSFree != 0xffffffffU && in checklost()
1299 boot->FSFree != boot->NumFree) { in checklost()
1301 boot->FSFree, boot->NumFree); in checklost()
1303 boot->FSFree = boot->NumFree; in checklost()
1307 if (boot->FSNext != 0xffffffffU && in checklost()
1308 (boot->FSNext >= boot->NumClusters || in checklost()
1309 (boot->NumFree && fat_get_cl_next(fat, boot->FSNext) != CLUST_FREE))) { in checklost()
1311 boot->FSNext, in checklost()
1312 (boot->FSNext >= boot->NumClusters) ? "invalid" : "not free"); in checklost()
1314 for (head = CLUST_FIRST; head < boot->NumClusters; head++) in checklost()
1316 boot->FSNext = head; in checklost()
1322 mod |= writefsinfo(dosfs, boot); in checklost()