+ cluster_t have;
+ cluster_t last_cluster;
+ cluster_t next_cluster;
+
+ /* Walk the cluster chain to the
+ * spot where it needs to change. That
+ * will either be the end of the chain (in case it needs to grow),
+ * or after the desired number of clusters, in which case it needs to shrink
+ */
+ next_cluster = first_cluster;
+ last_cluster = 0;
+ DBG("\tclusters:");
+ for (have = 0; have < size; have++) {
+ DBG(" %08x", next_cluster);
+ if (!_ao_fat_cluster_valid(next_cluster))
+ break;
+ last_cluster = next_cluster;
+ next_cluster = _ao_fat_entry_read(next_cluster);
+ }
+ DBG("\n");
+
+ /* At this point, last_cluster points to the last valid
+ * cluster in the file, if any. That's the spot in the FAT
+ * that needs to be rewritten, either to truncate the file by
+ * writing an END marker, or to extend the file by writing
+ * more clusters. next_cluster will contain the value of the
+ * FAT at last_cluster.
+ *
+ * If this is at the head of the cluster chain, then
+ * last_cluster will be zero and next_cluster will
+ * be the first cluster in the chain.
+ */
+ if (have == size) {
+ /* The file is large enough, truncate as needed */
+ if (_ao_fat_cluster_valid(next_cluster)) {
+ DBG("truncate between %08x and %08x\n", last_cluster, next_cluster);
+ if (last_cluster)
+ /*
+ * Otherwise, rewrite the last cluster
+ * in the chain with a LAST marker
+ */
+ (void) _ao_fat_entry_replace(last_cluster,
+ AO_FAT_LAST_CLUSTER);
+ else
+ /*
+ * If the file is getting erased, then
+ * rewrite the directory entry cluster
+ * value
+ */
+ first_cluster = 0;