ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_fs_fat_truncate.c File Reference

ra8_fs_truncate: shrink or grow an open file to an arbitrary length. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_fs.h"
#include "ra8_fs_fat_internal.h"
#include "ra8_fs_meta.h"
Include dependency graph for ra8_fs_fat_truncate.c:

Go to the source code of this file.

Functions

static uint64_t internal_trunc_clusters (uint64_t bytes, uint32_t cbytes)
 Clusters needed to hold bytes at cbytes bytes per cluster.
static ra8_err_t internal_trunc_walk (const ra8_fs_mount_t *m, uint32_t start, uint32_t idx, uint32_t *out)
 Walk idx clusters forward along a chain from start.
static ra8_err_t internal_trunc_zero_span (const ra8_fs_mount_t *m, uint32_t cluster, uint32_t lo, uint32_t hi)
 Write real zeros over the byte range [lo, hi) inside one cluster.
static ra8_err_t internal_fat_trunc_shrink (ra8_fs_file_t *file, uint32_t new_size, uint32_t cbytes)
 Free the cluster tail past new_size on a FAT file.
static ra8_err_t internal_fat_trunc_extend (ra8_fs_file_t *file, uint32_t tail, uint32_t have, uint32_t new_nclus, uint32_t cbytes)
 Append zeroed clusters to a FAT file until it owns new_nclus.
static ra8_err_t internal_fat_trunc_grow (ra8_fs_file_t *file, uint32_t new_size, uint32_t cbytes)
 Grow a FAT file to new_size, zero-filling [old_size, new_size).
static ra8_err_t internal_fat_trunc_commit (ra8_fs_file_t *file)
 Rewrite a FAT file's directory entry after its length changed.
static ra8_err_t internal_fat_trunc (ra8_fs_file_t *file, uint32_t new_size)
 Truncate a FAT file to new_size and commit its directory entry.
static ra8_err_t internal_exfat_free_run (const ra8_fs_mount_t *m, uint32_t first, uint64_t nbytes, uint8_t nofat)
 Release a cluster run by describing it as a Stream-extension entry.
static ra8_err_t internal_exfat_shrink_chain_tail (ra8_fs_file_t *file, uint32_t new_nclus, uint32_t cbytes)
 Trim a FAT-chained exFAT file to new_nclus clusters.
static ra8_err_t internal_exfat_trunc_shrink (ra8_fs_file_t *file, uint64_t new_size, uint32_t cbytes)
 Free an exFAT file's cluster tail past new_size.
static ra8_err_t internal_exfat_trunc (ra8_fs_file_t *file, uint64_t new_size)
 Truncate an exFAT file to new_size and flush its entry set.
static ra8_err_t internal_truncate_locked (ra8_fs_file_t *file, uint64_t new_size)
 Truncate the file behind file – the guarded body of ra8_fs_truncate.
ra8_err_t ra8_fs_truncate (ra8_fs_file_t *file, uint64_t new_size)
 Set an open file's length to new_size, shrinking or growing it.

Detailed Description

ra8_fs_truncate: shrink or grow an open file to an arbitrary length.

The ftruncate() verb, in both directions, on both filesystems (#680). Until now the only truncation was truncate-to-zero on open(write), and a file could not be given a length between "zero" and "everything a writer streamed into it": ra8_fs_seek() clamps to the current size, so a cursor cannot be placed past EOF to extend, and there was no verb to trim to N > 0 bytes.

The shrink half returns the tail clusters to the volume and lowers the recorded length. The grow half is where the two filesystems differ, and both differences are the format speaking:

  • FAT has one length. The bytes between the old end and the new one are read straight off the clusters that back them, so they have to BE zero on disk – the fresh clusters are zero-filled, and so is the slack of the last old cluster.
  • exFAT has two lengths (spec sec 7.4.5). Growing sets DataLength to the new size and leaves ValidDataLength at the written length, so the gap is a valid unwritten PREFIX suffix the read path already serves as zero – no bytes are written for it. A grow that runs past the volume's contiguous space converts the run from NoFatChain to a real FAT chain, reusing the identical streaming-write machinery (#602).

References (every shorthand citation in this file):

  • "exFAT spec" = Microsoft Corp., "exFAT file system specification", revision 1.00, March 2021.

NASA Power-of-Ten compliance:

  • Rule 2: every loop is bounded by the file's cluster count, the byte range being zeroed, or the sectors in one cluster.
  • Rule 3: zero malloc; the largest buffer is one sector on the stack.
  • Rule 7: every bitmap, FAT and backend call is checked.
Since
0.1.0

Definition in file ra8_fs_fat_truncate.c.

Function Documentation

◆ internal_exfat_free_run()

ra8_err_t internal_exfat_free_run ( const ra8_fs_mount_t * m,
uint32_t first,
uint64_t nbytes,
uint8_t nofat )
static

Release a cluster run by describing it as a Stream-extension entry.

priv_exfat_free_clusters already frees either a contiguous run or a FAT chain given a file's Stream entry, so the shrink path hands it a Stream entry describing exactly the SUB-run to release: the first cluster, a byte length whose ceiling is the run's cluster count, and the NoFatChain flag that selects contiguous-count vs chain-walk freeing. Nothing on disk is a real entry – it is a 32-byte argument.

Parameters
[in]mMounted exFAT volume.
[in]firstFirst cluster of the run to free.
[in]nbytesByte length whose cluster ceiling is the run length (> 0).
[in]nofat1 to free a contiguous run, 0 to walk a FAT chain.
Returns
Error code.
Return values
k_ra8_okThe run's clusters read as free in the allocation bitmap.
k_ra8_err_*Bitmap or backend failure.
Precondition
m is non-NULL; first is a real data cluster; nbytes > 0.
When nofat is 0 the chain from first terminates at an EOC marker.
Postcondition
On success the described run reads as free.
FAT contents of the freed clusters are left as-is (bitmap is authority).
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 515 of file ra8_fs_fat_truncate.c.

References k_exfat_entry_bytes, k_exfat_secflag_alloc, k_exfat_secflag_poss, k_exfat_strm_off_clus, k_exfat_strm_off_dlen, k_exfat_strm_off_flags, priv_exfat_free_clusters(), priv_wr32(), and priv_wr64().

Referenced by internal_exfat_shrink_chain_tail(), and internal_exfat_trunc_shrink().

◆ internal_exfat_shrink_chain_tail()

ra8_err_t internal_exfat_shrink_chain_tail ( ra8_fs_file_t * file,
uint32_t new_nclus,
uint32_t cbytes )
static

Trim a FAT-chained exFAT file to new_nclus clusters.

The chained arm of the shrink, split out so ::priv_exfat_trunc_shrink stays inside the statement budget. Walks to the survivor's new tail, caps it with an end-of-chain marker, and frees the remainder off the allocation bitmap by walking the FAT from the tail's old successor. The freed clusters keep their stale FAT links – the bitmap is exFAT's authority (spec sec 7.1) and nothing follows a free cluster's chain.

Parameters
[in,out]fileChained file being shrunk; tail_cluster is updated.
[in]new_nclusClusters to keep (>= 1, < the current allocation).
[in]cbytesBytes per cluster.
Returns
Error code.
Return values
k_ra8_okThe survivor ends at a fresh EOC and the tail is freed.
k_ra8_err_*Bitmap, FAT, or backend error.
Precondition
file is non-NULL, chained (no_fat_chain == 0), on an exFAT volume.
1 <= new_nclus < file->alloc_clusters.
Postcondition
On success tail_cluster is the survivor's last cluster.
On success the freed clusters read as free in the allocation bitmap.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 554 of file ra8_fs_fat_truncate.c.

References internal_exfat_free_run(), internal_trunc_walk(), k_ra8_ok, priv_eoc_write(), priv_fat_get(), and priv_fat_set().

Referenced by internal_exfat_trunc_shrink().

◆ internal_exfat_trunc()

ra8_err_t internal_exfat_trunc ( ra8_fs_file_t * file,
uint64_t new_size )
static

Truncate an exFAT file to new_size and flush its entry set.

Shrink frees the tail; grow takes clusters from the allocation bitmap (converting a run that outgrows its contiguous space to a FAT chain, exactly as a streaming write does) and raises DataLength alone – ValidDataLength stays at the written prefix, so the read path serves the grown gap as zero without a byte being written for it (exFAT spec sec 7.4.5). Either way the entry set is rewritten so a later mount sees the new length.

Parameters
[in,out]fileOpen exFAT file handle.
[in]new_sizeDesired length in bytes.
Returns
Error code.
Return values
k_ra8_okThe file is new_size bytes and its set matches.
k_ra8_err_no_memA grow ran out of free clusters.
k_ra8_err_*Bitmap, FAT, or backend error.
Precondition
file is non-NULL, in use, and opened for writing on an exFAT volume.
file->entry_set_* locate the file's directory entry set.
Postcondition
On success size_bytes == new_size and the Stream entry agrees.
On a grow valid_bytes is unchanged, so the gap reads as zero.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 676 of file ra8_fs_fat_truncate.c.

References internal_exfat_trunc_shrink(), internal_trunc_clusters(), k_ra8_err_no_mem, k_ra8_ok, priv_cluster_bytes(), priv_exfat_ensure_clusters(), and priv_exfat_flush_set().

◆ internal_exfat_trunc_shrink()

ra8_err_t internal_exfat_trunc_shrink ( ra8_fs_file_t * file,
uint64_t new_size,
uint32_t cbytes )
static

Free an exFAT file's cluster tail past new_size.

A contiguous run keeps [first, first + new_nclus) and frees the rest by count; a FAT-chained run re-terminates the survivor's tail and walks the freed remainder off the bitmap. Shrinking to zero drops the whole allocation and returns the handle to the empty shape a fresh open(write) produces.

Parameters
[in,out]fileFile being shrunk; allocation fields are updated.
[in]new_sizeNew length in bytes (< size_bytes).
[in]cbytesBytes per cluster.
Returns
Error code.
Return values
k_ra8_okThe file owns exactly the clusters new_size needs.
k_ra8_err_*Bitmap, FAT, or backend error.
Precondition
file is non-NULL, in use, and on an exFAT volume.
new_size < file->size_bytes and the allocation fields are current.
Postcondition
On success size_bytes == new_size and valid_bytes <= new_size.
On success the freed clusters read as free in the allocation bitmap.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 607 of file ra8_fs_fat_truncate.c.

References internal_exfat_free_run(), internal_exfat_shrink_chain_tail(), internal_trunc_clusters(), and k_ra8_ok.

Referenced by internal_exfat_trunc().

◆ internal_fat_trunc()

ra8_err_t internal_fat_trunc ( ra8_fs_file_t * file,
uint32_t new_size )
static

Truncate a FAT file to new_size and commit its directory entry.

Dispatches to the shrink or grow branch, resets the read accelerator (a shrink can free the cluster it cached, a grow moves the tail), and rewrites the directory entry once.

Parameters
[in,out]fileOpen FAT file handle.
[in]new_sizeDesired length in bytes.
Returns
Error code.
Return values
k_ra8_okThe file is new_size bytes and its entry matches.
k_ra8_err_*Backend, FAT, or no-memory error.
Precondition
file is non-NULL, in use, and opened for writing on a FAT volume.
file->mount is a mounted FAT12/16/32 volume.
Postcondition
On success size_bytes == new_size and the entry is consistent.
The read accelerator is invalidated.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 462 of file ra8_fs_fat_truncate.c.

References internal_fat_trunc_commit(), internal_fat_trunc_grow(), internal_fat_trunc_shrink(), k_ra8_ok, and priv_cluster_bytes().

Referenced by internal_truncate_locked().

◆ internal_fat_trunc_commit()

ra8_err_t internal_fat_trunc_commit ( ra8_fs_file_t * file)
static

Rewrite a FAT file's directory entry after its length changed.

Patches the entry's first cluster and size, and stamps the write time – a truncate is a content change even when no byte is written, so an mtime that still described the old contents would be a lie (#601). Leaves the handle dirty so close flushes FSInfo.

Parameters
[in,out]fileFile whose entry must match its new length.
Returns
Error code.
Return values
k_ra8_okThe on-disk entry reports the new first cluster and size.
k_ra8_err_*Backend read/write failure.
Precondition
file is non-NULL; dir_entry_lba / dir_entry_idx locate its entry.
The mount is a FAT12/16/32 volume.
Postcondition
On success the entry's size equals file->size_bytes.
On success file->dirty is 1.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 418 of file ra8_fs_fat_truncate.c.

References k_ra8_ok, priv_entry_set_cluster_size(), priv_fat_entry_stamp_write(), priv_read_sector(), priv_sec_walk(), and priv_write_sector().

Referenced by internal_fat_trunc().

◆ internal_fat_trunc_extend()

ra8_err_t internal_fat_trunc_extend ( ra8_fs_file_t * file,
uint32_t tail,
uint32_t have,
uint32_t new_nclus,
uint32_t cbytes )
static

Append zeroed clusters to a FAT file until it owns new_nclus.

Allocates the first cluster when the file has none, then links a fresh end-of-chain cluster on at a time, zeroing each as it is created so the grown region reads back as zero. One forward pass, so the cost is linear in the clusters added, not in the file's length.

Parameters
[in,out]fileFile being grown; first_cluster is set when empty.
[in]tailCurrent tail cluster (ignored when have is 0).
[in]haveClusters the file already owns.
[in]new_nclusClusters the file must own on return.
[in]cbytesBytes per cluster.
Returns
Error code.
Return values
k_ra8_okThe file owns new_nclus zeroed clusters.
k_ra8_err_no_memThe volume ran out of free clusters.
k_ra8_err_*Backend or FAT error.
Precondition
file is non-NULL and on a FAT12/16/32 volume.
have <= new_nclus; when have > 0, tail is the current tail.
Postcondition
On success every cluster from index have up reads as zero.
On failure any cluster taken is at worst leaked, reclaimable by fsck.
Note
The loop is bounded by new_nclus, itself bounded by the volume.
Since
0.1.0

Definition at line 298 of file ra8_fs_fat_truncate.c.

References internal_trunc_zero_span(), k_ra8_ok, priv_alloc_eoc_cluster(), and priv_fat_set().

Referenced by internal_fat_trunc_grow().

◆ internal_fat_trunc_grow()

ra8_err_t internal_fat_trunc_grow ( ra8_fs_file_t * file,
uint32_t new_size,
uint32_t cbytes )
static

Grow a FAT file to new_size, zero-filling [old_size, new_size).

Two things must read as zero: the slack of the last old cluster past the old length, and every newly allocated cluster. The slack is cleared first (a read-modify-write that keeps the real file data below it), then the chain is extended from that same cluster so it is walked only once.

Parameters
[in,out]fileFile being grown; first_cluster / size_bytes move.
[in]new_sizeNew length in bytes (> size_bytes).
[in]cbytesBytes per cluster.
Returns
Error code.
Return values
k_ra8_okThe file is new_size bytes and the gap reads zero.
k_ra8_err_no_memThe volume ran out of free clusters.
k_ra8_err_*Backend or FAT error.
Precondition
file is non-NULL, in use, and on a FAT12/16/32 volume.
new_size > file->size_bytes.
Postcondition
On success size_bytes == new_size.
On success a read of [old_size, new_size) returns zeros.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 366 of file ra8_fs_fat_truncate.c.

References internal_fat_trunc_extend(), internal_trunc_clusters(), internal_trunc_walk(), internal_trunc_zero_span(), and k_ra8_ok.

Referenced by internal_fat_trunc().

◆ internal_fat_trunc_shrink()

ra8_err_t internal_fat_trunc_shrink ( ra8_fs_file_t * file,
uint32_t new_size,
uint32_t cbytes )
static

Free the cluster tail past new_size on a FAT file.

Below the new cluster count the chain is left alone; at and above it the survivor's tail is re-capped with an end-of-chain marker and the rest is freed. Shrinking to zero drops the whole chain and clears the file's first cluster, so a later grow starts from nothing.

Parameters
[in,out]fileFile being shrunk; first_cluster and size_bytes are updated in place.
[in]new_sizeNew length in bytes (< size_bytes).
[in]cbytesBytes per cluster.
Returns
Error code.
Return values
k_ra8_okThe file owns exactly the clusters new_size needs.
k_ra8_err_*Backend or FAT error.
Precondition
file is non-NULL, in use, and on a FAT12/16/32 volume.
new_size < file->size_bytes <= k_ra8_fs_fat_max_file_bytes.
Postcondition
On success size_bytes == new_size and the freed clusters read free.
On success the survivor's tail FAT entry is an end-of-chain marker.
Note
Not thread-safe; the public entry holds the library lock.
Since
0.1.0

Definition at line 230 of file ra8_fs_fat_truncate.c.

References internal_trunc_clusters(), internal_trunc_walk(), k_cluster_first_data, k_ra8_ok, priv_eoc_write(), priv_fat_get(), priv_fat_set(), priv_free_chain(), and priv_is_eoc().

Referenced by internal_fat_trunc().

◆ internal_trunc_clusters()

uint64_t internal_trunc_clusters ( uint64_t bytes,
uint32_t cbytes )
static

Clusters needed to hold bytes at cbytes bytes per cluster.

Ceiling division, and 0 for a zero-length file – an empty file owns no clusters on either filesystem, so the caller frees the whole allocation rather than keeping one. 64-bit in and out because an exFAT length may exceed 4 GiB (#676); the FAT callers pass lengths already capped at k_ra8_fs_fat_max_file_bytes.

Parameters
[in]bytesByte length to size.
[in]cbytesBytes per cluster (a power of two >= 512).
Returns
Cluster count.
Return values
0bytes is 0.
>0ceil(bytes / cbytes).
Precondition
cbytes is non-zero.
bytes + cbytes does not overflow (true: a 64-bit length is bounded by the volume and the cluster size is at most 32 MiB).
Postcondition
No state is modified.
The result depends only on the inputs.
Note
Pure function; trivially thread-safe.
Since
0.1.0

Definition at line 82 of file ra8_fs_fat_truncate.c.

Referenced by internal_exfat_trunc(), internal_exfat_trunc_shrink(), internal_fat_trunc_grow(), and internal_fat_trunc_shrink().

◆ internal_trunc_walk()

ra8_err_t internal_trunc_walk ( const ra8_fs_mount_t * m,
uint32_t start,
uint32_t idx,
uint32_t * out )
static

Walk idx clusters forward along a chain from start.

The shared chain walker for the shrink paths: a FAT file's tail is only reachable by following its FAT links, and an exFAT chained file is the same. A chain that ends before idx is a corrupt file, not a short one, so it is reported rather than clamped.

Parameters
[in]mMount providing FAT access.
[in]startFirst cluster of the chain.
[in]idxClusters to advance (0 returns start).
[out]outReceives the cluster reached.
Returns
Error code.
Return values
k_ra8_ok*out is the cluster at index idx.
k_ra8_err_protocol_errorThe chain ended before idx.
k_ra8_err_*Backend or FAT error.
Precondition
m and out are non-NULL; start is a real data cluster.
idx is within the file's real cluster count.
Postcondition
On success *out is a real data cluster.
No volume state is modified.
Note
The loop is bounded by idx, itself bounded by the file's length.
Since
0.1.0

Definition at line 116 of file ra8_fs_fat_truncate.c.

References k_ra8_err_protocol_error, k_ra8_ok, priv_fat_get(), and priv_is_eoc().

Referenced by internal_exfat_shrink_chain_tail(), internal_fat_trunc_grow(), and internal_fat_trunc_shrink().

◆ internal_trunc_zero_span()

ra8_err_t internal_trunc_zero_span ( const ra8_fs_mount_t * m,
uint32_t cluster,
uint32_t lo,
uint32_t hi )
static

Write real zeros over the byte range [lo, hi) inside one cluster.

Sector by sector, read-modify-write: every sector the range touches is read, the covered bytes are cleared, and it is written back. That preserves neighbouring bytes on the two edge sectors – the file data below lo in the first, whatever sits above hi in the last – which is exactly what a FAT grow needs when the old length ends mid-sector. Zeroing a whole fresh cluster is the same call with lo == 0 and hi == cluster bytes.

Parameters
[in]mMount providing the backend.
[in]clusterCluster to zero within.
[in]loFirst byte to clear (offset within the cluster).
[in]hiOne past the last byte to clear.
Returns
Error code.
Return values
k_ra8_okThe range reads as zero (or lo >= hi, nothing to do).
k_ra8_err_*Backend read or write failure.
Precondition
m is non-NULL; hi is within one cluster.
cluster is an allocated data cluster.
Postcondition
On success bytes [lo, hi) of cluster read as zero.
Bytes outside [lo, hi) are unchanged.
Note
The loop is bounded by the sectors the range spans (at most one cluster's worth).
Since
0.1.0

Definition at line 166 of file ra8_fs_fat_truncate.c.

References k_ra8_ok, priv_bps(), priv_cluster_to_lba(), priv_read_sector(), priv_sec_io(), and priv_write_sector().

Referenced by internal_fat_trunc_extend(), and internal_fat_trunc_grow().

◆ internal_truncate_locked()

ra8_err_t internal_truncate_locked ( ra8_fs_file_t * file,
uint64_t new_size )
static

Truncate the file behind file – the guarded body of ra8_fs_truncate.

Validates the handle, dispatches on the mount's filesystem, and finally pulls the offset down if a shrink left it past the new end (the offset is otherwise left where the caller had it, as ftruncate() promises).

Parameters
[in,out]fileOpen file handle in a writing mode.
[in]new_sizeDesired length in bytes.
Returns
Error code.
Return values
k_ra8_okLength set.
k_ra8_err_null_ptrfile is NULL.
k_ra8_err_invalid_stateNot open, or opened read-only.
k_ra8_err_no_memA grow ran out of free clusters.
k_ra8_err_*Backend, FAT, or bitmap failure.
Precondition
The library lock is held (or none is installed).
file came from ra8_fs_open in write or append mode.
Postcondition
On success file->size_bytes == new_size.
On success file->offset == min(old_offset, new_size).
Note
Not thread-safe per file; callers serialise.
The mode/handle guard is one compound decision of two conditions – a closed handle, or a handle opened read-only – and its vectors live with the test that drives it, cited as libs/ra8_fs/src/ra8_fs_fat_truncate.c@priv_truncate_locked.
Since
0.1.0

Definition at line 742 of file ra8_fs_fat_truncate.c.

References internal_fat_trunc(), internal_truncate_locked(), k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_fs_fat_max_file_bytes, k_ra8_fs_mode_read, k_ra8_fs_type_exfat, and k_ra8_ok.

Referenced by internal_truncate_locked(), and ra8_fs_truncate().

◆ ra8_fs_truncate()

ra8_err_t ra8_fs_truncate ( ra8_fs_file_t * file,
uint64_t new_size )
nodiscard

Set an open file's length to new_size, shrinking or growing it.

The ftruncate() verb in both directions (#680), for a handle open in a writing mode. It is the only way to give a file an arbitrary length: writing extends only where bytes land, and ra8_fs_seek clamps to the current size, so neither can pre-size a file or trim it to N > 0 bytes. A shrink frees the tail clusters and lowers the length; a grow extends the file and the gap [old_size, new_size) reads back as zero – FAT zero-fills the fresh clusters on disk, exFAT raises DataLength while ValidDataLength stays at the written prefix so the format serves the gap as zero (and converts a run that outgrows its contiguous space to a real FAT chain). The offset is left where it was, pulled down only by a shrink that lands below it. Lengths are 64-bit: an exFAT file truncates to any size the volume can hold, past 4 GiB included (#676). On FAT12/16/32 a new_size above k_ra8_fs_fat_max_file_bytes is refused with k_ra8_err_invalid_sizeDIR_FileSize is 32-bit, so the format itself cannot express it.

Parameters
[in,out]fileOpen handle in k_ra8_fs_mode_write or _append.
[in]new_sizeDesired length in bytes.
Return values
k_ra8_okLength set; the entry / directory reflects it.
k_ra8_err_null_ptrfile is NULL.
k_ra8_err_invalid_stateNot open, or opened read-only.
k_ra8_err_invalid_sizeFAT volume and new_size exceeds 4 GiB - 1.
k_ra8_err_no_memA grow ran out of free clusters.
k_ra8_err_*Backend, FAT, or bitmap failure.
Precondition
file is a handle from ra8_fs_open() in write or append mode.
Postcondition
On k_ra8_ok ra8_fs_size() reports new_size and a re-read of the gap returns zeros.
On k_ra8_ok the offset is min(old_offset, new_size).
Note
Not thread-safe per file; the public entry holds the library lock.
See also
ra8_fs_write() Extends a file only where bytes are actually written.
Since
0.1.0

Definition at line 770 of file ra8_fs_fat_truncate.c.

References internal_truncate_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_truncate().

Referenced by ra8_fs_truncate().