xmem_vfsops.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/pathname.h>
#include <vm/seg_kmem.h>
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
/*
* xmemfs vfs operations.
*/
static int xmemfsinit(int, char *);
/*
* Loadable module wrapper
*/
"xmemfs",
0,
};
/*
* Module linkage information
*/
};
static struct modlinkage modlinkage = {
};
int
_init()
{
return (mod_install(&modlinkage));
}
int
_fini()
{
return (mod_remove(&modlinkage));
}
int
{
}
static int xmemfsfstype;
static major_t xmemfs_major;
static minor_t xmemfs_minor;
static kmutex_t xmemfs_minor_lock;
/*
* initialize global xmemfs locks and such
* called when loading xmemfs module
*/
static int
{
static const fs_operation_def_t xmem_vfsops[] = {
};
int error;
extern void xmemfs_hash_init();
if (error != 0) {
return (error);
}
if (error != 0) {
(void) vfs_freevfsops_by_type(fstype);
return (error);
}
ASSERT(xmemfsfstype != 0);
xmemfs_major = 0;
}
return (0);
}
/*
* xpg is an array of page_t * if xm_ppb > 1.
* xpg is a page_t * if xm_ppb == 1
*/
void
{
}
void *
{
return (NULL);
}
void
{
}
void
{
if (newsz) {
xm->xm_xpgarray =
}
}
void
{
}
static int
{
int error;
struct xmemfs_args xargs;
int got_attrs, num_pagesizes;
return (error);
return (ENOTDIR);
/*
* Force non-executable files by setting the "noexec" option
* which will be interpreted by the VFS layer.
*/
return (EBUSY);
}
/*
* Get arguments
*/
if (datalen != 0) {
return (EINVAL);
else {
return (EFAULT);
}
} else {
}
/* Make sure xa_bsize is a pure power of two */
}
while (--num_pagesizes >= 0)
break;
if (num_pagesizes < 0) {
"xmemfs: blocksize %lld not a natural pagesize",
}
return (error);
/* need to allocate more to ensure alignment if largepage */
/* Set block size & max memory allowed for the file system */
/*
* 5 * lotsfree satisfies XMEMMINFREE for 4 GB of memory and above.
*/
/* sanity check this against freemem */
return (EFBIG);
}
} else {
/*
* fssize is mandatory - should not be here but if
* fssize == 0 is allowed, grab all of free memory
* minus xmemfs_minfree.
*/
if (freemem < xmemfs_minfree)
else
}
/*
* Allocate a map to provide an address for each page in
* (xargs.xa_bsize * 4) and free all of them.
*/
/*
* do not SLEEP waiting for memory resources after vmem_alloc
*/
if (!xm->xm_mapaddr) {
return (ENOMEM);
}
/* grab all memory now */
xm->xm_vmmapsize);
return (ENOMEM);
}
while (blocks_left) {
int i;
/*
* optimise for ppb == 1 - let xp_ppa point directly
* to page.
*/
if (!ppa) {
"could only reserve %d blocks "
break;
}
}
}
"could only reserve %d blocks "
break;
}
}
PP_CLRFREE(pp);
PP_CLRAGED(pp);
else
}
blocks_left--;
}
/* No pages at all */
xm->xm_vmmapsize);
return (ENOMEM);
}
}
/*
* find an available minor device number for this mount
*/
do {
/*
* Set but don't bother entering the mutex
* (xmount not on mount list yet)
*/
/*
* allocate and initialize root xmemnode structure
*/
/*
* Get the mode, uid, and gid from the underlying mount point.
*/
/*
* If the getattr succeeded, use its results. Otherwise allow
* the previously set hardwired defaults to prevail.
*/
if (got_attrs == 0) {
}
/*
* initialize linked list of xmemnodes so that the back pointer of
* the root xmemnode always points to the last one on the list
* and the forward pointer of the last node is null.
*/
return (0);
}
static int
{
return (EPERM);
/*
* forced unmount is not supported by this file system
* and thus, ENOTSUP, is being returned.
*/
return (ENOTSUP);
/*
* Don't close down the xmemfs if there are open files.
* There should be only one file referenced (the rootnode)
* and only one reference to the vnode for that file.
*/
return (EBUSY);
}
return (EBUSY);
}
}
/*
* We can drop the mutex now because no one can find this mount
*/
/*
* Free all kmemalloc'd and non-anonalloc'd memory associated with
* this filesystem. To do this, we go through the file list twice,
* once to remove all the directory entries, and then to remove
* all the files. We do this because there is useful code in
* xmemnode_free which assumes that the directory entry has been
* removed before the file.
*/
/*
* Remove all directory entries
*/
}
/*
* We re-acquire the lock to prevent others who have a HOLD on
* a xmemnode via its pages from blowing it away
* (in xmem_inactive) while we're trying to get to it here. Once
* we have a HOLD on it we know it'll stick around.
*/
/*
* Remove all the files (except the rootnode) backwards.
*/
/*
* Blow the xmemnode away by HOLDing it and RELE'ing it.
* The RELE calls inactive and blows it away because there
* we have the last HOLD.
*/
/*
* It's still there after the RELE. Someone else like pageout
* has a hold on it so wait a bit and then try again - we know
* they'll give it up soon.
*/
}
}
/*LINTED*/
continue;
}
/* free each page */
/*LINTED*/
}
}
}
return (0);
}
/*
* return root xmemnode for given vnode
*/
static int
{
return (0);
}
static int
{
long blocks;
/*
* Find the amount of available physical and memory swap
*/
else
/*
* Total number of blocks is what's available plus what's been used
*/
/*
* return a somewhat arbitrary number of inodes available
*/
return (0);
}
static int
{
/*
* If the gen numbers don't match we know the
* file won't be found since only one xmemnode
* can have this number at a time.
*/
return (0);
}
}
return (0);
}
}
return (0);
}