The branch stable/14 has been updated by kib:

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

commit 6149261d549b3b5072fe69b498f26e8172de1623
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-01-05 22:51:23 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-01-20 02:40:09 +0000

    ffs_reallocblks(): ensure that pref cg is valid
    
    (cherry picked from commit dc37121d3210d08c96a883ebfed780660e7e2b39)
---
 sys/ufs/ffs/ffs_alloc.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index d08a51264fdb..b586ab8e126a 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -683,6 +683,7 @@ ffs_reallocblks_ufs1(
         * groups that we will search.
         */
        cg = dtog(fs, pref);
+       MPASS(cg < fs->fs_ncg);
        for (i = min(maxclustersearch, fs->fs_ncg); i > 0; i--) {
                if ((newblk = ffs_clusteralloc(ip, cg, pref, len)) != 0)
                        break;
@@ -949,6 +950,7 @@ ffs_reallocblks_ufs2(
         * groups that we will search.
         */
        cg = dtog(fs, pref);
+       MPASS(cg < fs->fs_ncg);
        for (i = min(maxclustersearch, fs->fs_ncg); i > 0; i--) {
                if ((newblk = ffs_clusteralloc(ip, cg, pref, len)) != 0)
                        break;
@@ -1440,8 +1442,11 @@ ffs_blkpref_ufs1(struct inode *ip,
                 * place it immediately following the last direct block.
                 */
                if (indx == -1 && lbn < UFS_NDADDR + NINDIR(fs) &&
-                   ip->i_din1->di_db[UFS_NDADDR - 1] != 0)
+                   ip->i_din1->di_db[UFS_NDADDR - 1] != 0) {
                        pref = ip->i_din1->di_db[UFS_NDADDR - 1] + fs->fs_frag;
+                       if (dtog(fs, pref) >= fs->fs_ncg)
+                               pref = 0;
+               }
                return (pref);
        }
        /*
@@ -1452,8 +1457,11 @@ ffs_blkpref_ufs1(struct inode *ip,
        if (lbn == UFS_NDADDR) {
                pref = ip->i_din1->di_ib[0];
                if (pref != 0 && pref >= cgdata(fs, inocg) &&
-                   pref < cgbase(fs, inocg + 1))
+                   pref < cgbase(fs, inocg + 1)) {
+                       if (dtog(fs, pref + fs->fs_frag) >= fs->fs_ncg)
+                               return (0);
                        return (pref + fs->fs_frag);
+               }
        }
        /*
         * If we are at the beginning of a file, or we have already allocated
@@ -1508,6 +1516,8 @@ ffs_blkpref_ufs1(struct inode *ip,
        /*
         * Otherwise, we just always try to lay things out contiguously.
         */
+       if (dtog(fs, prevbn + fs->fs_frag) >= fs->fs_ncg)
+               return (0);
        return (prevbn + fs->fs_frag);
 }
 
@@ -1552,8 +1562,11 @@ ffs_blkpref_ufs2(struct inode *ip,
                 * place it immediately following the last direct block.
                 */
                if (indx == -1 && lbn < UFS_NDADDR + NINDIR(fs) &&
-                   ip->i_din2->di_db[UFS_NDADDR - 1] != 0)
+                   ip->i_din2->di_db[UFS_NDADDR - 1] != 0) {
                        pref = ip->i_din2->di_db[UFS_NDADDR - 1] + fs->fs_frag;
+                       if (dtog(fs, pref) >= fs->fs_ncg)
+                               pref = 0;
+               }
                return (pref);
        }
        /*
@@ -1564,8 +1577,11 @@ ffs_blkpref_ufs2(struct inode *ip,
        if (lbn == UFS_NDADDR) {
                pref = ip->i_din2->di_ib[0];
                if (pref != 0 && pref >= cgdata(fs, inocg) &&
-                   pref < cgbase(fs, inocg + 1))
+                   pref < cgbase(fs, inocg + 1)) {
+                       if (dtog(fs, pref + fs->fs_frag) >= fs->fs_ncg)
+                               return (0);
                        return (pref + fs->fs_frag);
+               }
        }
        /*
         * If we are at the beginning of a file, or we have already allocated
@@ -1620,6 +1636,8 @@ ffs_blkpref_ufs2(struct inode *ip,
        /*
         * Otherwise, we just always try to lay things out contiguously.
         */
+       if (dtog(fs, prevbn + fs->fs_frag) >= fs->fs_ncg)
+               return (0);
        return (prevbn + fs->fs_frag);
 }
 
@@ -1970,6 +1988,7 @@ ffs_clusteralloc(struct inode *ip,
 
        ump = ITOUMP(ip);
        fs = ump->um_fs;
+       MPASS(cg < fs->fs_ncg);
        if (fs->fs_maxcluster[cg] < len)
                return (0);
        UFS_UNLOCK(ump);

Reply via email to