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


#ifndef fs_h
#define fs_h


#include"types.h"


#ifndef ASM_FILE


enum{
	/* File type */
	NORMAL_FILE=1,
	DIRECTORY=2,
	SYMBOL_LINK=3,
	DEVICE_FILE=4,

	MAX_FILE_OPEN=16,		/* プロセスの最大ファイルオープン数 */
	VDIR_MAX_NAME_SIZE=127,	/* 仮想ファイルシステムの最大名前サイズ */
};


/* ファイルシステムインフォメーション構造体 */
typedef struct{
	const char *name;
	void *(*mount)(int);
	int (*umount)(int);
	void *(*open)(const char*,void*,int);
	int (*read)(void*,void*,size_t,size_t);
	int (*write)(void*,void*,size_t,size_t);
	int (*ioctr)(void*,int,void*);
	int (*rename)(void*,const char*);
	int (*creat)(const char*,void*,int);
	void *(*opendir)(const char*,void*,int);
	int (*mkdir)(const char*,void*,int);
	int (*close)(void*);
}FS;

typedef struct VDIR{
	ushort fs;						/* file system number */
	ushort din;						/* device inode index */
	uint dir_blk;					/* ファイルシステムのディレクトリブロック */
	struct VDIR *same_next;			/* 同ノードのディレクトリ */
	struct VDIR *low_next;			/* 下のノードのディレクトリ */
	struct VDIR *before_vdir;		/* マウント前の仮想ディレクトリ */
	char name[VDIR_MAX_NAME_SIZE];
}VDIR;

/* ファイルディスクリプタ */
typedef struct{
	uchar dev;
	uchar fs;
	ushort count;
	void *inode;
	size_t offset;
}F_DSC;

typedef struct{
	F_DSC *fd[MAX_FILE_OPEN];	/* File descriptor pointer */
	void *current_dir;			/* Current directory */
	VDIR *current_vdir;			/* Current virtial directory */
}F_STRUCT;


extern FS *fs_info[];


extern void init_fs();
extern int regist_fs(FS*);
extern int mount_root_fs(const char*,const char*);
extern int sys_open();
extern int sys_read();
extern int sys_write();
extern int sys_ioctr();
extern int sys_lseek();
extern int sys_rename();
extern int sys_creat();
extern int sys_unlink();
extern int sys_lock();
extern int sys_mount();
extern int sys_umount();


/*
 * cmpare path strings
 * parameters : Destination string(end='\0'),Sorce string
 * return : 一致=0 or 不一致=-1
 */
extern inline int cmp_path(const char *path1,const char *path2)
{
	while(*path1!='\0')
		if(*path1++!=*path2++)return -1;

	if(*path2=='\0'||*path2=='/')return 0;

	return -1;
}


/*
 * パスの文字列をはかる。
 * parmeters :
 */
extern inline size_t path_len(const char *s)
{
	const char *p=s;


	while(*p++!='/')
		if(*p=='\0')break;

	return (size_t)(p-s-1);
}


#endif


#endif
