
XFS DOCUMENTATION
=================

$Id: xfs.txt,v 1.5 2000/06/06 15:21:12 lha Exp $

This is not the truth, but close too.


TODO
#include <xfs/xfs_attr.h>


LIMITATIONS and CONSTANTS
=========================

You can install messages to xfs of maxsize ``MAX_XMSG_SIZE''.

The kernel can at most hold  rights of size ``MAXRIGHTS''.

A xfs handle have the size of ``MAXHANDLE'', and that is at least 16bytes.

The annonous user had id ``XFS_ANONYMOUSID''.

The xfs-fh-open-handle have the size of ``CACHEHANDLESIZE'', and its
a opaque data-structure.

PAGS
====

Pags are a hack to separate processes of same UID to make them have
diffrent access-rights. Pags are saved over setuid(2)/initgroups(2)
calls. Xfs uses a struct ``xfs_cred'' to pass over the UID and the pag.


TOKENS
======

Tokens are the rights the xfs have on the node and what parts of the
node that is valid.

XXX Insert descriptions of tokens here....


MESSAGES
========

Are passed through the xfs device somehow.

Each message is prepended by a header including the 32-bit fields
`size'', ``opcode'', ``sequence_num'', ``pad1'' (in that
order). ``Size'' is the size of the WHOLE message.  ``Opcode'' is the
opcode (described bellow). ``sequence_num'' is a messages specific field
that is used for replying the the sender of the message (if so is
needed).

All messages (and the xfs_header) are padded to 64-bit boundery to
avoid bit unaligned data in the kernel. The padding is called padN,
where N is a number.

Note that the total size of the message may be larger then one message,
them its two or more message pasted together for preformance resons.

The opcode has a value from 0 (zero) to XFS_MSG_COUNT - 1.

The following opcodes are defined:

XFS_MSG_VERSION (userland)

	Used probe the kernelmodule to check some *basic* things that will change
        the behavior of the userland module.

        For each question XFS_MSG_VERSION can return XFS_VERSION_YES
        or XFS_VERSION_NO.

        If VERSION returns something else then XFS_VERSION_YES to
        XFS_MSG_VERSION, its not supported.

        ``probe'' is set to a query.

        Queries that exist today is:
	XFS_VERSION_VERSION	- check if we have XFS_VERSION supporta
	XFS_VERSION_FHGET	- have we fhget support, or do we use pathnames
	XFS_VERSION_FHGET_NATIVE- native fhget (not xfs-version ?)
	XFS_VERSION_GC_NODES	- we have gc-nodes xfs-call ?

XFS_MSG_WAKEUP (userland|xfs)

	Wakeup query ``sleepers_sequence_num'' with ``error'' (that is a
	errno or userdefined error).

        It may be called from both userland and the xfs-implementation.

XFS_MSG_GETROOT (xfs)

	GETROOT is called to get the root-node with the ``cred''

	Its only called from xfs to get the root-node, this might be
	serveral times per mount depending on filesystem.

        Xfs is wake-up:ed by a XFS_MSG_WAKEUP message from userland
        after a XFS_MSG_INSTALLROOT message has been sent or and error-code is
        passed to the kernel with the wakeup-message.

XFS_MSG_INSTALLROOT (userland)

	INSTALLROOT is called insert a root.

        INSTALLROOT MUST only be called on the request of GETROOT.

        The node to install is in ``node''.

        The only returnvalue of the message is the integer return value.

        Multiple INSTALLROOT must be ignored by the xfs-implementation, and
        the returnvalue EBUSY MUST be returned.

XFS_MSG_GETNODE (xfs)

	GETNODE is called to get the node named ``named'' in the
	directory ``parent_handle'' with ``cred''.

	While there is no error in the returning WAKEUP call and there
	is corresponding node in cache the xfs-implemetation should
	loop until there is an error.

XFS_MSG_INSTALLNODE (userland)

	Insert the ``node'' of ``name'' in the directory ``parent_handle''
	into the cache.

	The userland MUST NOT install the ``node'' yet onther time

	The xfs-implemetation SHOULD NOT install same node several
	times in the same ``parent_handle'', that is if ``node'' has
	same parent and same name (observe that same handle can be
	installed several times in the case of hardlinks).

XFS_MSG_GETATTR (xfs)

	Get the attributes for the node described by ``handle'' that
	already have been installed by INSTALLNODE with the ``cred''.

	The xfs-implemetation should loop until there is an error,
	or the node is the cache with appropriate pag in the cred
	part of the node.

XFS_MSG_INSTALLATTR (userland)

	Should update the preinstalled incache data with ``node''.  If
	the node found in ``node.handle'' isn't in the cache the
	xfs-implementation MUST return 0 and MIGHT print a
	debug-message. Note that this isn't error if the node isn't in
	the xfs-cache since it might have fallen out before the
	message was sent to xfs (that is, the invalidnode message is
	still in the queue to userland).

XFS_MSG_GETDATA (xfs)

	Get data for the node described in ``handle''. Otherwise same
	as GETATTR.

XFS_MSG_INSTALLDATA (userland)

	Install data for the node described by ``node.handle''. The
	vnode/inode that contains the is pointed out by ``cache_handle''
	the there is support for openfh/getfh. Its also pointed out
	by the name ``cache_name'', and that name is relative to the
	current process current working directory.

	Installdata also updates the attributes of the node.

	If the ``flag & XFS_ID_INVALID_DNLC'' is set the
	xfs-implementation should flush all namecache related to this
	node. The xfs-implementation SHOULD check that this is a
	directory-node.

XFS_MSG_INACTIVENODE (xfs)

	The message that xfs sends to the userland daemon when
	``handle'' no longer exist in the cache.

	To tell what state the node is in flag in set to appropiate
	value.  ``XFS_NOREFS'' tells the userland daemon that the xfs
	still have the node cached but nothing is using it and it can
	be removed at any time. ``XFS_DELETE'' mean that all this node
	has been droped from the cache and can't be used anymore.

XFS_MSG_INVALIDNODE (userland)

	Used to hint the kernel that node described by `handle''
	should be droped from the cache. Doesn't mean that the node
	should be killed off, just that it should be that when it's no
	longer used.

	The userland MUST NOT remove the node from the cache until it
	receives a XFS_MSG_INACTIVENODE.

	XXX what is the diffrence to GC_NODE

XFS_MSG_OPEN (xfs)

	Passed up to the userland to inform that ``handle'' has been
	opened with ``cred'' to do what is decribed in ``tokens''.

	Can be the same as XFS_MSG_GETDATA if no locking is implemeted.	

XFS_MSG_PUTDATA (xfs)

enum { XFS_READ = 1, XFS_WRITE = 2, XFS_NONBLOCK = 4, XFS_APPEND = 8};

XFS_MSG_PUTATTR (xfs)

/* Directory manipulating messages. */
XFS_MSG_CREATE (xfs)
XFS_MSG_MKDIR (xfs)
XFS_MSG_LINK (xfs)
XFS_MSG_SYMLINK (xfs)

XFS_MSG_REMOVE (xfs)
XFS_MSG_RMDIR (xfs)

XFS_MSG_RENAME (xfs)

XFS_MSG_PIOCTL (xfs)
XFS_MSG_WAKEUP_DATA (userland)

XFS_MSG_UPDATEFID (userland)

XFS_MSG_ADVLOCK (xfs/userland)

XFS_MSG_GC_NODES (userland)


__END__;

/* XFS_MSG_OPEN */
struct xfs_message_open {
  struct xfs_message_header header;
  struct xfs_cred cred;
  xfs_handle handle;
  u_int32_t tokens;
  u_int32_t pad1;
};

/* XFS_MSG_PUTDATA */
struct xfs_message_putdata {
  struct xfs_message_header header;
  xfs_handle handle;
  struct xfs_attr attr;		/* XXX ??? */
  struct xfs_cred cred;
  u_int32_t flag;
  u_int32_t pad1;
};

/* XFS_MSG_PUTATTR */
struct xfs_message_putattr {
  struct xfs_message_header header;
  xfs_handle handle;
  struct xfs_attr attr;
  struct xfs_cred cred;
};

/* XFS_MSG_CREATE */
struct xfs_message_create {
  struct xfs_message_header header;
  xfs_handle parent_handle;
  char name[256];		/* XXX */
  struct xfs_attr attr;
  u_int32_t mode;
  u_int32_t pad1;
  struct xfs_cred cred;
};

/* XFS_MSG_MKDIR */
struct xfs_message_mkdir {
  struct xfs_message_header header;
  xfs_handle parent_handle;
  char name[256];		/* XXX */
  struct xfs_attr attr;
  struct xfs_cred cred;
};

/* XFS_MSG_LINK */
struct xfs_message_link {
  struct xfs_message_header header;
  xfs_handle parent_handle;
  char name[256];		/* XXX */
  xfs_handle from_handle;
  struct xfs_cred cred;
};

/* XFS_MSG_SYMLINK */
struct xfs_message_symlink {
  struct xfs_message_header header;
  xfs_handle parent_handle;
  char name[256];		/* XXX */
  char contents[2048];		/* XXX */
  struct xfs_attr attr;
  struct xfs_cred cred;
};

/* XFS_MSG_REMOVE */
struct xfs_message_remove {
  struct xfs_message_header header;
  xfs_handle parent_handle;
  char name[256];		/* XXX */
  struct xfs_cred cred;
};

/* XFS_MSG_RMDIR */
struct xfs_message_rmdir {
  struct xfs_message_header header;
  xfs_handle parent_handle;
  char name[256];		/* XXX */
  struct xfs_cred cred;
};

/* XFS_MSG_RENAME */
struct xfs_message_rename {
  struct xfs_message_header header;
  xfs_handle old_parent_handle;
  char old_name[256];		/* XXX */
  xfs_handle new_parent_handle;
  char new_name[256];		/* XXX */
  struct xfs_cred cred;
};

/* XFS_MSG_PIOCTL */
struct xfs_message_pioctl {
  struct xfs_message_header header;
  u_int32_t opcode ;
  u_int32_t pad1;
  xfs_cred cred;
  u_int32_t insize;
  u_int32_t outsize;
  char msg[2048] ;    /* XXX */
  xfs_handle handle;
};


/* XFS_MESSAGE_WAKEUP_DATA */
struct xfs_message_wakeup_data {
  struct xfs_message_header header;
  u_int32_t sleepers_sequence_num;	/* Where to send wakeup */
  u_int32_t error;			/* Return value */
  u_int32_t len;
  u_int32_t pad1;
  char msg[2048] ;    /* XXX */
};

/* XFS_MESSAGE_UPDATEFID */
struct xfs_message_updatefid {
  struct xfs_message_header header;
  xfs_handle old_handle;
  xfs_handle new_handle;
};

/* XFS_MESSAGE_ADVLOCK */
struct xfs_message_advlock {
  struct xfs_message_header header;
  xfs_handle handle;
  struct xfs_cred cred;
  xfs_locktype_t locktype;
#define XFS_WR_LOCK 1 /* Write lock */
#define XFS_RD_LOCK 2 /* Read lock */
#define XFS_UN_LOCK 3 /* Unlock */
#define XFS_BR_LOCK 4 /* Break lock (inform that we don't want the lock) */
  xfs_lockid_t lockid;
};

/* XFS_MESSAGE_GC_NODES */
struct xfs_message_gc_nodes {
  struct xfs_message_header header;
#define XFS_GC_NODES_MAX_HANDLE 50
  u_int32_t len;
  u_int32_t pad1;
  xfs_handle handle[XFS_GC_NODES_MAX_HANDLE];
};
#endif /* _xmsg_h */
