On Tue, May 26, 2020 at 04:11:50PM +0200, Otto Moerbeek wrote:

> On Tue, May 26, 2020 at 03:54:15PM +0200, Otto Moerbeek wrote:
> 
> > On Tue, May 26, 2020 at 07:51:28AM -0600, Todd C. Miller wrote:
> > 
> > > On Tue, 26 May 2020 12:07:21 +0200, Otto Moerbeek wrote:
> > > 
> > > > Apart from the noting the strange Subject: I also like to mention one
> > > > change in the way cylinder groups are scanned. The current code scans
> > > > forward and backward, which causes an uneven distribution of full cgs
> > > > (the upper end of the cgs will get full first). Fix that by always
> > > > scanning forward, wrapping to cg 0 if needed.
> > > 
> > > Should that be a separate commit?  I can't find any problems
> > > with the diff but I haven't tried running with it yet.
> > > 
> > >  - todd
> > 
> > Yeah, I can do that. Note that it must be comitted first, since the
> > loop condition is always true if I change the loop var to unsigned.
> > 
> >     -Otto
> > 
> 
> And a new diff. I accidentally capitalized a letter just before sending.
> Thanks to naddy for spotting that.

Here's the separate diff for the prefcg loops. From FreeBSD.

OK?

        -Otto


Index: ffs_alloc.c
===================================================================
RCS file: /cvs/src/sys/ufs/ffs/ffs_alloc.c,v
retrieving revision 1.111
diff -u -p -r1.111 ffs_alloc.c
--- ffs_alloc.c 28 May 2020 15:48:29 -0000      1.111
+++ ffs_alloc.c 28 May 2020 18:47:53 -0000
@@ -515,7 +518,7 @@ ffs_dirpref(struct inode *pip)
                maxcontigdirs = 1;
 
        /*
-        * Limit number of dirs in one cg and reserve space for 
+        * Limit number of dirs in one cg and reserve space for
         * regular files, but only if we have no deficit in
         * inodes or space.
         *
@@ -524,16 +527,17 @@ ffs_dirpref(struct inode *pip)
         * We scan from our preferred cylinder group forward looking
         * for a cylinder group that meets our criterion. If we get
         * to the final cylinder group and do not find anything,
-        * we start scanning backwards from our preferred cylinder
-        * group. The ideal would be to alternate looking forward
-        * and backward, but tha tis just too complex to code for
-        * the gain it would get. The most likely place where the
-        * backward scan would take effect is when we start near
-        * the end of the filesystem and do not find anything from
-        * where we are to the end. In that case, scanning backward
-        * will likely find us a suitable cylinder group much closer
-        * to our desired location than if we were to start scanning
-        * forward from the beginning for the filesystem.
+        * we start scanning forwards from the beginning of the
+        * filesystem. While it might seem sensible to start scanning
+        * backwards or even to alternate looking forward and backward,
+        * this approach fails badly when the filesystem is nearly full.
+        * Specifically, we first search all the areas that have no space
+        * and finally try the one preceding that. We repeat this on
+        * every request and in the case of the final block end up
+        * searching the entire filesystem. By jumping to the front
+        * of the filesystem, our future forward searches always look
+        * in new cylinder groups so finds every possible block after
+        * one pass over the filesystem.
         */
        for (cg = prefcg; cg < fs->fs_ncg; cg++)
                if (fs->fs_cs(fs, cg).cs_ndir < maxndir &&
@@ -542,7 +546,7 @@ ffs_dirpref(struct inode *pip)
                        if (fs->fs_contigdirs[cg] < maxcontigdirs)
                                goto end;
                }
-       for (cg = prefcg - 1; cg >= 0; cg--)
+       for (cg = 0; cg < prefcg; cg++)
                if (fs->fs_cs(fs, cg).cs_ndir < maxndir &&
                    fs->fs_cs(fs, cg).cs_nifree >= minifree &&
                    fs->fs_cs(fs, cg).cs_nbfree >= minbfree) {
@@ -555,7 +559,7 @@ ffs_dirpref(struct inode *pip)
        for (cg = prefcg; cg < fs->fs_ncg; cg++)
                if (fs->fs_cs(fs, cg).cs_nifree >= avgifree)
                        goto end;
-       for (cg = prefcg - 1; cg >= 0; cg--)
+       for (cg = 0; cg < prefcg; cg++)
                if (fs->fs_cs(fs, cg).cs_nifree >= avgifree)
                        goto end;
 end:

Reply via email to