/*
 * local defs of useful things
 */

#ifndef __FS_USERFS_USERFS_H_SEEN__
#define __FS_USERFS_USERFS_H_SEEN__

#include "assert.h"

#ifdef AFTER1_1_13
#define AFTER1_1_11
#endif

#if __cplusplus
#define __FUNCTION__	"__FUNCTION__:"__FILE__":(function/line unknown)"
#endif

#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))

extern struct file_operations userfs_file_operations;
extern struct inode_operations userfs_inode_operations;
extern struct super_operations userfs_super_operations;

extern void userfs_close_chan(struct super_block *);
extern void userfs_setcred(up_cred *);

extern struct super_operations *userfs_probe_sops(struct super_block *);
extern struct inode_operations *userfs_probe_iops(struct super_block *);
extern struct file_operations *userfs_probe_fops(struct super_block *);

extern int userfs_probe(struct super_block *, up_ops);
extern void userfs_set_inode(struct inode *, const up_inode *);

/* Access macros for union members */

#ifdef MODULE
#define U_SB(sb)	(*(struct userfs_sb_info *)(sb)->u.generic_sbp)
#define U_INO(ino)	(*(struct userfs_inode_info *)(ino)->u.generic_ip)
#define U_SBP(sb)	((struct userfs_sb_info *)(sb)->u.generic_sbp)
#define U_INOP(ino)	((struct userfs_inode_info *)(ino)->u.generic_ip)
#ifdef AFTER1_1_13
#define U_FILEP(file)	((struct userfs_file_info *)(file)->private_data)
#define U_FILE(file)	(*(struct userfs_file_info *)(file)->private_data)
#else
#define U_FILEP(file)	((struct userfs_file_info *)(file)->u.generic_fp)
#define U_FILE(file)	(*(struct userfs_file_info *)(file)->u.generic_fp)
#endif /* AFTER1_1_13 */
#else /* !MODULE */
#define U_SB(sb)	((sb)->u.userfs_sb)
#define U_INO(ino)	((ino)->u.userfs_i)
#define U_FILE(file)	((file)->u.userfs_f)
#endif /* MODULE */

/* A kiss to end a sleep */
extern struct pwlist *userfs_kiss(struct super_block *, int seq, int why);

/* reasons why */
#define UP_FINISH	1	/* Finish up - your prince will never come */
#define UP_RECV		2	/* Your prince has arrived */
#define UP_BATON	3	/* You take over */

/* for matching entries */
#define UP_WFIRST	(-1)	/* wake first */
#define UP_WALL		(-2)	/* wake all entries */

/* Element on list of sleeping processes */
struct pwlist
{
	struct wait_queue *bed;		/* where we sleep */
	int	why;			/* filled on wake - why we woke */
	int	seq;			/* reply seqence */
	upp_repl repl;			/* reply header */
	char	*more;			/* extra data */
	int	pid;			/* prince id */

	struct pwlist *next;		/* there are other beauties */
	struct pwlist *prev;
};

/*
 * kmalloc can only allocate a certain amount of memory.
 * It used to be a page, but now its a little less.
 * This should really be in a header file related to kmalloc.
 */
#define MAX_KMALLOC USERFS_MAX_XFER
#include <linux/malloc.h>

/* Directory readahead things */
void userfs_free_dirra(struct inode *ino);

struct userfs_dir_ra
{
	int	nent;			/* Number of entries */
	struct	userfs_dent *ents;	/* Entries */
};

struct userfs_dent
{
	off_t		offset;		/* Dir offset */
	off_t		roff;		/* Returned offset */
	ino_t		inum;		/* Inode number */
	char		*name;		/* Name, not \0 terminated */
	unsigned	nlen;		/* Name length */
};

/* Inode locking, taken stright from linux/fs/inode.h */
void __wait_on_inode(struct inode *);

static inline void wait_on_inode(struct inode * inode)
{
	if (inode->i_lock)
		__wait_on_inode(inode);
}

static inline void lock_inode(struct inode * inode)
{
	wait_on_inode(inode);
	inode->i_lock = 1;
}

static inline void unlock_inode(struct inode * inode)
{
	inode->i_lock = 0;
	wake_up(&inode->i_wait);
}
   

#endif /* __FS_USERFS_USERFS_H_SEEN__ */
