[BACK]Return to dmapi_private.h CVS log [TXT][DIR] Up to [Development] / dmapi

File: [Development] / dmapi / dmapi_private.h (download)

Revision 1.9, Mon Mar 17 06:02:57 2003 UTC (14 years, 7 months ago) by nathans
Branch: MAIN
Changes since 1.8: +3 -1 lines

Separate the quota source into its own subdirectory ala dmapi.
Push a bunch of quota- and dmapi-specific code down into these
subdirs which previously was compiled into the core XFS code,
and don't descend into these subdirs if options config'd off.
Separate the quota source into its own subdirectory ala dmapi.
Push a bunch of quota- and dmapi-specific code down into these
subdirs which previously was compiled into the core XFS code,
and don't descend into these subdirs if options config'd off.

/*
 * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.	 Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 *
 * http://www.sgi.com
 *
 * For further information regarding this notice, see:
 *
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
 */
#ifndef _DMAPI_PRIVATE_H
#define _DMAPI_PRIVATE_H

#include "xfs.h"
#include "dmapi.h"
#include "dmapi_kern.h"

#ifdef CONFIG_PROC_FS
#define DMAPI_PROCFS		"fs/xfs_dmapi_v2" /* DMAPI device in /proc. */
#define DMAPI_DBG_PROCFS	"fs/xfs_dmapi_d" /* DMAPI debugging dir */
#endif

extern struct kmem_cache_s	*dm_fsreg_cachep;
extern struct kmem_cache_s	*dm_tokdata_cachep;
extern struct kmem_cache_s	*dm_session_cachep;



typedef struct dm_tokdata {
	struct dm_tokdata *td_next;
	struct dm_tokevent *td_tevp;	/* pointer to owning tevp */
	int		td_app_ref;	/* # app threads currently active */
	dm_right_t	td_orig_right;	/* original right held when created */
	dm_right_t	td_right;	/* current right held for this handle */
	short		td_flags;
	short		td_type;	/* object type */
	int		td_vcount;	/* # of current application VN_HOLDs */
	vnode_t		*td_vp;		/* vnode pointer */
	xfs_handle_t	td_handle;	/* handle for vp or vfsp */
} dm_tokdata_t;

/* values for td_type */

#define DM_TDT_NONE	0x00		/* td_handle is empty */
#define DM_TDT_VFS	0x01		/* td_handle points to a vfs */
#define DM_TDT_REG	0x02		/* td_handle points to a file */
#define DM_TDT_DIR	0x04		/* td_handle points to a directory */
#define DM_TDT_LNK	0x08		/* td_handle points to a symlink */
#define DM_TDT_OTH	0x10		/* some other object eg. pipe, socket */

#define DM_TDT_VNO	(DM_TDT_REG|DM_TDT_DIR|DM_TDT_LNK|DM_TDT_OTH)
#define DM_TDT_ANY	(DM_TDT_VFS|DM_TDT_REG|DM_TDT_DIR|DM_TDT_LNK|DM_TDT_OTH)

/* values for td_flags */

#define DM_TDF_ORIG	0x0001		/* part of the original event */
#define DM_TDF_EVTREF	0x0002		/* event thread holds vnode reference */
#define DM_TDF_STHREAD	0x0004		/* only one app can use this handle */
#define DM_TDF_RIGHT	0x0008		/* vcount bumped for dm_request_right */
#define DM_TDF_HOLD	0x0010		/* vcount bumped for dm_obj_ref_hold */


/* Because some events contain __u64 fields, we force te_msg and te_event
   to always be 8-byte aligned.	 In order to send more than one message in
   a single dm_get_events() call, we also ensure that each message is an
   8-byte multiple.
*/

typedef struct dm_tokevent {
	struct dm_tokevent  *te_next;
	struct dm_tokevent  *te_hashnext; /* hash chain */
	lock_t		te_lock;	/* lock for all fields but te_*next.
					 * te_next and te_hashnext are
					 * protected by the session lock.
					 */
	short		te_flags;
	short		te_allocsize;	/* alloc'ed size of this structure */
	sv_t		te_evt_queue;	/* queue waiting for dm_respond_event */
	sv_t		te_app_queue;	/* queue waiting for handle access */
	int		te_evt_ref;	/* number of event procs using token */
	int		te_app_ref;	/* number of app procs using token */
	int		te_app_slp;	/* number of app procs sleeping */
	int		te_reply;	/* return errno for sync messages */
	dm_tokdata_t	*te_tdp;	/* list of handle/right pairs */
	union {
		__u64		align;	/* force alignment of te_msg */
		dm_eventmsg_t	te_msg;		/* user visible part */
	} te_u;
	__u64		te_event;	/* start of dm_xxx_event_t message */
} dm_tokevent_t;

#define te_msg	te_u.te_msg

/* values for te_flags */

#define DM_TEF_LOCKED	0x0001		/* event "locked" by dm_get_events() */
#define DM_TEF_INTERMED 0x0002		/* a dm_pending reply was received */
#define DM_TEF_FINAL	0x0004		/* dm_respond_event has been received */
#ifdef __sgi
#define DM_TEF_HASHED	0x0010		/* event is on hash chain  */
#endif


#ifdef __sgi
#ifdef DEBUG
#define DM_SHASH_DEBUG
#endif

typedef struct dm_sesshash {
	dm_tokevent_t	*h_next;	/* ptr to chain of tokevents */
#ifdef DM_SHASH_DEBUG
	int		maxlength;
	int		curlength;
	int		num_adds;
	int		num_dels;
	int		dup_hits;
#endif
} dm_sesshash_t;
#endif


typedef struct dm_eventq {
	dm_tokevent_t	*eq_head;
	dm_tokevent_t	*eq_tail;
	int		eq_count;	/* size of queue */
} dm_eventq_t;


typedef struct dm_session {
	struct dm_session	*sn_next;	/* sessions linkage */
	dm_sessid_t	sn_sessid;	/* user-visible session number */
	u_int		sn_flags;
	lock_t		sn_qlock;	/* lock for newq/delq related fields */
	sv_t		sn_readerq;	/* waiting for message on sn_newq */
	sv_t		sn_writerq;	/* waiting for room on sn_newq */
	u_int		sn_readercnt;	/* count of waiting readers */
	u_int		sn_writercnt;	/* count of waiting readers */
	dm_eventq_t	sn_newq;	/* undelivered event queue */
	dm_eventq_t	sn_delq;	/* delivered event queue */
	dm_eventq_t	sn_evt_writerq; /* events of thrds in sn_writerq */
#ifdef __sgi
	dm_sesshash_t	*sn_sesshash;	/* buckets for tokevent hash chains */
#ifdef DM_SHASH_DEBUG
	int		sn_buckets_in_use;
	int		sn_max_buckets_in_use;
#endif
#endif
	char		sn_info[DM_SESSION_INFO_LEN];	/* user-supplied info */
} dm_session_t;

/* values for sn_flags */

#define DM_SN_WANTMOUNT 0x0001		/* session wants to get mount events */


typedef enum {
	DM_STATE_MOUNTING,
	DM_STATE_MOUNTED,
	DM_STATE_UNMOUNTING,
	DM_STATE_UNMOUNTED
} dm_fsstate_t;


typedef struct dm_fsreg {
	struct dm_fsreg *fr_next;
	vfs_t		*fr_vfsp;	/* filesystem pointer */
	dm_tokevent_t	*fr_tevp;
	fsid_t		fr_fsid;	/* filesystem ID */
	void		*fr_msg;	/* dm_mount_event_t for filesystem */
	int		fr_msgsize;	/* size of dm_mount_event_t */
	dm_fsstate_t	fr_state;
	sv_t		fr_dispq;
	int		fr_dispcnt;
	dm_eventq_t	fr_evt_dispq;	/* events of thrds in fr_dispq */
	sv_t		fr_queue;	/* queue for hdlcnt/vfscnt/unmount */
	lock_t		fr_lock;
	int		fr_hdlcnt;	/* threads blocked during unmount */
	int		fr_vfscnt;	/* threads in VFS_VGET or VFS_ROOT */
	int		fr_unmount;	/* if non-zero, umount is sleeping */
	dm_attrname_t	fr_rattr;	/* dm_set_return_on_destroy attribute */
	dm_session_t	*fr_sessp [DM_EVENT_MAX];
} dm_fsreg_t;




/* events valid in dm_set_disp() when called with a filesystem handle. */

#define DM_VALID_DISP_EVENTS		( \
	(1 << DM_EVENT_PREUNMOUNT)	| \
	(1 << DM_EVENT_UNMOUNT)		| \
	(1 << DM_EVENT_NOSPACE)		| \
	(1 << DM_EVENT_DEBUT)		| \
	(1 << DM_EVENT_CREATE)		| \
	(1 << DM_EVENT_POSTCREATE)	| \
	(1 << DM_EVENT_REMOVE)		| \
	(1 << DM_EVENT_POSTREMOVE)	| \
	(1 << DM_EVENT_RENAME)		| \
	(1 << DM_EVENT_POSTRENAME)	| \
	(1 << DM_EVENT_LINK)		| \
	(1 << DM_EVENT_POSTLINK)	| \
	(1 << DM_EVENT_SYMLINK)		| \
	(1 << DM_EVENT_POSTSYMLINK)	| \
	(1 << DM_EVENT_READ)		| \
	(1 << DM_EVENT_WRITE)		| \
	(1 << DM_EVENT_TRUNCATE)	| \
	(1 << DM_EVENT_ATTRIBUTE)	| \
	(1 << DM_EVENT_DESTROY)		)


/* isolate the read/write/trunc events of a dm_tokevent_t */

#define DM_EVENT_RDWRTRUNC(tevp)			(  \
	((tevp)->te_msg.ev_type == DM_EVENT_READ)	|| \
	((tevp)->te_msg.ev_type == DM_EVENT_WRITE)	|| \
	((tevp)->te_msg.ev_type == DM_EVENT_TRUNCATE)	)


/*
 *  Global handle hack isolation.
 */

#define DM_GLOBALHAN(hanp, hlen)	(((hanp) == DM_GLOBAL_HANP) && \
					 ((hlen) == DM_GLOBAL_HLEN))


#define DM_MAX_MSG_DATA		3960



/* Supported filesystem function vector functions. */


typedef struct {
	int				code_level;
	char				fsys_name[16];
	dm_fsys_clear_inherit_t		clear_inherit;
	dm_fsys_create_by_handle_t	create_by_handle;
	dm_fsys_downgrade_right_t	downgrade_right;
	dm_fsys_get_allocinfo_rvp_t	get_allocinfo_rvp;
	dm_fsys_get_bulkall_rvp_t	get_bulkall_rvp;
	dm_fsys_get_bulkattr_rvp_t	get_bulkattr_rvp;
	dm_fsys_get_config_t		get_config;
	dm_fsys_get_config_events_t	get_config_events;
	dm_fsys_get_destroy_dmattr_t	get_destroy_dmattr;
	dm_fsys_get_dioinfo_t		get_dioinfo;
	dm_fsys_get_dirattrs_rvp_t	get_dirattrs_rvp;
	dm_fsys_get_dmattr_t		get_dmattr;
	dm_fsys_get_eventlist_t		get_eventlist;
	dm_fsys_get_fileattr_t		get_fileattr;
	dm_fsys_get_region_t		get_region;
	dm_fsys_getall_dmattr_t		getall_dmattr;
	dm_fsys_getall_inherit_t	getall_inherit;
	dm_fsys_init_attrloc_t		init_attrloc;
	dm_fsys_mkdir_by_handle_t	mkdir_by_handle;
	dm_fsys_probe_hole_t		probe_hole;
	dm_fsys_punch_hole_t		punch_hole;
	dm_fsys_read_invis_rvp_t	read_invis_rvp;
	dm_fsys_release_right_t		release_right;
	dm_fsys_remove_dmattr_t		remove_dmattr;
	dm_fsys_request_right_t		request_right;
	dm_fsys_set_dmattr_t		set_dmattr;
	dm_fsys_set_eventlist_t		set_eventlist;
	dm_fsys_set_fileattr_t		set_fileattr;
	dm_fsys_set_inherit_t		set_inherit;
	dm_fsys_set_region_t		set_region;
	dm_fsys_symlink_by_handle_t	symlink_by_handle;
	dm_fsys_sync_by_handle_t	sync_by_handle;
	dm_fsys_upgrade_right_t		upgrade_right;
	dm_fsys_write_invis_rvp_t	write_invis_rvp;
	dm_fsys_obj_ref_hold_t		obj_ref_hold;
} dm_fsys_vector_t;


extern	dm_session_t	*dm_sessions;		/* head of session list */
extern	dm_fsreg_t	*dm_registers;
extern	lock_t		dm_reg_lock;		/* lock for registration list */

/*
 *  Kernel only prototypes.
 */

int		dm_find_session_and_lock(
			dm_sessid_t	sid,
			dm_session_t	**sessionpp,
			unsigned long	*lcp);

int		dm_find_msg_and_lock(
			dm_sessid_t	sid,
			dm_token_t	token,
			dm_tokevent_t	**tevpp,
			unsigned long	*lcp);

dm_tokevent_t * dm_evt_create_tevp(
			dm_eventtype_t	event,
			int		variable_size,
			void		**msgpp);

int		dm_app_get_tdp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			short		types,
			dm_right_t	right,
			dm_tokdata_t	**tdpp);

int		dm_get_config_tdp(
			void		*hanp,
			size_t		hlen,
			dm_tokdata_t	**tdpp);

void		dm_app_put_tdp(
			dm_tokdata_t	*tdp);

void		dm_put_tevp(
			dm_tokevent_t	*tevp,
			dm_tokdata_t	*tdp);

void		dm_evt_rele_tevp(
			dm_tokevent_t	*tevp,
			int		droprights);

int		dm_enqueue_normal_event(
			vfs_t		*vfsp,
			dm_tokevent_t	*tevp,
			int		flags);

int		dm_enqueue_mount_event(
			vfs_t		*vfsp,
			dm_tokevent_t	*tevp);

int		dm_enqueue_sendmsg_event(
			dm_sessid_t	targetsid,
			dm_tokevent_t	*tevp,
			int		synch);

int		dm_enqueue_user_event(
			dm_sessid_t	sid,
			dm_tokevent_t	*tevp,
			dm_token_t	*tokenp);

int		dm_obj_ref_query_rvp(
			dm_sessid_t	sid,
			dm_token_t	token,
			void		*hanp,
			size_t		hlen,
			int		*rvp);

int		dm_read_invis_rvp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			dm_off_t	off,
			dm_size_t	len,
			void		*bufp,
			int		*rvp);

int		dm_write_invis_rvp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			int		flags,
			dm_off_t	off,
			dm_size_t	len,
			void		*bufp,
			int		*rvp);

int		dm_get_bulkattr_rvp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			u_int		mask,
			dm_attrloc_t	*locp,
			size_t		buflen,
			void		*bufp,
			size_t		*rlenp,
			int		*rvp);

int		dm_get_bulkall_rvp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			u_int		mask,
			dm_attrname_t	*attrnamep,
			dm_attrloc_t	*locp,
			size_t		buflen,
			void		*bufp,
			size_t		*rlenp,
			int		*rvp);

int		dm_get_dirattrs_rvp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			u_int		mask,
			dm_attrloc_t	*locp,
			size_t		buflen,
			void		*bufp,
			size_t		*rlenp,
			int		*rvp);

int		dm_get_allocinfo_rvp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			dm_off_t	*offp,
			u_int		nelem,
			dm_extent_t	*extentp,
			u_int		*nelemp,
			int		*rvp);

int		dm_waitfor_destroy_attrname(
			vfs_t		*vfsp,
			dm_attrname_t	*attrnamep);

void		dm_clear_fsreg(
			dm_session_t	*s);

int		dm_add_fsys_entry(
			vfs_t		*vfsp,
			dm_tokevent_t	*tevp);

void		dm_change_fsys_entry(
			vfs_t		*vfsp,
			dm_fsstate_t	newstate);

void		dm_remove_fsys_entry(
			vfs_t		*vfsp);

dm_fsys_vector_t *dm_fsys_vector(
			vnode_t		*vp);

void		dm_fsys_vector_free(void);

int		dm_waitfor_disp_session(
			vfs_t		*vfsp,
			dm_tokevent_t	*tevp,
			dm_session_t	**sessionpp,
			unsigned long	*lcp);

vnode_t *	dm_handle_to_vp (
			xfs_handle_t	*handlep,
			short		*typep);

int		dm_check_dmapi_vp(
			vnode_t		*vp);

dm_tokevent_t * dm_find_mount_tevp_and_lock(
			fsid_t		*fsidp,
			unsigned long	*lcp);

int		dm_path_to_hdl(
			char		*path,
			void		*hanp,
			size_t		*hlenp);

int		dm_path_to_fshdl(
			char		*path,
			void		*hanp,
			size_t		*hlenp);

int		dm_fd_to_hdl(
			int		fd,
			void		*hanp,
			size_t		*hlenp);

int		dm_upgrade_right(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token);

int		dm_downgrade_right(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token);

int		dm_request_right(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			u_int		flags,
			dm_right_t	right);

int		dm_release_right(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token);

int		dm_query_right(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			dm_right_t	*rightp);


int		dm_set_eventlist(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			dm_eventset_t	*eventsetp,
			u_int		maxevent);

int		dm_obj_ref_hold(
			dm_sessid_t	sid,
			dm_token_t	token,
			void		*hanp,
			size_t		hlen);

int		dm_obj_ref_rele(
			dm_sessid_t	sid,
			dm_token_t	token,
			void		*hanp,
			size_t		hlen);

int		dm_get_eventlist(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			u_int		nelem,
			dm_eventset_t	*eventsetp,
			u_int		*nelemp);


int		dm_set_disp(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			dm_eventset_t	*eventsetp,
			u_int		maxevent);


int		dm_set_return_on_destroy(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			dm_attrname_t	*attrnamep,
			dm_boolean_t	enable);


int		dm_get_mountinfo(
			dm_sessid_t	sid,
			void		*hanp,
			size_t		hlen,
			dm_token_t	token,
			size_t		buflen,
			void		*bufp,
			size_t		*rlenp);

void		dm_link_event(
			dm_tokevent_t	*tevp,
			dm_eventq_t	*queue);

void		dm_unlink_event(
			dm_tokevent_t	*tevp,
			dm_eventq_t	*queue);

int		dm_open_by_handle_rvp(
			unsigned int	fd,
			void		*hanp,
			size_t		hlen,
			int		mode,
			int		*rvp);

int		dm_copyin_handle(
			void		*hanp,
			size_t		hlen,
			xfs_handle_t	*handlep);

#endif	/* _DMAPI_PRIVATE_H */