The branch stable/13 has been updated by mckusick:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e2a49768a4ad938c4dc0b9ce11298b409832a9ab

commit e2a49768a4ad938c4dc0b9ce11298b409832a9ab
Author:     Kirk McKusick <[email protected]>
AuthorDate: 2021-05-11 21:51:06 +0000
Commit:     Kirk McKusick <[email protected]>
CommitDate: 2021-05-18 20:26:00 +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 c1f1b1ec04f5..319a324cc070 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -248,7 +248,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)
@@ -429,25 +429,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)
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to