Date: Tue, 18 May 2021 20:22:43 GMT From: Kirk McKusick <mckusick@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: e2a49768a4ad - stable/13 - Ensure that files with no allocated blocks are trimmed to zero length. Message-ID: <202105182022.14IKMhSO004498@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=e2a49768a4ad938c4dc0b9ce11298b409832a9ab commit e2a49768a4ad938c4dc0b9ce11298b409832a9ab Author: Kirk McKusick <mckusick@FreeBSD.org> AuthorDate: 2021-05-11 21:51:06 +0000 Commit: Kirk McKusick <mckusick@FreeBSD.org> 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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105182022.14IKMhSO004498>