/*
 * fs.h
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 */


#ifndef fs_h
#define fs_h


#include<config.h>
#include<types.h>
#include<wait.h>
#include<limits.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<sys/unistd.h>
#include<sys/select.h>
#include<sys/poll.h>
#include<share/stropts.h>


#ifndef ASM_FILE


#include<sys/mount.h>


enum{
	/* ファイルディスクリプター用ファイルの種類。 */
	FD_FORM_LOCALFILE=1,
	FD_FORM_DIRSTREAM,
	FD_FORM_NETSOKET,
};


/* ファイルシステムインフォメーション構造体 */
typedef struct FS{
	const char *name;
	// parameters : device inode, out root inode object
	// retern     : error number
	int (*mount)(const int, void**);
	// parameters : device inode, root inode object
	// retern     : error number
	int (*umount)(const int, void*);
	// parameters : path, device inode, directory inode object, out inode number
	// retern     : error number
	int (*lookup)(const char*, const int, void*, uint*);
	// parameters : path, device inode, directory inode object, file mode, out inode number
	// retern     : error number
	int (*creat)(const char*, const int, void*, const int, uint*);
	// parameters : device inode, inode number, open flag, out inode object, out file type
	// retern     : error number
	int (*open)(const int, const uint, int, void **, int *);
	// parameters : device inode, inode object
	// retern     : error number
	int (*close)(const int, void*);
	// parameters : device inode, inode object, resd buffer, read bytes, begin byte
	// retern     : read bytes error number
	int (*read)(const int, void*, void*, size_t, size_t);
	// parameters : device inode, inode object, write buffer, write bytes, begin byte
	// retern     : write bytes error number
	int (*write)(const int, void*, void*, size_t, size_t);
	// parameters : device inode, inode object, command, parameter, parameter2, 
	// retern     : error number
	int (*ioctl)(const int, void*, int, caddr_t, int);
	// parameters : inode object, events
	// retern     : poll condition
	int (*poll)(void*, int);
	// parameters : path, device inode, directory inode object, out inode object, out stream, out block, out index 
	// retern     : error number
	int (*opendir)(const char*, const int, void*, void**, uint*, int*);
	// parameters : device inode, inode object, modify block, modify index, out name 
	// retern     : error number
	int (*readdir)(const int, void*, uint*, int*,char*);
	// parameters : device inode, old dir inode object, old path, new dir inode object, new path
	// retern     : error number
	int (*rename)(const int, void*, const char*, void*, const char*);
	// parameters : path, device inode, directory inode object, mode
	// retern     : error number
	int (*mkdir)(const char*,const int, void*, int);
	// parameters : device inode, inode object, modivy struct stat
	// retern     : error number
	int (*stat)(const int, void*, struct stat*);
	// parameters : path, device inode, directory inode object, file type
	// retern     : error number
	int (*delete)(const char*, const int, void*, int);
	// parameters : device inode, inode object, mode, uid, gid, access time, modified time
	// retern     : error number
	int (*chattr)(const int, void*, uint, uint, uint, uint, uint);
	// parameters : device inode, destination inode object, source inode object, source path
	// retern     : error number
	int (*link)(const int, void*, void*, const char*);
	// parameters : path, device inode, directory inode object, link path
	// retern     : error number
	int (*symlink)(const char*, const int, void*, char*);
	// parameters : device inode, modify struct statfs
	// retern     : NOERR
	int (*statfs)(const int din, struct statfs*);
	struct FS *next;
}FS;

/*
 * 仮想エントリー
 * Note!
 *  fsとinodeの位置はソケット構造体とリンクしているので注意。
 */
typedef struct VENTRY{
	FS				*fs;		/* Filesystem. */
	void			*inodeObj;	/* inode object */
	struct VENTRY	*next;		/* ラウンドリンクリストネクスト */
	struct VENTRY	*prev;		/* ラウンドリンクリストプレビュー */
	struct VENTRY	*parent;	/* 親エントリー */
	struct VENTRY	*child;		/* 次のノードのトップエントリー */
	struct VENTRY	*mount;		/* マウントエントリー */
	WAIT_QUEUE		*wait;		/* Lock wait. */
	ushort			refCount;	/* 参照カウンタ、マウントやカレントディレクトリ時、実行ファイル実行カウント */
	uchar			din;		/* デバイスinode */
	uchar			len;		/* Name size. */
	int				type;		/* ファイルタイプ */
	int				link;		/* ファイルリンクカウント */
	char			name[0];	/* パスネーム */
}VENTRY;

/* ファイル実行用ファイルディスクリプタ */
typedef struct{
	int		din;
	void	*inodeObj;
	FS		*fs;
	size_t	offset;		// 読み書き開始オフセット
}EXEC_FD;

/* ファイルディスクリプタ */
typedef struct{
	uchar  form;		/* 種類。 */
	uchar  refCount;	/* 参照カウント。 */
	ushort accessMode;	/* Access mode. */
	size_t f_pos;		/* 読み書き開始オフセット。 */
	VENTRY *vent;		/* 仮想エントリー。 */
}F_DSC;

/*
 * ディレクトリストリーム
 *《注意》ファイルディスクリプタと共用して使われるので"fd"の位置は必ず先頭にする
 */
typedef struct{
	F_DSC		fd;
	uint		block;		/* directory block. */
	int			index;		/* directory index. */
}DIR_STRAEM;

/* プロセス用ファイル構造体 */
typedef struct{
	VENTRY		*current_dir;		// カレントディレクトリ
	F_DSC		*fd[OPEN_MAX];
	uchar		flag[OPEN_MAX];		// ファイルディスクリプタフラグ
	uchar		fd_count;			// ファイルディスクリプタオープン数
	uchar		next_fd;			// 次の空きファイルディスクリプタ配列
}FILE_STRUCT;


extern FS *fs_info[];


extern void			 initExecFs();
extern void			 init_fs();
extern int			 mount_dev_fs(FS*);
extern int			 regist_fs(FS*);
extern FILE_STRUCT	*copyFileStruct(FILE_STRUCT*);
extern void			 releaseFileStruct(FILE_STRUCT*);
extern int			 init_file_struct(PROC*);
extern void			 initFd(VENTRY*, const int, const int ,F_DSC*);
extern int			 setFd(F_DSC*, const int flag);
extern F_DSC		*getFd(int);
extern int			 isFileOpenMax();
extern int			 initProc1Fs();
//extern int			 get_inode(int);
extern int			 mountRoot(const char*,const char*);
extern int			 mountPageBackupDev(const char*, void**);
extern int			 cmpString(const char *str1,const char *str2);
extern const char	*cmpPathNull(const char *path1,const char *path2);
extern int			 cmpPath(const char *name,const char *path,int count);
extern size_t		 pathLen(const char *path);
extern int			 isLastPath(const char *path);

extern int			 exec_open(const char*,EXEC_FD*);
extern int			 exec_read(EXEC_FD*,void*,size_t);
extern int			 exec_close(EXEC_FD*);
extern int			 sys_open();
extern int			 sys_close();
extern int			 sys_read();
extern int			 sys_write();
extern int			 sys_ioctr();
extern int			 sys_lseek();
extern int			 sys_mkdir();
extern int			 sys_creat();
extern int			 sys_rename();
extern int			 sys_unlink();
extern int			 sys_rmdir();
extern int			 sys_lock();
extern int			 sys_mount();
extern int			 sys_umount();
extern int			 sys_opendir();
extern int			 sys_closedir();
extern int			 sys_readdir();
extern int			 sys_rewinddir();
extern int			 sys_chdir();
extern int			 sys_fchdir();
extern int			 sys_getcwd();
extern int			 sys_stat();
extern int			 sys_chattr();
extern int			 sys_fchattr();
extern int			 sys_umount_root();
extern int			 sys_fcntl();
extern int			 sys_ioctl();
extern int			 sys_link();
extern int			 sys_symlink();
extern int			 sys_readlink();
extern int			 sys_select();
extern int			 sys_poll();
extern int			 sys_getstatfs();
extern int			 sys_statfs();



#endif


#endif
