/*-
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2019 Google LLC
 * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
 * Copyright (c) 1995 Martin Husemann
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fat.c,v 1.18 2006/06/05 16:51:18 christos Exp $");
static const char rcsid[] =
  "$FreeBSD$";
#endif /* not lint */

#include <sys/endian.h>
#include <sys/queue.h>
#include <sys/limits.h>
#include <sys/mman.h>
#include <sys/param.h>

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>

#include "ext.h"
#include "fsutil.h"

static int _readfat(struct fat_descriptor *);
static inline struct bootblock* boot_of_(struct fat_descriptor *);
static inline int fd_of_(struct fat_descriptor *);
static inline bool valid_cl(struct fat_descriptor *, cl_t);


/*
 * Head bitmap for FAT scanning.
 *
 * FAT32 have up to 2^28 = 256M entries, and FAT16/12 have much less.
 * For each cluster, we use 1 bit to represent if it's a head cluster
 * (the first cluster of a cluster chain).
 *
 * Head bitmap
 * ===========
 * Initially, we set all bits to 1.  In readfat(), we traverse the
 * whole FAT and mark each cluster identified as "next" cluster as
 * 0.  After the scan, we have a bitmap with 1's to indicate the
 * corresponding cluster was a "head" cluster.
 *
 * We use head bitmap to identify lost chains: a head cluster that was
 * not being claimed by any file or directories is the head cluster of
 * a lost chain.
 *
 * Handle of lost chains
 * =====================
 * At the end of scanning, we can easily find all lost chain's heads
 * by finding out the 1's in the head bitmap.
 */

typedef struct long_bitmap {
	unsigned long	*map;
	size_t		 count;		/* Total set bits in the map */
} long_bitmap_t;

static inline void
bitmap_clear(long_bitmap_t *lbp, cl_t cl)
{
	cl_t i = cl / LONG_BIT;
	unsigned long clearmask = ~(1UL << (cl % LONG_BIT));

	assert((lbp->map[i] & ~clearmask) != 0);
	lbp->map[i] &= clearmask;
	lbp->count--;
}

static inline bool
bitmap_get(long_bitmap_t *lbp, cl_t cl)
{
	cl_t i = cl / LONG_BIT;
	unsigned long usedbit = 1UL << (cl % LONG_BIT);

	return ((lbp->map[i] & usedbit) == usedbit);
}

static inline bool
bitmap_none_in_range(long_bitmap_t *lbp, cl_t cl)
{
	cl_t i = cl / LONG_BIT;

	return (lbp->map[i] == 0);
}

static inline size_t
bitmap_count(long_bitmap_t *lbp)
{
	return (lbp->count);
}

static int
bitmap_ctor(long_bitmap_t *lbp, size_t bits, bool allone)
{
	size_t bitmap_size = roundup2(bits, LONG_BIT) / (LONG_BIT / 8);

	free(lbp->map);
	lbp->map = calloc(1, bitmap_size);
	if (lbp->map == NULL)
		return FSFATAL;

	if (allone) {
		memset(lbp->map, 0xff, bitmap_size);
		lbp->count = bits;
	} else {
		lbp->count = 0;
	}
	return FSOK;
}

static void
bitmap_dtor(long_bitmap_t *lbp)
{
	free(lbp->map);
	lbp->map = NULL;
}

/*
 * FAT32 can be as big as 256MiB (2^26 entries * 4 bytes), when we
 * can not ask the kernel to manage the access, use a simple LRU
 * cache with chunk size of 128 KiB to manage it.
 */
struct fat32_cache_entry {
	TAILQ_ENTRY(fat32_cache_entry)	entries;
	uint8_t			*chunk;		/* pointer to chunk */
	off_t			 addr;		/* offset */
	bool			 dirty;		/* dirty bit */
};

static const size_t	fat32_cache_chunk_size = 131072; /* MAXPHYS */
static const size_t	fat32_cache_size = 4194304;
static const size_t	fat32_cache_entries = 32; /* XXXgcc: cache_size / cache_chunk_size */

/*
 * FAT table descriptor, represents a FAT table that is already loaded
 * into memory.
 */
struct fat_descriptor {
	struct bootblock	*boot;
	uint8_t			*fatbuf;
	cl_t			(*get)(struct fat_descriptor *, cl_t);
	int			(*set)(struct fat_descriptor *, cl_t, cl_t);
	long_bitmap_t		 headbitmap;
	int			 fd;
	bool			 is_mmapped;
	bool			 use_cache;
	size_t		  	 fatsize;

	size_t			 fat32_cached_chunks;
	TAILQ_HEAD(cachehead, fat32_cache_entry)	fat32_cache_head;
	struct fat32_cache_entry	*fat32_cache_allentries;
	off_t			 fat32_offset;
	off_t			 fat32_lastaddr;
};

void
fat_clear_cl_head(struct fat_descriptor *fat, cl_t cl)
{
	bitmap_clear(&fat->headbitmap, cl);
}

bool
fat_is_cl_head(struct fat_descriptor *fat, cl_t cl)
{
	return (bitmap_get(&fat->headbitmap, cl));
}

static inline bool
fat_is_cl_head_in_range(struct fat_descriptor *fat, cl_t cl)
{
	return (!(bitmap_none_in_range(&fat->headbitmap, cl)));
}

static size_t
fat_get_head_count(struct fat_descriptor *fat)
{
	return (bitmap_count(&fat->headbitmap));
}

/*
 * FAT12 accessors.
 *
 * FAT12s are sufficiently small, expect it to always fit in the RAM.
 */
static inline uint8_t *
fat_get_fat12_ptr(struct fat_descriptor *fat, cl_t cl)
{
	return (fat->fatbuf + ((cl + (cl >> 1))));
}

static cl_t
fat_get_fat12_next(struct fat_descriptor *fat, cl_t cl)
{
	const uint8_t	*p;
	cl_t	retval;

	p = fat_get_fat12_ptr(fat, cl);
	retval = le16dec(p);
	/* Odd cluster: lower 4 bits belongs to the subsequent cluster */
	if ((cl & 1) == 1)
		retval >>= 4;
	retval &= CLUST12_MASK;

	if (retval >= (CLUST_BAD & CLUST12_MASK))
		retval |= ~CLUST12_MASK;

	return (retval);
}

static int
fat_set_fat12_next(struct fat_descriptor *fat, cl_t cl, cl_t nextcl)
{
	uint8_t	*p;

	/* Truncate 'nextcl' value, if needed */
	nextcl &= CLUST12_MASK;

	p = fat_get_fat12_ptr(fat, cl);

	/*
	 * Read in the 4 bits from the subsequent (for even clusters)
	 * or the preceding (for odd clusters) cluster and combine
	 * it to the nextcl value for encoding
	 */
	if ((cl & 1) == 0) {
		nextcl |= ((p[1] & 0xf0) << 8);
	} else {
		nextcl <<= 4;
		nextcl |= (p[0] & 0x0f);
	}

	le16enc(p, (uint16_t)nextcl);

	return (0);
}

/*
 * FAT16 accessors.
 *
 * FAT16s are sufficiently small, expect it to always fit in the RAM.
 */
static inline uint8_t *
fat_get_fat16_ptr(struct fat_descriptor *fat, cl_t cl)
{
	return (fat->fatbuf + (cl << 1));
}

static cl_t
fat_get_fat16_next(struct fat_descriptor *fat, cl_t cl)
{
	const uint8_t	*p;
	cl_t	retval;

	p = fat_get_fat16_ptr(fat, cl);
	retval = le16dec(p) & CLUST16_MASK;

	if (retval >= (CLUST_BAD & CLUST16_MASK))
		retval |= ~CLUST16_MASK;

	return (retval);
}

static int
fat_set_fat16_next(struct fat_descriptor *fat, cl_t cl, cl_t nextcl)
{
	uint8_t	*p;

	/* Truncate 'nextcl' value, if needed */
	nextcl &= CLUST16_MASK;

	p = fat_get_fat16_ptr(fat, cl);

	le16enc(p, (uint16_t)nextcl);

	return (0);
}

/*
 * FAT32 accessors.
 */
static inline uint8_t *
fat_get_fat32_ptr(struct fat_descriptor *fat, cl_t cl)
{
	return (fat->fatbuf + (cl << 2));
}

static cl_t
fat_get_fat32_next(struct fat_descriptor *fat, cl_t cl)
{
	const uint8_t	*p;
	cl_t	retval;

	p = fat_get_fat32_ptr(fat, cl);
	retval = le32dec(p) & CLUST32_MASK;

	if (retval >= (CLUST_BAD & CLUST32_MASK))
		retval |= ~CLUST32_MASK;

	return (retval);
}

static int
fat_set_fat32_next(struct fat_descriptor *fat, cl_t cl, cl_t nextcl)
{
	uint8_t	*p;

	/* Truncate 'nextcl' value, if needed */
	nextcl &= CLUST32_MASK;

	p = fat_get_fat32_ptr(fat, cl);

	le32enc(p, (uint32_t)nextcl);

	return (0);
}

static inline size_t
fat_get_iosize(struct fat_descriptor *fat, off_t address)
{

	if (address == fat->fat32_lastaddr) {
		return (fat->fatsize & ((off_t)fat32_cache_chunk_size - 1));
	} else {
		return (fat32_cache_chunk_size);
	}
}

static int
fat_flush_fat32_cache_entry(struct fat_descriptor *fat,
    struct fat32_cache_entry *entry)
{
	int fd;
	off_t fat_addr;
	size_t writesize;

	fd = fd_of_(fat);

	if (!entry->dirty)
		return (FSOK);

	writesize = fat_get_iosize(fat, entry->addr);

	fat_addr = fat->fat32_offset + entry->addr;
	if (lseek(fd, fat_addr, SEEK_SET) != fat_addr ||
	    (size_t)write(fd, entry->chunk, writesize) != writesize) {
			pfatal("Unable to write FAT");
			return (FSFATAL);
	}

	entry->dirty = false;
	return (FSOK);
}

static struct fat32_cache_entry *
fat_get_fat32_cache_entry(struct fat_descriptor *fat, off_t addr,
    bool writing)
{
	int fd;
	struct fat32_cache_entry *entry, *first;
	off_t	fat_addr;
	size_t	rwsize;

	addr &= ~(fat32_cache_chunk_size - 1);

	first = TAILQ_FIRST(&fat->fat32_cache_head);

	/*
	 * Cache hit: if we already have the chunk, move it to list head
	 */
	TAILQ_FOREACH(entry, &fat->fat32_cache_head, entries) {
		if (entry->addr == addr) {
			if (writing) {
				entry->dirty = true;
			}
			if (entry != first) {

				TAILQ_REMOVE(&fat->fat32_cache_head, entry, entries);
				TAILQ_INSERT_HEAD(&fat->fat32_cache_head, entry, entries);
			}
			return (entry);
		}
	}

	/*
	 * Cache miss: detach the chunk at tail of list, overwrite with
	 * the located chunk, and populate with data from disk.
	 */
	entry = TAILQ_LAST(&fat->fat32_cache_head, cachehead);
	TAILQ_REMOVE(&fat->fat32_cache_head, entry, entries);
	if (fat_flush_fat32_cache_entry(fat, entry) != FSOK) {
		return (NULL);
	}

	rwsize = fat_get_iosize(fat, addr);
	fat_addr = fat->fat32_offset + addr;
	entry->addr = addr;
	fd = fd_of_(fat);
	if (lseek(fd, fat_addr, SEEK_SET) != fat_addr ||
		(size_t)read(fd, entry->chunk, rwsize) != rwsize) {
		pfatal("Unable to read FAT");
		return (NULL);
	}
	if (writing) {
		entry->dirty = true;
	}
	TAILQ_INSERT_HEAD(&fat->fat32_cache_head, entry, entries);

	return (entry);
}

static inline uint8_t *
fat_get_fat32_cached_ptr(struct fat_descriptor *fat, cl_t cl, bool writing)
{
	off_t addr, off;
	struct fat32_cache_entry *entry;

	addr = cl << 2;
	entry = fat_get_fat32_cache_entry(fat, addr, writing);

	if (entry != NULL) {
		off = addr & (fat32_cache_chunk_size - 1);
		return (entry->chunk + off);
	} else {
		return (NULL);
	}
}


static cl_t
fat_get_fat32_cached_next(struct fat_descriptor *fat, cl_t cl)
{
	const uint8_t	*p;
	cl_t	retval;

	p = fat_get_fat32_cached_ptr(fat, cl, false);
	if (p != NULL) {
		retval = le32dec(p) & CLUST32_MASK;
		if (retval >= (CLUST_BAD & CLUST32_MASK))
			retval |= ~CLUST32_MASK;
	} else {
		retval = CLUST_DEAD;
	}

	return (retval);
}

static int
fat_set_fat32_cached_next(struct fat_descriptor *fat, cl_t cl, cl_t nextcl)
{
	uint8_t	*p;

	/* Truncate 'nextcl' value, if needed */
	nextcl &= CLUST32_MASK;

	p = fat_get_fat32_cached_ptr(fat, cl, true);
	if (p != NULL) {
		le32enc(p, (uint32_t)nextcl);
		return FSOK;
	} else {
		return FSFATAL;
	}
}

cl_t fat_get_cl_next(struct fat_descriptor *fat, cl_t cl)
{

	if (!valid_cl(fat, cl)) {
		pfatal("Invalid cluster: %ud", cl);
		return CLUST_DEAD;
	}

	return (fat->get(fat, cl));
}

int fat_set_cl_next(struct fat_descriptor *fat, cl_t cl, cl_t nextcl)
{

	if (rdonly) {
		pwarn(" (NO WRITE)\n");
		return FSFATAL;
	}

	if (!valid_cl(fat, cl)) {
		pfatal("Invalid cluster: %ud", cl);
		return FSFATAL;
	}

	return (fat->set(fat, cl, nextcl));
}

static inline struct bootblock*
boot_of_(struct fat_descriptor *fat) {

	return (fat->boot);
}

struct bootblock*
fat_get_boot(struct fat_descriptor *fat) {

	return (boot_of_(fat));
}

static inline int
fd_of_(struct fat_descriptor *fat)
{
	return (fat->fd);
}

int
fat_get_fd(struct fat_descriptor * fat)
{
	return (fd_of_(fat));
}

/*
 * Whether a cl is in valid data range.
 */
bool
fat_is_valid_cl(struct fat_descriptor *fat, cl_t cl)
{

	return (valid_cl(fat, cl));
}

static inline bool
valid_cl(struct fat_descriptor *fat, cl_t cl)
{
	const struct bootblock *boot = boot_of_(fat);

	return (cl >= CLUST_FIRST && cl < boot->NumClusters);
}

/*
 * The first 2 FAT entries contain pseudo-cluster numbers with the following
 * layout:
 *
 * 31...... ........ ........ .......0
 * rrrr1111 11111111 11111111 mmmmmmmm         FAT32 entry 0
 * rrrrsh11 11111111 11111111 11111xxx         FAT32 entry 1
 *
 *                   11111111 mmmmmmmm         FAT16 entry 0
 *                   sh111111 11111xxx         FAT16 entry 1
 *
 * r = reserved
 * m = BPB media ID byte
 * s = clean flag (1 = dismounted; 0 = still mounted)
 * h = hard error flag (1 = ok; 0 = I/O error)
 * x = any value ok
 */
int
checkdirty(int fs, struct bootblock *boot)
{
	off_t off;
	u_char *buffer;
	int ret = 0;
	size_t len;

	if (boot->ClustMask != CLUST16_MASK && boot->ClustMask != CLUST32_MASK)
		return 0;

	off = boot->bpbResSectors;
	off *= boot->bpbBytesPerSec;

	buffer = malloc(len = boot->bpbBytesPerSec);
	if (buffer == NULL) {
		perr("No space for FAT sectors (%zu)", len);
		return 1;
	}

	if (lseek(fs, off, SEEK_SET) != off) {
		perr("Unable to read FAT");
		goto err;
	}

	if ((size_t)read(fs, buffer, boot->bpbBytesPerSec) !=
	    boot->bpbBytesPerSec) {
		perr("Unable to read FAT");
		goto err;
	}

	/*
	 * If we don't understand the FAT, then the file system must be
	 * assumed to be unclean.
	 */
	if (buffer[0] != boot->bpbMedia || buffer[1] != 0xff)
		goto err;
	if (boot->ClustMask == CLUST16_MASK) {
		if ((buffer[2] & 0xf8) != 0xf8 || (buffer[3] & 0x3f) != 0x3f)
			goto err;
	} else {
		if (buffer[2] != 0xff || (buffer[3] & 0x0f) != 0x0f
		    || (buffer[4] & 0xf8) != 0xf8 || buffer[5] != 0xff
		    || buffer[6] != 0xff || (buffer[7] & 0x03) != 0x03)
			goto err;
	}

	/*
	 * Now check the actual clean flag (and the no-error flag).
	 */
	if (boot->ClustMask == CLUST16_MASK) {
		if ((buffer[3] & 0xc0) == 0xc0)
			ret = 1;
	} else {
		if ((buffer[7] & 0x0c) == 0x0c)
			ret = 1;
	}

err:
	free(buffer);
	return ret;
}

int
cleardirty(struct fat_descriptor *fat)
{
	int fd, ret = FSERROR;
	struct bootblock *boot;
	u_char *buffer;
	size_t len;
	off_t off;

	boot = boot_of_(fat);
	fd = fd_of_(fat);

	if (boot->ClustMask != CLUST16_MASK && boot->ClustMask != CLUST32_MASK)
		return 0;

	off = boot->bpbResSectors;
	off *= boot->bpbBytesPerSec;

	buffer = malloc(len = boot->bpbBytesPerSec);
	if (buffer == NULL) {
		perr("No memory for FAT sectors (%zu)", len);
		return 1;
	}

	if ((size_t)pread(fd, buffer, len, off) != len) {
		perr("Unable to read FAT");
		goto err;
	}

	if (boot->ClustMask == CLUST16_MASK) {
		buffer[3] |= 0x80;
	} else {
		buffer[7] |= 0x08;
	}

	if ((size_t)pwrite(fd, buffer, len, off) != len) {
		perr("Unable to write FAT");
		goto err;
	}

	ret = FSOK;

err:
	free(buffer);
	return ret;
}

/*
 * Read a FAT from disk. Returns 1 if successful, 0 otherwise.
 */
static int
_readfat(struct fat_descriptor *fat)
{
	int fd;
	size_t i;
	off_t off;
	size_t readsize;
	struct bootblock *boot;
	struct fat32_cache_entry *entry;

	boot = boot_of_(fat);
	fd = fd_of_(fat);
	fat->fatsize = boot->FATsecs * boot->bpbBytesPerSec;

	off = boot->bpbResSectors;
	off *= boot->bpbBytesPerSec;

	fat->is_mmapped = false;
	fat->use_cache = false;

	/* Attempt to mmap() first */
	if (allow_mmap) {
		fat->fatbuf = mmap(NULL, fat->fatsize,
				PROT_READ | (rdonly ? 0 : PROT_WRITE),
				MAP_SHARED, fd_of_(fat), off);
		if (fat->fatbuf != MAP_FAILED) {
			fat->is_mmapped = true;
			return 1;
		}
	}

	/*
	 * Unfortunately, we were unable to mmap().
	 *
	 * Only use the cache manager when it's necessary, that is,
	 * when the FAT is sufficiently large; in that case, only
	 * read in the first 4 MiB of FAT into memory, and split the
	 * buffer into chunks and insert to the LRU queue to populate
	 * the cache with data.
	 */
	if (boot->ClustMask == CLUST32_MASK &&
	    fat->fatsize >= fat32_cache_size) {
		readsize = fat32_cache_size;
		fat->use_cache = true;

		fat->fat32_offset = boot->bpbResSectors * boot->bpbBytesPerSec;
		fat->fat32_lastaddr = fat->fatsize & ~(fat32_cache_chunk_size);
	} else {
		readsize = fat->fatsize;
	}
	fat->fatbuf = malloc(readsize);
	if (fat->fatbuf == NULL) {
		perr("No space for FAT (%zu)", readsize);
		return 0;
	}

	if (lseek(fd, off, SEEK_SET) != off) {
		perr("Unable to read FAT");
		goto err;
	}
	if ((size_t)read(fd, fat->fatbuf, readsize) != readsize) {
		perr("Unable to read FAT");
		goto err;
	}

	/*
	 * When cache is used, split the buffer into chunks, and
	 * connect the buffer into the cache.
	 */
	if (fat->use_cache) {
		TAILQ_INIT(&fat->fat32_cache_head);
		entry = calloc(fat32_cache_entries, sizeof(*entry));
		if (entry == NULL) {
			perr("No space for FAT cache (%zu of %zu)",
			    fat32_cache_entries, sizeof(entry));
			goto err;
		}
		for (i = 0; i < fat32_cache_entries; i++) {
			entry[i].addr = fat32_cache_chunk_size * i;
			entry[i].chunk = &fat->fatbuf[entry[i].addr];
			TAILQ_INSERT_TAIL(&fat->fat32_cache_head,
			    &entry[i], entries);
		}
		fat->fat32_cache_allentries = entry;
	}

	return 1;

err:
	free(fat->fatbuf);
	fat->fatbuf = NULL;
	return 0;
}

static void
releasefat(struct fat_descriptor *fat)
{
	if (fat->is_mmapped) {
		munmap(fat->fatbuf, fat->fatsize);
	} else {
		if (fat->use_cache) {
			free(fat->fat32_cache_allentries);
			fat->fat32_cache_allentries = NULL;
		}
		free(fat->fatbuf);
	}
	fat->fatbuf = NULL;
	bitmap_dtor(&fat->headbitmap);
}

/*
 * Read or map a FAT and populate head bitmap
 */
int
readfat(int fs, struct bootblock *boot, struct fat_descriptor **fp)
{
	struct fat_descriptor *fat;
	u_char *buffer, *p;
	cl_t cl, nextcl;
	int ret = FSOK;

	boot->NumFree = boot->NumBad = 0;

	fat = calloc(1, sizeof(struct fat_descriptor));
	if (fat == NULL) {
		perr("No space for FAT descriptor");
		return FSFATAL;
	}

	fat->fd = fs;
	fat->boot = boot;

	if (!_readfat(fat)) {
		free(fat);
		return FSFATAL;
	}
	buffer = fat->fatbuf;

	/* Populate accessors */
	switch(boot->ClustMask) {
	case CLUST12_MASK:
		fat->get = fat_get_fat12_next;
		fat->set = fat_set_fat12_next;
		break;
	case CLUST16_MASK:
		fat->get = fat_get_fat16_next;
		fat->set = fat_set_fat16_next;
		break;
	case CLUST32_MASK:
		if (fat->is_mmapped || !fat->use_cache) {
			fat->get = fat_get_fat32_next;
			fat->set = fat_set_fat32_next;
		} else {
			fat->get = fat_get_fat32_cached_next;
			fat->set = fat_set_fat32_cached_next;
		}
		break;
	default:
		pfatal("Invalid ClustMask: %d", boot->ClustMask);
		releasefat(fat);
		free(fat);
		return FSFATAL;
	}

	if (bitmap_ctor(&fat->headbitmap, boot->NumClusters,
	    true) != FSOK) {
		perr("No space for head bitmap for FAT clusters (%zu)",
		    (size_t)boot->NumClusters);
		releasefat(fat);
		free(fat);
		return FSFATAL;
	}

	if (buffer[0] != boot->bpbMedia
	    || buffer[1] != 0xff || buffer[2] != 0xff
	    || (boot->ClustMask == CLUST16_MASK && buffer[3] != 0xff)
	    || (boot->ClustMask == CLUST32_MASK
		&& ((buffer[3]&0x0f) != 0x0f
		    || buffer[4] != 0xff || buffer[5] != 0xff
		    || buffer[6] != 0xff || (buffer[7]&0x0f) != 0x0f))) {

		/* Windows 95 OSR2 (and possibly any later) changes
		 * the FAT signature to 0xXXffff7f for FAT16 and to
		 * 0xXXffff0fffffff07 for FAT32 upon boot, to know that the
		 * file system is dirty if it doesn't reboot cleanly.
		 * Check this special condition before errorring out.
		 */
		if (buffer[0] == boot->bpbMedia && buffer[1] == 0xff
		    && buffer[2] == 0xff
		    && ((boot->ClustMask == CLUST16_MASK && buffer[3] == 0x7f)
			|| (boot->ClustMask == CLUST32_MASK
			    && buffer[3] == 0x0f && buffer[4] == 0xff
			    && buffer[5] == 0xff && buffer[6] == 0xff
			    && buffer[7] == 0x07)))
			ret |= FSDIRTY;
		else {
			/* just some odd byte sequence in FAT */

			switch (boot->ClustMask) {
			case CLUST32_MASK:
				pwarn("%s (%02x%02x%02x%02x%02x%02x%02x%02x)\n",
				      "FAT starts with odd byte sequence",
				      buffer[0], buffer[1], buffer[2], buffer[3],
				      buffer[4], buffer[5], buffer[6], buffer[7]);
				break;
			case CLUST16_MASK:
				pwarn("%s (%02x%02x%02x%02x)\n",
				    "FAT starts with odd byte sequence",
				    buffer[0], buffer[1], buffer[2], buffer[3]);
				break;
			default:
				pwarn("%s (%02x%02x%02x)\n",
				    "FAT starts with odd byte sequence",
				    buffer[0], buffer[1], buffer[2]);
				break;
			}

			if (ask(1, "Correct")) {
				ret |= FSFATMOD;
				p = buffer;

				*p++ = (u_char)boot->bpbMedia;
				*p++ = 0xff;
				*p++ = 0xff;
				switch (boot->ClustMask) {
				case CLUST16_MASK:
					*p++ = 0xff;
					break;
				case CLUST32_MASK:
					*p++ = 0x0f;
					*p++ = 0xff;
					*p++ = 0xff;
					*p++ = 0xff;
					*p++ = 0x0f;
					break;
				default:
					break;
				}
			}
		}
	}

	/*
	 * Traverse the FAT table and populate head map.  Initially, we
	 * consider all clusters as possible head cluster (beginning of
	 * a file or directory), and traverse the whole allocation table
	 * by marking every non-head nodes as such (detailed below) and
	 * fix obvious issues while we walk.
	 *
	 * For each "next" cluster, the possible values are:
	 *
	 * a) CLUST_FREE or CLUST_BAD.  The *current* cluster can't be a
	 *    head node.
	 * b) An out-of-range value. The only fix would be to truncate at
	 *    the cluster.
	 * c) A valid cluster.  It means that cluster (nextcl) is not a
	 *    head cluster.  Note that during the scan, every cluster is
	 *    expected to be seen for at most once, and when we saw them
	 *    twice, it means a cross-linked chain which should be
	 *    truncated at the current cluster.
	 *
	 * After scan, the remaining set bits indicates all possible
	 * head nodes, because they were never claimed by any other
	 * node as the next node, but we do not know if these chains
	 * would end with a valid EOF marker.  We will check that in
	 * checkchain() at a later time when checking directories,
	 * where these head nodes would be marked as non-head.
	 *
	 * In the final pass, all head nodes should be cleared, and if
	 * there is still head nodes, these would be leaders of lost
	 * chain.
	 */
	for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++) {
		nextcl = fat_get_cl_next(fat, cl);

		/* Check if the next cluster number is valid */
		if (nextcl == CLUST_FREE) {
			/* Save a hint for next free cluster */
			if (boot->FSNext == 0) {
				boot->FSNext = cl;
			}
			if (fat_is_cl_head(fat, cl)) {
				fat_clear_cl_head(fat, cl);
			}
			boot->NumFree++;
		} else if (nextcl == CLUST_BAD) {
			if (fat_is_cl_head(fat, cl)) {
				fat_clear_cl_head(fat, cl);
			}
			boot->NumBad++;
		} else if (!valid_cl(fat, nextcl) && nextcl < CLUST_RSRVD) {
			pwarn("Cluster %u continues with out of range "
			    "cluster number %u\n",
			    cl,
			    nextcl & boot->ClustMask);
			if (ask(0, "Truncate")) {
				ret |= fat_set_cl_next(fat, cl, CLUST_EOF);
				ret |= FSFATMOD;
			}
		} else if (valid_cl(fat, nextcl)) {
			if (fat_is_cl_head(fat, nextcl)) {
				fat_clear_cl_head(fat, nextcl);
			} else {
				pwarn("Cluster %u crossed another chain at %u\n",
				    cl, nextcl);
				if (ask(0, "Truncate")) {
					ret |= fat_set_cl_next(fat, cl, CLUST_EOF);
					ret |= FSFATMOD;
				}
			}
		}

	}

	if (ret & FSFATAL) {
		releasefat(fat);
		free(fat);
		*fp = NULL;
	} else
		*fp = fat;
	return ret;
}

/*
 * Get type of reserved cluster
 */
const char *
rsrvdcltype(cl_t cl)
{
	if (cl == CLUST_FREE)
		return "free";
	if (cl < CLUST_BAD)
		return "reserved";
	if (cl > CLUST_BAD)
		return "as EOF";
	return "bad";
}

/*
 * Examine a cluster chain for errors and count its size.
 */
int
checkchain(struct fat_descriptor *fat, cl_t head, size_t *chainsize)
{
	cl_t prev_cl, current_cl, next_cl;
	const char *op;

	/*
	 * We expect that the caller to give us a real, unvisited 'head'
	 * cluster, and it must be a valid cluster.  While scanning the
	 * FAT table, we already excluded all clusters that was claimed
	 * as a "next" cluster.  Assert all the three conditions.
	 */
	assert(valid_cl(fat, head));
	assert(fat_is_cl_head(fat, head));

	/*
	 * Immediately mark the 'head' cluster that we are about to visit.
	 */
	fat_clear_cl_head(fat, head);

	/*
	 * The allocation of a non-zero sized file or directory is
	 * represented as a singly linked list, and the tail node
	 * would be the EOF marker (>=CLUST_EOFS).
	 *
	 * With a valid head node at hand, we expect all subsequent
	 * cluster to be either a not yet seen and valid cluster (we
	 * would continue counting), or the EOF marker (we conclude
	 * the scan of this chain).
	 *
	 * For all other cases, the chain is invalid, and the only
	 * viable fix would be to truncate at the current node (mark
	 * it as EOF) when the next node violates that.
	 */
	*chainsize = 0;
	prev_cl = current_cl = head;
	for (next_cl = fat_get_cl_next(fat, current_cl);
	    valid_cl(fat, next_cl);
	    prev_cl = current_cl, current_cl = next_cl, next_cl = fat_get_cl_next(fat, current_cl))
		(*chainsize)++;

	/* A natural end */
	if (next_cl >= CLUST_EOFS) {
		(*chainsize)++;
		return FSOK;
	}

	/*
	 * The chain ended with an out-of-range cluster number.
	 *
	 * If the current node is e.g. CLUST_FREE, CLUST_BAD, etc.,
	 * it should not be present in a chain and we has to truncate
	 * at the previous node.
	 *
	 * If the current cluster points to an invalid cluster, the
	 * current cluster might have useful data and we truncate at
	 * the current cluster instead.
	 */
	if (next_cl == CLUST_FREE || next_cl >= CLUST_RSRVD) {
		pwarn("Cluster chain starting at %u ends with cluster marked %s\n",
		    head, rsrvdcltype(next_cl));
		current_cl = prev_cl;
	} else {
		pwarn("Cluster chain starting at %u ends with cluster out of range (%u)\n",
		    head,
		    next_cl & boot_of_(fat)->ClustMask);
		(*chainsize)++;
	}

	if (*chainsize > 0) {
		op = "Truncate";
		next_cl = CLUST_EOF;
	} else {
		op = "Clear";
		next_cl = CLUST_FREE;
	}
	if (ask(0, "%s", op)) {
		return (fat_set_cl_next(fat, current_cl, next_cl) | FSFATMOD);
	} else {
		return (FSERROR);
	}
}

/*
 * Clear cluster chain from head.
 */
void
clearchain(struct fat_descriptor *fat, cl_t head)
{
	cl_t current_cl, next_cl;
	struct bootblock *boot = boot_of_(fat);

	current_cl = head;

	while (valid_cl(fat, current_cl)) {
		next_cl = fat_get_cl_next(fat, current_cl);
		(void)fat_set_cl_next(fat, current_cl, CLUST_FREE);
		boot->NumFree++;
		current_cl = next_cl;
	}

}

/*
 * Overwrite the n-th FAT with FAT0
 */
static int
copyfat(struct fat_descriptor *fat, int n)
{
	size_t	rwsize, tailsize, blobs, i;
	off_t	dst_off, src_off;
	struct bootblock *boot;
	int ret, fd;

	ret = FSOK;
	fd = fd_of_(fat);
	boot = boot_of_(fat);

	blobs = howmany(fat->fatsize, fat32_cache_size);
	tailsize = fat->fatsize % fat32_cache_size;
	if (tailsize == 0) {
		tailsize = fat32_cache_size;
	}
	rwsize = fat32_cache_size;

	src_off = fat->fat32_offset;
	dst_off = boot->bpbResSectors + n * boot->FATsecs;
	dst_off *= boot->bpbBytesPerSec;

	for (i = 0; i < blobs;
	    i++, src_off += fat32_cache_size, dst_off += fat32_cache_size) {
		if (i == blobs - 1) {
			rwsize = tailsize;
		}
		if ((lseek(fd, src_off, SEEK_SET) != src_off ||
		    (size_t)read(fd, fat->fatbuf, rwsize) != rwsize) &&
		    ret == FSOK) {
			perr("Unable to read FAT0");
			ret = FSFATAL;
			continue;
		}
		if ((lseek(fd, dst_off, SEEK_SET) != dst_off ||
			(size_t)write(fd, fat->fatbuf, rwsize) != rwsize) &&
			ret == FSOK) {
			perr("Unable to write FAT %d", n);
			ret = FSERROR;
		}
	}
	return (ret);
}

/*
 * Write out FAT
 */
int
writefat(struct fat_descriptor *fat)
{
	u_int i;
	size_t writesz;
	off_t dst_base;
	int ret = FSOK, fd;
	struct bootblock *boot;
	struct fat32_cache_entry *entry;

	boot = boot_of_(fat);
	fd = fd_of_(fat);

	if (fat->use_cache) {
		/*
		 * Attempt to flush all in-flight cache, and bail out
		 * if we encountered an error (but only emit error
		 * message once).  Stop proceeding with copyfat()
		 * if any flush failed.
		 */
		TAILQ_FOREACH(entry, &fat->fat32_cache_head, entries) {
			if (fat_flush_fat32_cache_entry(fat, entry) != FSOK) {
				if (ret == FSOK) {
					perr("Unable to write FAT");
					ret = FSFATAL;
				}
			}
		}
		if (ret != FSOK)
			return (ret);

		/* Update backup copies of FAT, error is not fatal */
		for (i = 1; i < boot->bpbFATs; i++) {
			if (copyfat(fat, i) != FSOK)
				ret = FSERROR;
		}
	} else {
		writesz = fat->fatsize;

		for (i = fat->is_mmapped ? 1 : 0; i < boot->bpbFATs; i++) {
			dst_base = boot->bpbResSectors + i * boot->FATsecs;
			dst_base *= boot->bpbBytesPerSec;
			if ((lseek(fd, dst_base, SEEK_SET) != dst_base ||
			    (size_t)write(fd, fat->fatbuf, writesz) != writesz) &&
			    ret == FSOK) {
				perr("Unable to write FAT %d", i);
				ret = ((i == 0) ? FSFATAL : FSERROR);
			}
		}
	}

	return ret;
}

/*
 * Check a complete in-memory FAT for lost cluster chains
 */
int
checklost(struct fat_descriptor *fat)
{
	cl_t head;
	int mod = FSOK;
	int dosfs, ret;
	size_t chains, chainlength;
	struct bootblock *boot;

	dosfs = fd_of_(fat);
	boot = boot_of_(fat);

	/*
	 * At this point, we have already traversed all directories.
	 * All remaining chain heads in the bitmap are heads of lost
	 * chains.
	 */
	chains = fat_get_head_count(fat);
	for (head = CLUST_FIRST;
	    chains > 0 && head < boot->NumClusters;
	    ) {
		/*
		 * We expect the bitmap to be very sparse, so skip if
		 * the range is full of 0's
		 */
		if (head % LONG_BIT == 0 &&
		    !fat_is_cl_head_in_range(fat, head)) {
			head += LONG_BIT;
			continue;
		}
		if (fat_is_cl_head(fat, head)) {
			ret = checkchain(fat, head, &chainlength);
			if (ret != FSERROR && chainlength > 0) {
				pwarn("Lost cluster chain at cluster %u\n"
				    "%zd Cluster(s) lost\n",
				    head, chainlength);
				mod |= ret = reconnect(fat, head,
				    chainlength);
			}
			if (mod & FSFATAL)
				break;
			if (ret == FSERROR && ask(0, "Clear")) {
				clearchain(fat, head);
				mod |= FSFATMOD;
			}
			chains--;
		}
		head++;
	}

	finishlf();

	if (boot->bpbFSInfo) {
		ret = 0;
		if (boot->FSFree != 0xffffffffU &&
		    boot->FSFree != boot->NumFree) {
			pwarn("Free space in FSInfo block (%u) not correct (%u)\n",
			      boot->FSFree, boot->NumFree);
			if (ask(1, "Fix")) {
				boot->FSFree = boot->NumFree;
				ret = 1;
			}
		}
		if (boot->FSNext != 0xffffffffU &&
		    (boot->FSNext >= boot->NumClusters ||
		    (boot->NumFree && fat_get_cl_next(fat, boot->FSNext) != CLUST_FREE))) {
			pwarn("Next free cluster in FSInfo block (%u) %s\n",
			      boot->FSNext,
			      (boot->FSNext >= boot->NumClusters) ? "invalid" : "not free");
			if (ask(1, "Fix"))
				for (head = CLUST_FIRST; head < boot->NumClusters; head++)
					if (fat_get_cl_next(fat, head) == CLUST_FREE) {
						boot->FSNext = head;
						ret = 1;
						break;
					}
		}
		if (ret)
			mod |= writefsinfo(dosfs, boot);
	}

	return mod;
}
