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 \
--- /dev/null
+/* 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 */
+
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)
/* 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
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
--- /dev/null
+# Makefile for libminixfs
+.include <bsd.own.mk>
+
+LIB= minixfs
+
+SRCS= fetch_credentials.c cache.c
+
+.include <bsd.lib.mk>
--- /dev/null
+
+#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;
+}
+
--- /dev/null
+
+#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;
+}
+
--- /dev/null
+#define _SYSTEM
+
+#include <lib.h> /* common to all libraries */
+#include <minix/com.h> /* need task numbers + message types */
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>
#include "fs.h"
#include <minix/u64.h>
+#include <minix/libminixfs.h>
#include <stdlib.h>
#include <assert.h>
#include "buf.h"
/*===========================================================================*
* 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);
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;
}
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);
}
/* 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 */
}
- 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) {
*===========================================================================*/
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;
/* 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 */
_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) );
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);
write.c inode.c main.c path.c super.c
DPADD+= ${LIBM} ${LIBSYS}
-LDADD+= -lsys
+LDADD+= -lminixfs -lsys
MAN=
#include <sys/param.h>
#include <stdlib.h>
#include <assert.h>
+#include <minix/libminixfs.h>
#include <math.h>
#include "buf.h"
#include "super.h"
*===========================================================================*/
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));
}
/*===========================================================================*
*===========================================================================*/
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;
/* 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 */