/*
* Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by the
* Google Summer of Code program and the Ulla Tuominen Foundation.
* The Google SoC project was mentored by Bill Studenmund.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* really statvfs90 */
struct puffs_statvfs {
unsigned long f_flag; /* copy of mount exported flags */
unsigned long f_bsize; /* file system block size */
unsigned long f_frsize; /* fundamental file system block size */
unsigned long f_iosize; /* optimal file system block size */
/* The following are in units of f_frsize */
fsblkcnt_t f_blocks; /* number of blocks in file system, */
fsblkcnt_t f_bfree; /* free blocks avail in file system */
fsblkcnt_t f_bavail; /* free blocks avail to non-root */
fsblkcnt_t f_bresvd; /* blocks reserved for root */
fsfilcnt_t f_files; /* total file nodes in file system */
fsfilcnt_t f_ffree; /* free file nodes in file system */
fsfilcnt_t f_favail; /* free file nodes avail to non-root */
fsfilcnt_t f_fresvd; /* file nodes reserved for root */
uint64_t f_syncreads; /* count of sync reads since mount */
uint64_t f_syncwrites; /* count of sync writes since mount */
uint64_t f_asyncreads; /* count of async reads since mount */
uint64_t f_asyncwrites; /* count of async writes since mount */
fsid_t f_fsidx; /* NetBSD compatible fsid */
unsigned long f_fsid; /* Posix compatible fsid */
unsigned long f_namemax; /* maximum filename length */
uid_t f_owner; /* user that mounted the file system */
uint32_t f_spare[4]; /* spare space */
char f_fstypename[_VFS_NAMELEN]; /* fs type name */
char f_mntonname[_VFS_MNAMELEN]; /* directory on which mounted */
char f_mntfromname[_VFS_MNAMELEN]; /* mounted file system */
};
/*
* Just a weak typedef for code clarity. Additionally, we have a
* more appropriate vanity type for puffs:
* <uep> it should be croissant, not cookie.
*/
typedef void *puffs_cookie_t;
typedef puffs_cookie_t puffs_croissant_t;
struct puffs_kargs {
unsigned int pa_vers;
int pa_fd;
uint16_t preq_opclass;
uint16_t preq_optype;
int preq_rv;
uint32_t preq_setbacks;
/* Who is making the call? Eventually host id is also needed. */
pid_t preq_pid;
lwpid_t preq_lid;
/*
* the following helper pads the struct size to md alignment
* multiple (should size_t not cut it). it makes sure that
* whatever comes after this struct is aligned
*/
size_t preq_buflen;
uint8_t preq_buf[0] __aligned(ALIGNBYTES+1);
};
#define PUFFS_SETBACK_INACT_N1 0x01 /* set VOP_INACTIVE for node 1 */
#define PUFFS_SETBACK_INACT_N2 0x02 /* set VOP_INACTIVE for node 2 */
#define PUFFS_SETBACK_NOREF_N1 0x04 /* set pn PN_NOREFS for node 1 */
#define PUFFS_SETBACK_NOREF_N2 0x08 /* set pn PN_NOREFS for node 2 */
#define PUFFS_SETBACK_MASK 0x0f
/*
* Flush operation. This can be used to invalidate:
* 1) name cache for one node
* 2) name cache for all children
* 3) name cache for the entire mount
* 4) page cache for a set of ranges in one node
* 5) page cache for one entire node
*
* It can be used to flush:
* 1) page cache for a set of ranges in one node
* 2) page cache for one entire node
*/
/*
* Credentials for an operation. Can be either struct uucred for
* ops called from a credential context or NOCRED/FSCRED for ops
* called from within the kernel. It is up to the implementation
* if it makes a difference between these two and the super-user.
*/
struct puffs_kcred {
struct uucred pkcr_uuc;
uint8_t pkcr_type;
uint8_t pkcr_internal;
};
#define PUFFCRED_TYPE_UUC 1
#define PUFFCRED_TYPE_INTERNAL 2
#define PUFFCRED_CRED_NOCRED 1
#define PUFFCRED_CRED_FSCRED 2
/*
* 2*MAXPHYS is the max size the system will attempt to copy,
* else treated as garbage
*/
#define PUFFS_MSG_MAXSIZE 2*MAXPHYS
#define PUFFS_MSGSTRUCT_MAX 4096 /* approximate */
#define PUFFS_EXTNAMELEN KERNEL_NAME_MAX /* currently same as EXTATTR_MAXNAMELEN */
char pkcn_name[MAXPATHLEN]; /* nulterminated path component */
size_t pkcn_namelen; /* current component length */
size_t pkcn_consume; /* IN: extra chars server ate */
};
/*
* Next come the individual requests. They are all subclassed from
* puffs_req and contain request-specific fields in addition. Note
* that there are some requests which have to handle arbitrary-length
* buffers.
*
* The division is the following: puffs_req is to be touched only
* by generic routines while the other stuff is supposed to be
* modified only by specific routines.
*/
/*
* aux structures for vfs operations.
*/
struct puffs_vfsmsg_unmount {
struct puffs_req pvfsr_pr;
struct puffs_kcn pvnr_cn; /* OUT */
struct puffs_kcred pvnr_cn_cred; /* OUT */
puffs_cookie_t pvnr_newnode; /* IN */
enum vtype pvnr_vtype; /* IN */
voff_t pvnr_size; /* IN */
dev_t pvnr_rdev; /* IN */
/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
struct vattr pvnr_va; /* IN */
struct timespec pvnr_va_ttl; /* IN */
struct timespec pvnr_cn_ttl; /* IN */
};
struct puffs_kcn pvnr_cn; /* OUT */
struct puffs_kcred pvnr_cn_cred; /* OUT */
struct vattr pvnr_va; /* OUT */
puffs_cookie_t pvnr_newnode; /* IN */
/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
struct timespec pvnr_va_ttl; /* IN */
struct timespec pvnr_cn_ttl; /* IN */
};
struct puffs_kcn pvnr_cn; /* OUT */
struct puffs_kcred pvnr_cn_cred; /* OUT */
struct vattr pvnr_va; /* OUT */
puffs_cookie_t pvnr_newnode; /* IN */
/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
struct timespec pvnr_va_ttl; /* IN */
struct timespec pvnr_cn_ttl; /* IN */
};
struct puffs_kcn pvnr_cn; /* OUT */
struct puffs_kcred pvnr_cn_cred; /* OUT */
struct vattr pvnr_va; /* OUT */
puffs_cookie_t pvnr_newnode; /* IN */
/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
struct timespec pvnr_va_ttl; /* IN */
struct timespec pvnr_cn_ttl; /* IN */
};
struct puffs_kcn pvnr_cn; /* OUT */
struct puffs_kcred pvnr_cn_cred; /* OUT */
struct vattr pvnr_va; /* OUT */
puffs_cookie_t pvnr_newnode; /* IN */
char pvnr_link[MAXPATHLEN]; /* OUT */
/* Used only if PUFFS_KFLAG_CACHE_USE_TTL */
struct timespec pvnr_va_ttl; /* IN */
struct timespec pvnr_cn_ttl; /* IN */
};