ctfs_root.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 <sys/contract.h>
#include <sys/contract_impl.h>
#include <sys/ctfs_impl.h>
/*
* ctfs, the contract filesystem.
*
* Exposes the constract subsystem to userland. The structure of the
* filesytem is a public interface, but the behavior of the files is
* private and unstable. Contract consumers are expected to use
* libcontract(3lib) to operate on ctfs file descriptors.
*
* We're trying something a little different here. Rather than make
* each vnode op itself call into a vector of file type operations, we
* actually use different vnode types (gasp!), the implementations of
* which may call into routines providing common functionality. This
* design should hopefully make it easier to factor and maintain the
* code. For the most part, there is a separate file for each vnode
* nodes, which are very similar, and the three event endpoint types.
*
* This file contains common routines used by some or all of the vnode
* types, the filesystem's module linkage and VFS operations, and the
* implementation of the root vnode.
*/
/*
* Ops vectors for all the vnode types; they have to be defined
* somewhere. See gfs_make_opsvec for thoughts on how this could be
* done differently.
*/
static const fs_operation_def_t ctfs_vfstops[];
static gfs_opsvec_t ctfs_opsvec[];
static int ctfs_init(int, char *);
/*
* File system module linkage
*/
static mntopts_t ctfs_mntopts = {
0,
};
"ctfs",
};
};
static struct modlinkage modlinkage = {
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
{
}
int
_fini(void)
{
/*
* As unloading filesystem modules isn't completely safe, we
* don't allow it.
*/
return (EBUSY);
}
static int ctfs_fstype;
static major_t ctfs_major;
static minor_t ctfs_minor = 0;
/*
* The ops vector vector.
*/
static const fs_operation_def_t ctfs_tops_root[];
extern const fs_operation_def_t ctfs_tops_tmpl[];
extern const fs_operation_def_t ctfs_tops_ctl[];
extern const fs_operation_def_t ctfs_tops_adir[];
extern const fs_operation_def_t ctfs_tops_cdir[];
extern const fs_operation_def_t ctfs_tops_tdir[];
extern const fs_operation_def_t ctfs_tops_latest[];
extern const fs_operation_def_t ctfs_tops_stat[];
extern const fs_operation_def_t ctfs_tops_sym[];
extern const fs_operation_def_t ctfs_tops_event[];
extern const fs_operation_def_t ctfs_tops_bundle[];
static gfs_opsvec_t ctfs_opsvec[] = {
{ NULL }
};
/*
* ctfs_init - the vfsdef_t init entry point
*
* Sets the VFS ops, builds all the vnode ops, and allocates a device
* number.
*/
/* ARGSUSED */
static int
{
int error;
return (error);
}
(void) vfs_freevfsops(vfsops);
return (error);
}
ctfs_major = 0;
}
return (0);
}
/*
* ctfs_mount - the VFS_MOUNT entry point
*/
static int
{
int i;
return (EPERM);
return (ENOTDIR);
return (EBUSY);
/*
*/
do
while (vfs_devismounted(dev));
/*
* Dynamically create gfs_dirent_t array for the root directory.
*/
for (i = 0; i < ct_ntypes; i++) {
}
/*
* Create root vnode
*/
return (0);
}
/*
* ctfs_unmount - the VFS_UNMOUNT entry point
*/
static int
{
return (EPERM);
/*
* Supporting forced unmounts would be nice to do at some
* point.
*/
return (ENOTSUP);
/*
* We should never have a reference count less than 2: one for
* the caller, one for the root vnode.
*/
/*
* If we have any active vnodes, they will (transitively) have
* holds on the root vnode.
*/
return (EBUSY);
/*
* Release the last hold on the root vnode. It will, in turn,
* release its hold on us.
*/
/*
* Disappear.
*/
return (0);
}
/*
* ctfs_root - the VFS_ROOT entry point
*/
static int
{
return (0);
}
/*
* ctfs_statvfs - the VFS_STATVFS entry point
*/
static int
{
int total, i;
sizeof (sp->f_basetype));
return (0);
}
static const fs_operation_def_t ctfs_vfstops[] = {
{ VFSNAME_MOUNT, ctfs_mount },
{ VFSNAME_UNMOUNT, ctfs_unmount },
{ VFSNAME_ROOT, ctfs_root },
{ VFSNAME_STATVFS, ctfs_statvfs },
};
/*
* ctfs_common_getattr
*
* Implements functionality common to all ctfs VOP_GETATTR entry
* points. It assumes vap->va_size is set.
*/
void
{
}
/*
* ctfs_open - common VOP_OPEN entry point
*
* Used by all ctfs directories; just verifies we are using large-file
* aware interfaces and we aren't trying to open the directories
* writable.
*/
/* ARGSUSED */
int
{
return (EINVAL);
return (0);
}
/*
* ctfs_close - common VOP_CLOSE entry point
*
* For all ctfs vnode types which have no close-time clean-up to do.
*/
/* ARGSUSED */
int
{
return (0);
}
/*
* ctfs_access_dir - common VOP_ACCESS entry point for directories
*/
/* ARGSUSED */
int
{
return (EACCES);
return (0);
}
/*
* ctfs_access_dir - common VOP_ACCESS entry point for read-only files
*/
/* ARGSUSED */
int
{
return (EACCES);
return (0);
}
/*
* ctfs_access_dir - common VOP_ACCESS entry point for read-write files
*/
/* ARGSUSED */
int
{
return (EACCES);
return (0);
}
/*
* ctfs_root_getattr - VOP_GETATTR entry point
*/
/* ARGSUSED */
static int
{
return (0);
}
/* ARGSUSED */
static ino64_t
{
return (CTFS_INO_TYPE_DIR(index));
}
static const fs_operation_def_t ctfs_tops_root[] = {
{ VOPNAME_OPEN, ctfs_open },
{ VOPNAME_CLOSE, ctfs_close },
{ VOPNAME_IOCTL, fs_inval },
{ VOPNAME_LOOKUP, gfs_vop_lookup },
{ VOPNAME_SEEK, fs_seek },
};