summaryrefslogtreecommitdiff
path: root/scripts/Makefile.thinlto
diff options
context:
space:
mode:
authorHengyu Liang <hengyul@cs.unc.edu>2026-10-12 05:40:46 -0400
committerNamjae Jeon <linkinjeon@kernel.org>2026-10-21 08:28:32 +0900
commitb4c282c0d82e8715ea9ed0b35813a3f365e3f952 (patch)
tree8fe8b982b554c404b75b94fb30ba4de98462ec10 /scripts/Makefile.thinlto
parent0550ac7f5f577e34e5fcf2bd7a51965f5c1b0194 (diff)
downloadlinux-b4c282c0d82e8715ea9ed0b35813a3f365e3f952.tar.gz
linux-b4c282c0d82e8715ea9ed0b35813a3f365e3f952.zip
exfat: free clusters beyond EOF when a write fails or is short
Commit 82a81a7352bc ("exfat: add iomap buffered I/O support") and commit 867b9c96dc83 ("exfat: add iomap direct I/O support") made a write allocate the clusters for its whole range in one step. They also dropped exfat_write_failed(), which freed the clusters beyond the end of the file after a failed or short write. However, a write can stop early, for example when the process is killed or when a part of the buffer cannot be read. As of now, the clusters for the part that was not written stay allocated beyond the end of the file. exfat_cont_expand() does not expect them, so a later write or truncate that extends the file fails with ENOSPC. The directory entry records only the size of the file, so the space can be lost for good once the volume is unmounted. The issue can be reproduced on a 64M volume made by mkfs.exfat and mounted on /mnt, with a write of 1M from a buffer that has only its first 4K mapped: #include <fcntl.h> #include <stdio.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> int main(void) { char *p = mmap(NULL, 8192, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); int fd = open("/mnt/f", O_CREAT | O_WRONLY, 0644); struct stat st; munmap(p + 4096, 4096); printf("write: %zd\n", write(fd, p, 1 << 20)); fstat(fd, &st); printf("blocks: %ld\n", (long)st.st_blocks); printf("ftruncate: %d\n", ftruncate(fd, 1 << 16)); return 0; } Before commit 82a81a7352bc ("exfat: add iomap buffered I/O support"), the result is: write: 4096 blocks: 8 ftruncate: 0 After that commit, the result is: write: 4096 blocks: 2048 ftruncate: -1 This patch will bring back exfat_write_failed() and call it when a write ends before the end of its range, so that the clusters beyond the end of the file are freed again. It waits for direct I/O in flight first, as exfat_setattr() does before it frees clusters. Fixes: 82a81a7352bc ("exfat: add iomap buffered I/O support") Fixes: 867b9c96dc83 ("exfat: add iomap direct I/O support") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions