How does the encoding of sysctl_rdint as [1,0] sound?

OK?

>From 27fda35ce0990df113dab99f2e4018e63b5390d7 Mon Sep 17 00:00:00 2001
From: Greg Steuck <g...@nest.cx>
Date: Sun, 1 Nov 2020 19:14:12 -0800
Subject: [PATCH] Convert ffs_sysctl to sysctl_bounded_args

Requires sysctl_bounded_arr branch to support sysctl_rdint.
The read-only variables are marked by an empty range of [1, 0].
---
 sys/kern/kern_sysctl.c   | 10 ++++-
 sys/sys/sysctl.h         |  2 +-
 sys/ufs/ffs/ffs_vfsops.c | 88 ++++++++++++++--------------------------
 3 files changed, 39 insertions(+), 61 deletions(-)

diff --git sys/kern/kern_sysctl.c sys/kern/kern_sysctl.c
index ccf0e5ffa05..87419cf2d17 100644
--- sys/kern/kern_sysctl.c
+++ sys/kern/kern_sysctl.c
@@ -938,8 +938,14 @@ sysctl_bounded_arr(const struct sysctl_bounded_args 
*valpp, u_int valplen,
                return (ENOTDIR);
        for (i = 0; i < valplen; ++i) {
                if (valpp[i].mib == name[0]) {
-                       return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
-                           valpp[i].var, valpp[i].minimum, valpp[i].maximum));
+                       if (valpp[i].minimum <= valpp[i].maximum) {
+                               return (sysctl_int_bounded(oldp, oldlenp, newp,
+                                   newlen, valpp[i].var, valpp[i].minimum,
+                                   valpp[i].maximum));
+                       } else {
+                               return (sysctl_rdint(oldp, oldlenp, newp,
+                                   *valpp[i].var));
+                       }
                }
        }
        return (EOPNOTSUPP);
diff --git sys/sys/sysctl.h sys/sys/sysctl.h
index 5e5115d4f4e..f8f36cfb55b 100644
--- sys/sys/sysctl.h
+++ sys/sys/sysctl.h
@@ -984,7 +984,7 @@ struct sysctl_bounded_args {
        int mib;     /* identifier shared with userspace as a CTL_ #define */
        int *var;    /* never NULL */
        int minimum; /* checking is disabled if minimum == maximum  */
-       int maximum;
+       int maximum; /* read-only variable if minimum > maximum */
 };
 
 /*
diff --git sys/ufs/ffs/ffs_vfsops.c sys/ufs/ffs/ffs_vfsops.c
index 5bfec8dc339..70ded4d905d 100644
--- sys/ufs/ffs/ffs_vfsops.c
+++ sys/ufs/ffs/ffs_vfsops.c
@@ -1568,69 +1568,41 @@ ffs_init(struct vfsconf *vfsp)
        return (ufs_init(vfsp));
 }
 
-/*
- * fast filesystem related variables.
- */
-int
-ffs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
-    size_t newlen, struct proc *p)
-{
 #ifdef FFS_SOFTUPDATES
-       extern int max_softdeps, tickdelay, stat_worklist_push;
-       extern int stat_blk_limit_push, stat_ino_limit_push, stat_blk_limit_hit;
-       extern int stat_ino_limit_hit, stat_sync_limit_hit, stat_indir_blk_ptrs;
-       extern int stat_inode_bitmap, stat_direct_blk_ptrs, stat_dir_entry;
+extern int max_softdeps, tickdelay, stat_worklist_push;
+extern int stat_blk_limit_push, stat_ino_limit_push, stat_blk_limit_hit;
+extern int stat_ino_limit_hit, stat_sync_limit_hit, stat_indir_blk_ptrs;
+extern int stat_inode_bitmap, stat_direct_blk_ptrs, stat_dir_entry;
 #endif
-
-       /* all sysctl names at this level are terminal */
-       if (namelen != 1)
-               return (ENOTDIR);               /* overloaded */
-
-       switch (name[0]) {
-       case FFS_CLUSTERREAD:
-       case FFS_CLUSTERWRITE:
-       case FFS_REALLOCBLKS:
-       case FFS_ASYNCFREE:
-               return (EOPNOTSUPP);
+const struct sysctl_bounded_args ffs_vars[] = {
 #ifdef FFS_SOFTUPDATES
-       case FFS_MAX_SOFTDEPS:
-               return (sysctl_int(oldp, oldlenp, newp, newlen, &max_softdeps));
-       case FFS_SD_TICKDELAY:
-               return (sysctl_int(oldp, oldlenp, newp, newlen, &tickdelay));
-       case FFS_SD_WORKLIST_PUSH:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_worklist_push));
-       case FFS_SD_BLK_LIMIT_PUSH:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_blk_limit_push));
-       case FFS_SD_INO_LIMIT_PUSH:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_ino_limit_push));
-       case FFS_SD_BLK_LIMIT_HIT:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_blk_limit_hit));
-       case FFS_SD_INO_LIMIT_HIT:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_ino_limit_hit));
-       case FFS_SD_SYNC_LIMIT_HIT:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_sync_limit_hit));
-       case FFS_SD_INDIR_BLK_PTRS:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_indir_blk_ptrs));
-       case FFS_SD_INODE_BITMAP:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_inode_bitmap));
-       case FFS_SD_DIRECT_BLK_PTRS:
-               return (sysctl_rdint(oldp, oldlenp, newp, 
stat_direct_blk_ptrs));
-       case FFS_SD_DIR_ENTRY:
-               return (sysctl_rdint(oldp, oldlenp, newp, stat_dir_entry));
+       { FFS_MAX_SOFTDEPS, &max_softdeps, 0, INT_MAX },
+       { FFS_SD_TICKDELAY, &tickdelay, 2, INT_MAX },
+       { FFS_SD_WORKLIST_PUSH, &stat_worklist_push, 1, 0 }, /* read-only */
+       { FFS_SD_BLK_LIMIT_PUSH, &stat_blk_limit_push, 1, 0 },
+       { FFS_SD_INO_LIMIT_PUSH, &stat_ino_limit_push, 1, 0 },
+       { FFS_SD_BLK_LIMIT_HIT, &stat_blk_limit_hit, 1, 0 },
+       { FFS_SD_INO_LIMIT_HIT, &stat_ino_limit_hit, 1, 0 },
+       { FFS_SD_SYNC_LIMIT_HIT, &stat_sync_limit_hit, 1, 0 },
+       { FFS_SD_INDIR_BLK_PTRS, &stat_indir_blk_ptrs, 1, 0 },
+       { FFS_SD_INODE_BITMAP, &stat_inode_bitmap, 1, 0 },
+       { FFS_SD_DIRECT_BLK_PTRS, &stat_direct_blk_ptrs, 1, 0 },
+       { FFS_SD_DIR_ENTRY, &stat_dir_entry, 1, 0 },
 #endif
 #ifdef UFS_DIRHASH
-       case FFS_DIRHASH_DIRSIZE:
-               return (sysctl_int(oldp, oldlenp, newp, newlen,
-                   &ufs_mindirhashsize));
-       case FFS_DIRHASH_MAXMEM:
-               return (sysctl_int(oldp, oldlenp, newp, newlen,
-                   &ufs_dirhashmaxmem));
-       case FFS_DIRHASH_MEM:
-               return (sysctl_rdint(oldp, oldlenp, newp, ufs_dirhashmem));
+       { FFS_DIRHASH_DIRSIZE, &ufs_mindirhashsize, 0, INT_MAX },
+       { FFS_DIRHASH_MAXMEM, &ufs_dirhashmaxmem, 0, INT_MAX },
+       { FFS_DIRHASH_MEM, &ufs_dirhashmem, 1, 0 },
 #endif
+};
 
-       default:
-               return (EOPNOTSUPP);
-       }
-       /* NOTREACHED */
+/*
+ * fast filesystem related variables.
+ */
+int
+ffs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+    size_t newlen, struct proc *p)
+{
+       return sysctl_bounded_arr(ffs_vars, nitems(ffs_vars), name,
+           namelen, oldp, oldlenp, newp, newlen);
 }
-- 
2.29.1

Reply via email to