]> Zhao Yanbai Git Server - minix.git/commitdiff
add -lminixfs with fs support routines
authorBen Gras <ben@minix3.org>
Thu, 8 Sep 2011 16:49:54 +0000 (16:49 +0000)
committerBen Gras <ben@minix3.org>
Thu, 8 Sep 2011 16:52:13 +0000 (16:52 +0000)
. move cache size heuristic from mfs there
  so mfs and ext2 can share it
. add vfs credentials retrieving function, with
  backwards compatability from previous struct
  format, to be used by both ext2 and mfs
. fix for ext2 - STATICINIT was fed no.
  of bytes instead of no. of elements, overallocating
  memory by a megabyte or two for the superblock

19 files changed:
common/include/Makefile.inc
common/include/minix/libminixfs.h [new file with mode: 0644]
common/include/minix/vfsif.h
include/limits.h
lib/Makefile
lib/libminixfs/Makefile [new file with mode: 0644]
lib/libminixfs/cache.c [new file with mode: 0644]
lib/libminixfs/fetch_credentials.c [new file with mode: 0644]
lib/libminixfs/minixfs.h [new file with mode: 0644]
servers/ext2/Makefile
servers/ext2/cache.c
servers/ext2/main.c
servers/ext2/mount.c
servers/ext2/path.c
servers/ext2/proto.h
servers/ext2/super.c
servers/mfs/Makefile
servers/mfs/cache.c
servers/mfs/path.c

index 2736db87f5e204170060c27af71491b76f8a3ad1..e06146a925c83f95dd2c978cd49819f51897c203 100644 (file)
@@ -18,7 +18,7 @@ INCS+=        minix/acpi.h minix/ansi.h minix/audio_fw.h minix/bitmap.h \
        minix/sound.h minix/spin.h minix/sys_config.h minix/sysinfo.h \
        minix/syslib.h minix/sysutil.h minix/timers.h minix/type.h \
        minix/tty.h minix/u64.h minix/usb.h minix/usb_ch9.h minix/vm.h \
-       minix/vfsif.h minix/vtreefs.h
+       minix/vfsif.h minix/vtreefs.h minix/libminixfs.h
 
 INCS+= net/gen/arp_io.h net/gen/dhcp.h net/gen/ether.h \
        net/gen/eth_hdr.h net/gen/eth_io.h net/gen/icmp.h \
diff --git a/common/include/minix/libminixfs.h b/common/include/minix/libminixfs.h
new file mode 100644 (file)
index 0000000..96d2b3e
--- /dev/null
@@ -0,0 +1,16 @@
+/* Prototypes for -lminixfs. */
+
+#ifndef _MINIX_FSLIB_H
+#define _MINIX_FSLIB_H
+
+#include <minix/safecopies.h>
+#include <minix/sef.h>
+#include <minix/vfsif.h>
+
+int fs_lookup_credentials(vfs_ucred_t *credentials,
+        uid_t *caller_uid, gid_t *caller_gid, cp_grant_id_t grant2, size_t cred_size);
+u32_t fs_bufs_heuristic(int minbufs, u32_t btotal, u32_t bfree,
+       int blocksize, dev_t majordev);
+
+#endif /* _MINIX_FSLIB_H */
+
index 6c40de2a04556d361f11d610176b7eafb2b95943..2bde532a2c61c9ac836f8b3d0e5a0e89cbb77632 100644 (file)
@@ -82,6 +82,16 @@ typedef struct {
        gid_t vu_sgroups[NGROUPS_MAX];
 } vfs_ucred_t;
 
+#define NGROUPS_MAX_OLD        8
+/* User credential structure before increasing
+ * uid_t and gid_t u8_t */
+typedef struct {
+       short vu_uid;
+       char vu_gid;
+       int vu_ngroups;
+       char vu_sgroups[NGROUPS_MAX_OLD];
+} vfs_ucred_old_t;
+
 /* Request numbers */
 #define REQ_GETNODE    (VFS_BASE + 1)  /* Should be removed */
 #define REQ_PUTNODE    (VFS_BASE + 2)
index 792d3c1d849370ce8a83b994ea92d14ef9ca88dd..23b1c35867b212cb700bbd6bb357c2bb39a2ddb5 100644 (file)
@@ -83,7 +83,6 @@
 /* Some of these old names had better be defined when not POSIX. */
 #define _NO_LIMIT          100 /* arbitrary number; limit not enforced */
 
-#define NGROUPS_MAX          8 /* max. number of supplemental groups */
 #if _EM_WSIZE > 2
 #define ARG_MAX          262144 /* # bytes of args + environ for exec() */
 #else
 #define IOV_MAX        INT_MAX  /* maximum number of buffers for readv/writev */
 #endif /* _POSIX_SOURCE */
 
+#define NGROUPS_MAX          8 /* max. number of supplemental groups */
+
 #define GID_MAX                USHRT_MAX
 #define UID_MAX                USHRT_MAX
 
index 1009b1fa57a990c1b6e95b09975415bdf96f8c24..9cdb5f778f09b761eaefb7beecb19a485d9efa89 100644 (file)
@@ -18,7 +18,7 @@ SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libdriver libnetdriver \
        libedit ${LIBM_DIR} libsys libtimers libminixutil libbz2 libl libhgfs  \
        libz libfetch libarchive libvtreefs libaudiodriver libmthread     \
        libexec libdevman libusb ${LIBMINLIB_DIR} ${LIBASYN_DIR}          \
-       libddekit
+       libddekit libminixfs
 
 .if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
 SUBDIR+= libelf libminc libcrypt libterminfo libcurses libvassert
diff --git a/lib/libminixfs/Makefile b/lib/libminixfs/Makefile
new file mode 100644 (file)
index 0000000..ade0703
--- /dev/null
@@ -0,0 +1,8 @@
+# Makefile for libminixfs
+.include <bsd.own.mk>
+
+LIB=           minixfs
+
+SRCS=          fetch_credentials.c cache.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libminixfs/cache.c b/lib/libminixfs/cache.c
new file mode 100644 (file)
index 0000000..bf43750
--- /dev/null
@@ -0,0 +1,59 @@
+
+#define _SYSTEM
+
+#include <minix/libminixfs.h>
+#include <minix/dmap.h>
+#include <minix/u64.h>
+#include <sys/param.h>
+#include <errno.h>
+
+u32_t fs_bufs_heuristic(int minbufs, u32_t btotal, u32_t bfree, 
+         int blocksize, dev_t majordev)
+{
+  struct vm_stats_info vsi;
+  int bufs;
+  u32_t kbytes_used_fs, kbytes_total_fs, kbcache, kb_fsmax;
+  u32_t kbytes_remain_mem, bused;
+
+  bused = btotal-bfree;
+
+  /* but we simply need minbufs no matter what, and we don't
+   * want more than that if we're a memory device
+   */
+  if(majordev == MEMORY_MAJOR) {
+       return minbufs;
+  }
+
+  /* set a reasonable cache size; cache at most a certain
+   * portion of the used FS, and at most a certain %age of remaining
+   * memory
+   */
+  if((vm_info_stats(&vsi) != OK)) {
+       bufs = 1024;
+       printf("fslib: heuristic info fail: default to %d bufs\n", bufs);
+       return bufs;
+  }
+
+  kbytes_remain_mem = div64u(mul64u(vsi.vsi_free, vsi.vsi_pagesize), 1024);
+
+  /* check fs usage. */
+  kbytes_used_fs = div64u(mul64u(bused, blocksize), 1024);
+  kbytes_total_fs = div64u(mul64u(btotal, blocksize), 1024);
+
+  /* heuristic for a desired cache size based on FS usage;
+   * but never bigger than half of the total filesystem
+   */
+  kb_fsmax = sqrt_approx(kbytes_used_fs)*40;
+  kb_fsmax = MIN(kb_fsmax, kbytes_total_fs/2);
+
+  /* heuristic for a maximum usage - 10% of remaining memory */
+  kbcache = MIN(kbytes_remain_mem/10, kb_fsmax);
+  bufs = kbcache * 1024 / blocksize;
+
+  /* but we simply need MINBUFS no matter what */
+  if(bufs < minbufs)
+       bufs = minbufs;
+
+  return bufs;
+}
+
diff --git a/lib/libminixfs/fetch_credentials.c b/lib/libminixfs/fetch_credentials.c
new file mode 100644 (file)
index 0000000..26f62d2
--- /dev/null
@@ -0,0 +1,51 @@
+
+#include <minix/vfsif.h>
+#include <minix/type.h>
+#include <assert.h>
+
+#include "minixfs.h"
+
+int fs_lookup_credentials(vfs_ucred_t *credentials,
+       uid_t *caller_uid, gid_t *caller_gid, cp_grant_id_t grant2, size_t cred_size)
+{
+  vfs_ucred_old_t old_cred;
+  int r;
+
+  memset(credentials, 0, sizeof(*credentials));
+
+  if(cred_size == sizeof(*credentials)) {
+           r = sys_safecopyfrom(VFS_PROC_NR, grant2, (vir_bytes) 0,
+                                (vir_bytes) credentials, cred_size, D);
+           if (r != OK) {
+               printf("FS: cred copy (regular) failed.\n");
+               return(r);
+          }
+  } else if(cred_size == sizeof(old_cred)) {
+           int g;
+           r = sys_safecopyfrom(VFS_PROC_NR, grant2, (vir_bytes) 0,
+                                (vir_bytes) &old_cred, sizeof(old_cred), D);
+           if (r != OK) {
+               printf("FS: cred copy (fallback) failed.\n");
+               return(r);
+          }
+           credentials->vu_ngroups = old_cred.vu_ngroups;
+           credentials->vu_uid = old_cred.vu_uid;
+           credentials->vu_gid = old_cred.vu_gid;
+           for(g = 0; g < NGROUPS_MAX_OLD; g++) {
+                  assert(g < NGROUPS_MAX);
+                   credentials->vu_sgroups[g] = old_cred.vu_sgroups[g];
+           }
+  } else {
+          static int w = 0;
+          if(!w) { printf("FS: cred size incompatible with VFS.\n"); w = 1; }
+           return(EINVAL); /* Wrong size. */
+  }
+
+   assert(credentials->vu_ngroups <= NGROUPS_MAX);
+
+   *caller_uid = credentials->vu_uid;
+   *caller_gid = credentials->vu_gid;
+
+   return OK;
+}
+
diff --git a/lib/libminixfs/minixfs.h b/lib/libminixfs/minixfs.h
new file mode 100644 (file)
index 0000000..30d70b9
--- /dev/null
@@ -0,0 +1,4 @@
+#define _SYSTEM
+
+#include <lib.h>               /* common to all libraries */
+#include <minix/com.h>         /* need task numbers + message types */
index 02e4aa8c4b087712602b1fc528d9b6e65e983f20..35bd6892e50e9c8e90df809425a183af2096feb0 100644 (file)
@@ -6,14 +6,11 @@ SRCS= balloc.c cache.c device.c link.c \
        write.c ialloc.c inode.c main.c path.c \
        super.c optset.c
 DPADD+=        ${LIBSYS}
-LDADD+=        -lsys
+LDADD+= -lminixfs -lsys
 
 MAN=
 
 BINDIR?= /sbin
 INSTALLFLAGS+= -S 128k
 
-DEFAULT_NR_BUFS= 1024
-CPPFLAGS+= -DDEFAULT_NR_BUFS=${DEFAULT_NR_BUFS}
-
 .include <minix.service.mk>
index e4a213b9d0d7670e0d1a88f5d07df126477dafe5..2b0305d85b92816cbc16eaa9a3ed1960441e766c 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "fs.h"
 #include <minix/u64.h>
+#include <minix/libminixfs.h>
 #include <stdlib.h>
 #include <assert.h>
 #include "buf.h"
@@ -489,10 +490,12 @@ PRIVATE void rm_lru(
 /*===========================================================================*
  *                             set_blocksize                                *
  *===========================================================================*/
-PUBLIC void set_blocksize(unsigned int blocksize)
+PUBLIC void set_blocksize(unsigned int blocksize, u32_t blocks,
+       u32_t freeblocks, dev_t majordev)
 {
   struct buf *bp;
   struct inode *rip;
+  int new_nr_bufs;
 
   ASSERT(blocksize > 0);
 
@@ -502,7 +505,9 @@ PUBLIC void set_blocksize(unsigned int blocksize)
   for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
        if (rip->i_count > 0) panic("change blocksize with inode in use");
 
-  buf_pool(nr_bufs);
+  new_nr_bufs = fs_bufs_heuristic(10, blocks, freeblocks, blocksize, majordev);
+
+  buf_pool(new_nr_bufs);
   fs_block_size = blocksize;
 }
 
index eacb58d0cab09bf76242574f277b2858545bbd12..07caa5a3fb5ed6213fe0afba79c5cf5352115a13 100644 (file)
@@ -157,7 +157,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
        driver_endpoints[i].driver_e = NONE;
 
   SELF_E = getprocnr();
-  buf_pool(DEFAULT_NR_BUFS);
+
+  /* just a small number before we find out the block size at mount time */
+  buf_pool(10);
   fs_block_size = _MIN_BLOCK_SIZE;
 
   return(OK);
index e5802ab8a0413f48fe34fb89ca25f4ea98617ba4..a062e4e6bf9eb2b9157399fcfa0cc2e63e1009bf 100644 (file)
@@ -70,7 +70,7 @@ PUBLIC int fs_readsuper()
   }
 
   /* Fill in the super block. */
-  STATICINIT(superblock, sizeof(struct super_block));
+  STATICINIT(superblock, 1);
   if (!superblock)
        panic("Can't allocate memory for superblock.");
   superblock->s_dev = fs_dev;  /* read_super() needs to know which dev */
@@ -125,7 +125,10 @@ PUBLIC int fs_readsuper()
   }
 
 
-  set_blocksize(superblock->s_block_size);
+  set_blocksize(superblock->s_block_size,
+       superblock->s_blocks_count,
+       superblock->s_free_blocks_count,
+       major(fs_dev));
 
   /* Get the root inode of the mounted file system. */
   if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
index 6b44433d901bf0c27c4b92439e77f751078cc182..ee054ac64ed1942577ed6c883a4452d2b6a3944a 100644 (file)
@@ -36,10 +36,10 @@ FORWARD _PROTOTYPE( int parse_path, (ino_t dir_ino, ino_t root_ino,
  *===========================================================================*/
 PUBLIC int fs_lookup()
 {
-  cp_grant_id_t grant, grant2;
+  cp_grant_id_t grant;
   int r, r1, flags, symlinks;
   unsigned int len;
-  size_t offset = 0, path_size, cred_size;
+  size_t offset = 0, path_size;
   ino_t dir_ino, root_ino;
   struct inode *rip;
 
@@ -62,21 +62,16 @@ PUBLIC int fs_lookup()
   /* Verify this is a null-terminated path. */
   if(user_path[len - 1] != '\0') return(EINVAL);
 
-  if(flags & PATH_GET_UCRED) { /* Do we have to copy uid/gid credentials? */
-       grant2 = (cp_grant_id_t) fs_m_in.REQ_GRANT2;
-       cred_size = (size_t) fs_m_in.REQ_UCRED_SIZE;
-
-       if (cred_size > sizeof(credentials)) return(EINVAL); /* Too big. */
-       r = sys_safecopyfrom(VFS_PROC_NR, grant2, (vir_bytes) 0,
-                            (vir_bytes) &credentials, cred_size, D);
-       if (r != OK) return(r);
-
-       caller_uid = (uid_t) credentials.vu_uid;
-       caller_gid = (gid_t) credentials.vu_gid;
-  } else {
-       memset(&credentials, 0, sizeof(credentials));
-       caller_uid      = fs_m_in.REQ_UID;
-       caller_gid      = fs_m_in.REQ_GID;
+  memset(&credentials, 0, sizeof(credentials));
+  if(!(flags & PATH_GET_UCRED)) { /* Do we have to copy uid/gid credentials? */
+        caller_uid      = (uid_t) fs_m_in.REQ_UID;
+        caller_gid      = (gid_t) fs_m_in.REQ_GID;
+   } else {
+         if((r=fs_lookup_credentials(&credentials,
+               &caller_uid, &caller_gid,
+               (cp_grant_id_t) fs_m_in.REQ_GRANT2,
+               (size_t) fs_m_in.REQ_UCRED_SIZE)) != OK)
+               return r;
   }
 
   /* Lookup inode */
index eda3f635800c54a3201a327a86dce8514fdab5db..a76d0657e0654696fe9d9e3c10522cb268877485 100644 (file)
@@ -21,7 +21,8 @@ _PROTOTYPE( void flushall, (dev_t dev)                                        );
 _PROTOTYPE( struct buf *get_block, (dev_t dev, block_t block,int only_search));
 _PROTOTYPE( void invalidate, (dev_t device)                            );
 _PROTOTYPE( void put_block, (struct buf *bp, int block_type)           );
-_PROTOTYPE( void set_blocksize, (unsigned int blocksize)               );
+_PROTOTYPE( void set_blocksize, (unsigned int blocksize, u32_t blocks, 
+       u32_t freeblocks, dev_t major));
 _PROTOTYPE( void rw_scattered, (dev_t dev,
                        struct buf **bufq, int bufqsize, int rw_flag)   );
 
index 628a1478c1161e5a49bf26f434a5510c5e0aefc5..45ab48d2f90a58ff0a2d17677f14c63569867b61 100644 (file)
@@ -85,14 +85,17 @@ register struct super_block *sp; /* pointer to a superblock */
        super_block_offset = opt.block_with_super * 1024;
   }
 
-  STATICINIT(ondisk_superblock, sizeof(struct super_block));
+  STATICINIT(ondisk_superblock, 1);
 
   if (!sp || !ondisk_superblock)
        panic("can't allocate memory for super_block buffers");
 
+  printf("ext2: reading %d bytes into %d buffer\n", _MIN_BLOCK_SIZE, sizeof(*ondisk_superblock));
+
   r = block_dev_io(MFS_DEV_READ, dev, SELF_E,
                   (char*) ondisk_superblock, cvu64(super_block_offset),
                   _MIN_BLOCK_SIZE);
+                  
   if (r != _MIN_BLOCK_SIZE)
        return(EINVAL);
 
index 3730c4400f65e4ab1d7433f73e5e58caecc5a862..a937b97f346efd80ffffa5cb6e14f6c792bdcba7 100644 (file)
@@ -6,7 +6,7 @@ SRCS=   cache.c device.c link.c \
        write.c inode.c main.c path.c super.c
 
 DPADD+=        ${LIBM} ${LIBSYS}
-LDADD+= -lsys
+LDADD+= -lminixfs  -lsys
 
 MAN=
 
index 3a6898db7aba136c24e8ad8b9f0fc01f376541a4..96715f6c53e19e5e04c6eac38ce2a58986aa4554 100644 (file)
@@ -19,6 +19,7 @@
 #include <sys/param.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <minix/libminixfs.h>
 #include <math.h>
 #include "buf.h"
 #include "super.h"
@@ -567,52 +568,12 @@ PRIVATE void cache_resize(unsigned int blocksize, unsigned int bufs)
  *===========================================================================*/
 PRIVATE int bufs_heuristic(struct super_block *sp)
 {
-  struct vm_stats_info vsi;
-  int bufs;
-  u32_t btotal, bfree, bused, kbytes_used_fs,
-       kbytes_total_fs, kbcache, kb_fsmax;
-  u32_t kbytes_remain_mem;
-
-  /* but we simply need MINBUFS no matter what, and we don't
-   * want more than that if we're a memory device
-   */
-  if(major(sp->s_dev) == MEMORY_MAJOR) {
-       bufs = MINBUFS;
-       return bufs;
-  }
-
-  /* set a reasonable cache size; cache at most a certain
-   * portion of the used FS, and at most a certain %age of remaining
-   * memory
-   */
-  if((vm_info_stats(&vsi) != OK)) {
-       bufs = 1024;
-       printf("mfs: heuristic info fail: default to %d bufs\n", bufs);
-       return bufs;
-  }
-
-  kbytes_remain_mem = div64u(mul64u(vsi.vsi_free, vsi.vsi_pagesize), 1024);
+  u32_t btotal, bfree, bused;
 
-  /* check fs usage. */
   blockstats(&btotal, &bfree, &bused);
-  kbytes_used_fs = div64u(mul64u(bused, sp->s_block_size), 1024);
-  kbytes_total_fs = div64u(mul64u(btotal, sp->s_block_size), 1024);
-
-  /* heuristic for a desired cache size based on FS usage;
-   * but never bigger than half of the total filesystem
-   */
-  kb_fsmax = sqrt_approx(kbytes_used_fs)*40;
-  kb_fsmax = MIN(kb_fsmax, kbytes_total_fs/2);
-
-  /* heuristic for a maximum usage - 10% of remaining memory */
-  kbcache = MIN(kbytes_remain_mem/10, kb_fsmax);
-  bufs = kbcache * 1024 / sp->s_block_size;
-
-  /* but we simply need MINBUFS no matter what */
-  if(bufs < MINBUFS)
-       bufs = MINBUFS;
 
-  return bufs;
+  return fs_bufs_heuristic(MINBUFS, btotal, bfree,
+       sp->s_block_size, major(sp->s_dev));
 }
 
 /*===========================================================================*
index 10732770d0eeba49b9554fadea2c7eee31242736..4efffcad75df9e1b8af0aa150f26314e148aa591 100644 (file)
@@ -36,10 +36,10 @@ FORWARD _PROTOTYPE( int parse_path, (ino_t dir_ino, ino_t root_ino,
  *===========================================================================*/
 PUBLIC int fs_lookup()
 {
-  cp_grant_id_t grant, grant2;
+  cp_grant_id_t grant;
   int r, r1, flags, symlinks;
   unsigned int len;
-  size_t offset = 0, path_size, cred_size;
+  size_t offset = 0, path_size;
   ino_t dir_ino, root_ino;
   struct inode *rip;
 
@@ -62,21 +62,16 @@ PUBLIC int fs_lookup()
   /* Verify this is a null-terminated path. */
   if(user_path[len - 1] != '\0') return(EINVAL);
 
-  if(flags & PATH_GET_UCRED) { /* Do we have to copy uid/gid credentials? */
-       grant2 = (cp_grant_id_t) fs_m_in.REQ_GRANT2;
-       cred_size = (size_t) fs_m_in.REQ_UCRED_SIZE;
-
-       if (cred_size > sizeof(credentials)) return(EINVAL); /* Too big. */
-       r = sys_safecopyfrom(VFS_PROC_NR, grant2, (vir_bytes) 0,
-                            (vir_bytes) &credentials, cred_size, D);
-       if (r != OK) return(r);
-
-       caller_uid = credentials.vu_uid;
-       caller_gid = credentials.vu_gid;
+  memset(&credentials, 0, sizeof(credentials));
+  if(!(flags & PATH_GET_UCRED)) { /* Do we have to copy uid/gid credentials? */
+        caller_uid      = (uid_t) fs_m_in.REQ_UID;
+        caller_gid      = (gid_t) fs_m_in.REQ_GID;
   } else {
-       memset(&credentials, 0, sizeof(credentials));
-       caller_uid      = (uid_t) fs_m_in.REQ_UID;
-       caller_gid      = (gid_t) fs_m_in.REQ_GID;
+         if((r=fs_lookup_credentials(&credentials,
+               &caller_uid, &caller_gid,
+               (cp_grant_id_t) fs_m_in.REQ_GRANT2,
+               (size_t) fs_m_in.REQ_UCRED_SIZE)) != OK)
+               return r;
   }
 
   /* Lookup inode */