add -lminixfs with fs support routines

. 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
This commit is contained in:
Ben Gras
2011-09-08 16:49:54 +00:00
parent ce1a2793f9
commit 4857d5d554
19 changed files with 202 additions and 91 deletions

View 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>

View 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;
}

View 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);

View 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) {

View 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 */

View 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) );

View 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);

View 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=

View 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;
u32_t btotal, bfree, bused;
/* 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);
/* 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));
}
/*===========================================================================*

View 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 */