/*
 * fsbase.c: implementation of base filesystem object.
 */

/* TODO convert to use vsize_t, vssize_t */

#include <../source/TAL/objbase.h>
#include <../source/PAL/dataman.h>
#include <../source/vfs/iobase.h>
#include <../source/vfs/fsbase.h>
#include <../source/vfs/fsops.h>

#ifdef	CHECKED_BUILD
#define	VFS_MAGIC				0x524F4653	/* ROFS */
static char	*vfs_object			= "virtual FS";
#endif	/* CHECKED_BUILD */

/*
 * Note: we don't touching ref_count here if it greater then 1.
 */
V_LOCAL u32_t V_CALL
vfs_generic_destroy(vhandle_t handle)
{
	mutex_t mut;
	vfs_dev_p self = (vfs_dev_p)handle;
	mutexLock(self->vfs_lock);
	if(self->base.ref_count > 1)
	{
		mutexUnlock(self->vfs_lock);
		return self->base.ref_count;
	}
	mut = self->vfs_lock;
	memFreeObject(self);
	mutexUnlock(mut);
	mutexDestroy(mut);
	return 0;
}

/*
 * Default FS stubs.
 */
#include <../source/PAL/argsused.h>
V_LOCAL char_p	V_CALL
vfs_get_volume_name_stub(struct vfs_dev_s *self)
{
	return "[unknown]";
}

#include <../source/PAL/argsused.h>
V_LOCAL u32_t	V_CALL
vfs_get_inode_count_stub(struct vfs_dev_s *self)
{
	return 0;
}

#include <../source/PAL/argsused.h>
V_LOCAL vboolean	V_CALL
vfs_get_file_name_stub(struct vfs_dev_s *self,u32_t inode,char *name_ret)
{
	return false;
}

#include <../source/PAL/argsused.h>
V_LOCAL vhandle_t	V_CALL
vfs_create_file_stub(struct vfs_dev_s *self,u32_t inode)
{
	/*
	 * Note: in real routine self->base.ref_count must be
	 * incremented if port created successfully.
	 */
	return NULL;
}

vfs_dev_p	V_CALL
vfsCreateFS(u32_t size_of_object)
{
	vfs_dev_t *fs;
	if(size_of_object < sizeof(vfs_dev_t))
		size_of_object = sizeof(vfs_dev_t);
	ALLOC_OBJECT(fs,vfs_dev_t,size_of_object-sizeof(vfs_dev_t),VFS_MAGIC);
	fs->base.destroy = vfs_generic_destroy;
	fs->vfs_lock = mutexCreate();
	fs->get_volume_name = vfs_get_volume_name_stub;
	fs->get_inode_count = vfs_get_inode_count_stub;
	fs->get_file_name = vfs_get_file_name_stub;
	fs->create_file = vfs_create_file_stub;
	return fs;
}

void	V_CALL
vfsDestroy(vhandle_t vfs_handle)
{
	libvCloseHandle(vfs_handle,"vfsDestroy",vfs_object,VFS_MAGIC);
}
