git: 80e3f1df8ca8 - stable/12 - Ensure that files with no allocated blocks are trimmed to zero length.
Kirk McKusick
mckusick at FreeBSD.org
Tue May 18 20:25:41 UTC 2021
The branch stable/12 has been updated by mckusick:
URL: https://cgit.FreeBSD.org/src/commit/?id=80e3f1df8ca8d355b31f1b7596e025edb3a2746d
commit 80e3f1df8ca8d355b31f1b7596e025edb3a2746d
Author: Kirk McKusick <mckusick at FreeBSD.org>
AuthorDate: 2021-05-11 21:51:06 +0000
Commit: Kirk McKusick <mckusick at FreeBSD.org>
CommitDate: 2021-05-18 20:28:34 +0000
Ensure that files with no allocated blocks are trimmed to zero length.
(cherry picked from commit a3628327e7b62c955e7bad9e43044cdb01984d80)
---
sbin/fsck_ffs/pass1.c | 38 +++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c
index 81aa73bffc26..4cfacef2a4d0 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -247,7 +247,7 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
off_t kernmaxfilesize;
ufs2_daddr_t ndb;
mode_t mode;
- uintmax_t fixsize;
+ intmax_t size, fixsize;
int j, ret, offset;
if ((dp = getnextinode(inumber, rebuildcg)) == NULL)
@@ -424,25 +424,37 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
}
}
/*
+ * UFS does not allow files to end with a hole; it requires that
+ * the last block of a file be allocated. The last allocated block
+ * in a file is tracked in id_lballoc. Here, we check for a size
+ * past the last allocated block of the file and if that is found,
+ * shorten the file to reference the last allocated block to avoid
+ * having it reference a hole at its end.
+ *
* Soft updates will always ensure that the file size is correct
* for files that contain only direct block pointers. However
* soft updates does not roll back sizes for files with indirect
* blocks that it has set to unallocated because their contents
* have not yet been written to disk. Hence, the file can appear
* to have a hole at its end because the block pointer has been
- * rolled back to zero. Thus, id_lballoc tracks the last allocated
- * block in the file. Here, for files that extend into indirect
- * blocks, we check for a size past the last allocated block of
- * the file and if that is found, shorten the file to reference
- * the last allocated block to avoid having it reference a hole
- * at its end.
+ * rolled back to zero. Thus finding a hole at the end of a file
+ * that is located in an indirect block receives only a warning
+ * while finding a hole at the end of a file in a direct block
+ * receives a fatal error message.
*/
- if (DIP(dp, di_size) > UFS_NDADDR * sblock.fs_bsize &&
- idesc->id_lballoc < lblkno(&sblock, DIP(dp, di_size) - 1)) {
- fixsize = lblktosize(&sblock, idesc->id_lballoc + 1);
- pwarn("INODE %lu: FILE SIZE %ju BEYOND END OF ALLOCATED FILE, "
- "SIZE SHOULD BE %ju", (u_long)inumber,
- (uintmax_t)DIP(dp, di_size), fixsize);
+ size = DIP(dp, di_size);
+ if (idesc->id_lballoc < lblkno(&sblock, size - 1) &&
+ /* exclude embedded symbolic links */
+ ((mode != IFLNK) || size >= sblock.fs_maxsymlinklen)) {
+ fixsize = lblktosize(&sblock, idesc->id_lballoc + 1);
+ if (size > UFS_NDADDR * sblock.fs_bsize)
+ pwarn("INODE %lu: FILE SIZE %ju BEYOND END OF "
+ "ALLOCATED FILE, SIZE SHOULD BE %ju",
+ (u_long)inumber, size, fixsize);
+ else
+ pfatal("INODE %lu: FILE SIZE %ju BEYOND END OF "
+ "ALLOCATED FILE, SIZE SHOULD BE %ju",
+ (u_long)inumber, size, fixsize);
if (preen)
printf(" (ADJUSTED)\n");
else if (reply("ADJUST") == 0)
More information about the dev-commits-src-branches
mailing list