* Ported the FAT filesystem to the recent filesystem interface changes which

was, thanks to the detailed instructions from Ingo, quite doable.
* Ported the (deprecated and now publically removed) notify_listener() calls
  to the respective new notify_* calls.
* Fixed debug build.
* Added the FAT filesystem back to the image.

I only tested the filesystem briefly and everything seemed to work as expected
(mounted the FAT part of my bootable Haiku memory stick, opened a few files
and copied something to it). At least it should not be any more broken than
before the interface changes ;-).

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24987 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2008-04-16 20:24:22 +00:00
parent 261a29594b
commit 72010d4247
9 changed files with 311 additions and 258 deletions

View File

@ -134,8 +134,8 @@ BEOS_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com etherpci $(X86_ONLY)ipro1000
BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
config_manager agp_gart usb firewire
;
BEOS_ADD_ONS_FILE_SYSTEMS = bfs ;
#cdda fat googlefs iso9660 nfs $(GPL_ONLY)ntfs ;
BEOS_ADD_ONS_FILE_SYSTEMS = bfs fat ;
#cdda googlefs iso9660 nfs $(GPL_ONLY)ntfs ;
# modules

View File

@ -57,9 +57,9 @@ status_t set_mime_type(vnode *node, const char *filename)
status_t
dosfs_open_attrdir(void *_vol, void *_node, void **_cookie)
dosfs_open_attrdir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
{
nspace *vol = (nspace *)_vol;
nspace *vol = (nspace *)_vol->private_volume;
TOUCH(_node);
@ -84,9 +84,9 @@ dosfs_open_attrdir(void *_vol, void *_node, void **_cookie)
}
status_t
dosfs_close_attrdir(void *_vol, void *_node, void *_cookie)
dosfs_close_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
nspace *vol = (nspace *)_vol;
nspace *vol = (nspace *)_vol->private_volume;
TOUCH(_node);
@ -108,7 +108,7 @@ dosfs_close_attrdir(void *_vol, void *_node, void *_cookie)
status_t
dosfs_free_attrdir_cookie(void *_vol, void *_node, void *_cookie)
dosfs_free_attrdir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
TOUCH(_vol); TOUCH(_node);
@ -127,7 +127,7 @@ dosfs_free_attrdir_cookie(void *_vol, void *_node, void *_cookie)
status_t
dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie)
dosfs_rewind_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
TOUCH(_vol); TOUCH(_node);
@ -144,11 +144,11 @@ dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie)
status_t
dosfs_read_attrdir(void *_vol, void *_node, void *_cookie,
dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
struct dirent *entry, size_t bufsize, uint32 *num)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
int32 *cookie = (int32 *)_cookie;
TOUCH(bufsize);
@ -183,11 +183,11 @@ dosfs_read_attrdir(void *_vol, void *_node, void *_cookie,
status_t
dosfs_open_attr(void *_vol, void *_node, const char *name, int openMode,
fs_cookie *_cookie)
dosfs_open_attr(fs_volume *_vol, fs_vnode *_node, const char *name,
int openMode, void **_cookie)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
if (strcmp(name, "BEOS:TYPE"))
return ENOENT;
@ -207,24 +207,25 @@ dosfs_open_attr(void *_vol, void *_node, const char *name, int openMode,
status_t
dosfs_close_attr(void *_vol, void *_node, fs_cookie cookie)
dosfs_close_attr(fs_volume *_vol, fs_vnode *_node, void *cookie)
{
return B_OK;
}
status_t
dosfs_free_attr_cookie(void *_vol, void *_node, fs_cookie cookie)
dosfs_free_attr_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie)
{
return B_OK;
}
status_t
dosfs_read_attr_stat(void *_vol, void *_node, fs_cookie _cookie, struct stat *stat)
dosfs_read_attr_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
struct stat *stat)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
DPRINTF(0, ("dosfs_read_attr_stat\n"));
@ -253,11 +254,11 @@ dosfs_read_attr_stat(void *_vol, void *_node, fs_cookie _cookie, struct stat *st
status_t
dosfs_read_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
dosfs_read_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
void *buffer, size_t *_length)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
DPRINTF(0, ("dosfs_read_attr\n"));
@ -293,8 +294,8 @@ dosfs_read_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
// suck up application attempts to set mime types; this hides an unsightly
// error message printed out by zip
status_t
dosfs_write_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
const void *buffer, size_t *_length)
dosfs_write_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, const void *buffer, size_t *_length)
{
DPRINTF(0, ("dosfs_write_attr\n"));

View File

@ -9,20 +9,22 @@
status_t set_mime_type(vnode *node, const char *filename);
status_t dosfs_open_attrdir(void *_vol, void *_node, void **_cookie);
status_t dosfs_close_attrdir(void *_vol, void *_node, void *_cookie);
status_t dosfs_free_attrdir_cookie(void *_vol, void *_node, void *_cookie);
status_t dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie);
status_t dosfs_read_attrdir(void *_vol, void *_node, void *_cookie,
status_t dosfs_open_attrdir(fs_volume *_vol, fs_vnode *_node, void **_cookie);
status_t dosfs_close_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie);
status_t dosfs_free_attrdir_cookie(fs_volume *_vol, fs_vnode *_node,
void *_cookie);
status_t dosfs_rewind_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie);
status_t dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
struct dirent *buf, size_t bufsize, uint32 *num);
status_t dosfs_open_attr(void *_vol, void *_node, const char *name, int openMode,
fs_cookie *_cookie);
status_t dosfs_close_attr(void *_vol, void *_node, fs_cookie cookie);
status_t dosfs_free_attr_cookie(void *_vol, void *_node, fs_cookie cookie);
status_t dosfs_read_attr_stat(void *_vol, void *_node, fs_cookie _cookie, struct stat *stat);
status_t dosfs_read_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
void *buffer, size_t *_length);
status_t dosfs_write_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
const void *buffer, size_t *_length);
status_t dosfs_open_attr(fs_volume *_vol, fs_vnode *_node, const char *name,
int openMode, void **_cookie);
status_t dosfs_close_attr(fs_volume *_vol, fs_vnode *_node, void *cookie);
status_t dosfs_free_attr_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie);
status_t dosfs_read_attr_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
struct stat *stat);
status_t dosfs_read_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, void *buffer, size_t *_length);
status_t dosfs_write_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, const void *buffer, size_t *_length);
#endif

View File

@ -21,6 +21,7 @@
#include "fat.h"
#include "util.h"
#include "vcache.h"
#include "file.h"
#include "encodings.h"
@ -432,7 +433,7 @@ findfile(nspace *vol, vnode *dir, const char *file, ino_t *vnid,
if (vnid)
*vnid = found_vnid;
if (node)
result = get_vnode(vol->id, found_vnid, (void **)node);
result = get_vnode(vol->volume, found_vnid, (void **)node);
result = B_OK;
} else {
result = ENOENT;
@ -922,9 +923,10 @@ create_dir_entry(nspace *vol, vnode *dir, vnode *node, const char *name,
status_t
dosfs_read_vnode(void *_vol, ino_t vnid, void **_node, bool reenter)
dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
uint32 *_flags, bool reenter)
{
nspace *vol = (nspace*)_vol;
nspace *vol = (nspace*)_vol->private_volume;
int result = B_NO_ERROR;
ino_t loc, dir_vnid;
vnode *entry;
@ -936,7 +938,9 @@ dosfs_read_vnode(void *_vol, ino_t vnid, void **_node, bool reenter)
LOCK_VOL(vol);
}
*_node = NULL;
_node->private_node = NULL;
_node->ops = &gFATVnodeOps;
_flags = 0;
if (check_nspace_magic(vol, "dosfs_read_vnode")) {
if (!reenter) UNLOCK_VOL(vol);
@ -947,7 +951,8 @@ dosfs_read_vnode(void *_vol, ino_t vnid, void **_node, bool reenter)
if (vnid == vol->root_vnode.vnid) {
dprintf("??? dosfs_read_vnode called on root node ???\n");
*_node = (void *)&(vol->root_vnode);
_node->private_node = (void *)&(vol->root_vnode);
*_type = make_mode(vol, &vol->root_vnode);
goto bi;
}
@ -1043,7 +1048,8 @@ dosfs_read_vnode(void *_vol, ino_t vnid, void **_node, bool reenter)
if (!(entry->mode & FAT_SUBDIR))
set_mime_type(entry, filename);
*_node = entry;
_node->private_node = entry;
*_type = make_mode(vol, entry);
bi2:
diri_free(&iter);
@ -1059,12 +1065,12 @@ bi:
status_t
dosfs_walk(void *_vol, void *_dir, const char *file, ino_t *_vnid, int *_type)
dosfs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *_vnid)
{
/* Starting at the base, find file in the subdir, and return path
string and vnode id of file. */
nspace *vol = (nspace*)_vol;
vnode *dir = (vnode*)_dir;
nspace *vol = (nspace*)_vol->private_volume;
vnode *dir = (vnode*)_dir->private_node;
vnode *vnode = NULL;
status_t result = ENOENT;
@ -1092,11 +1098,11 @@ dosfs_walk(void *_vol, void *_dir, const char *file, ino_t *_vnid, int *_type)
status_t
dosfs_access(void *_vol, void *_node, int mode)
dosfs_access(fs_volume *_vol, fs_vnode *_node, int mode)
{
status_t result = B_OK;
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
LOCK_VOL(vol);
@ -1128,7 +1134,7 @@ dosfs_access(void *_vol, void *_node, int mode)
status_t
dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize)
dosfs_readlink(fs_volume *_vol, fs_vnode *_node, char *buf, size_t *bufsize)
{
TOUCH(_vol); TOUCH(_node); TOUCH(buf); TOUCH(bufsize);
@ -1140,10 +1146,10 @@ dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize)
status_t
dosfs_opendir(void *_vol, void *_node, void **_cookie)
dosfs_opendir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
{
nspace *vol = (nspace*)_vol;
vnode *node = (vnode*)_node;
nspace *vol = (nspace*)_vol->private_volume;
vnode *node = (vnode*)_node->private_node;
dircookie *cookie = NULL;
int result;
@ -1198,12 +1204,12 @@ bi:
status_t
dosfs_readdir(void *_vol, void *_dir, void *_cookie,
dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
struct dirent *entry, size_t bufsize, uint32 *num)
{
int result = ENOENT;
nspace* vol = (nspace*)_vol;
vnode *dir = (vnode *)_dir;
nspace* vol = (nspace*)_vol->private_volume;
vnode *dir = (vnode *)_dir->private_node;
dircookie* cookie = (dircookie*)_cookie;
struct diri diri;
@ -1279,10 +1285,10 @@ bi:
status_t
dosfs_rewinddir(void *_vol, void *_node, void* _cookie)
dosfs_rewinddir(fs_volume *_vol, fs_vnode *_node, void* _cookie)
{
nspace *vol = _vol;
vnode *node = _node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
dircookie *cookie = (dircookie*)_cookie;
LOCK_VOL(vol);
@ -1305,7 +1311,7 @@ dosfs_rewinddir(void *_vol, void *_node, void* _cookie)
status_t
dosfs_closedir(void *_vol, void *_node, void *_cookie)
dosfs_closedir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
TOUCH(_vol); TOUCH(_node); TOUCH(_cookie);
@ -1316,15 +1322,16 @@ dosfs_closedir(void *_vol, void *_node, void *_cookie)
status_t
dosfs_free_dircookie(void *_vol, void *node, void *_cookie)
dosfs_free_dircookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
nspace *vol = _vol;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
dircookie *cookie = _cookie;
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_free_dircookie")
|| check_vnode_magic((vnode *)node, "dosfs_free_dircookie")
|| check_vnode_magic(node, "dosfs_free_dircookie")
|| check_dircookie_magic((dircookie *)cookie, "dosfs_free_dircookie")) {
UNLOCK_VOL(vol);
return EINVAL;
@ -1336,7 +1343,7 @@ dosfs_free_dircookie(void *_vol, void *node, void *_cookie)
return EINVAL;
}
DPRINTF(0, ("dosfs_free_dircookie (vnode id %Lx)\n", ((vnode*)node)->vnid));
DPRINTF(0, ("dosfs_free_dircookie (vnode id %Lx)\n", node->vnid));
cookie->magic = ~DIRCOOKIE_MAGIC;
free(cookie);

View File

@ -21,16 +21,19 @@ status_t create_volume_label(nspace *vol, const char name[11], uint32 *index);
status_t create_dir_entry(nspace *vol, vnode *dir, vnode *node,
const char *name, uint32 *ns, uint32 *ne);
status_t dosfs_read_vnode(void *_vol, ino_t vnid, void **node, bool reenter);
status_t dosfs_walk(void *_vol, void *_dir, const char *file,
ino_t *_vnid, int *_type);
status_t dosfs_access(void *_vol, void *_node, int mode);
status_t dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize);
status_t dosfs_opendir(void *_vol, void *_node, void **cookie);
status_t dosfs_readdir(void *_vol, void *_node, void *cookie,
status_t dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node,
int *_type, uint32 *_flags, bool reenter);
status_t dosfs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file,
ino_t *_vnid);
status_t dosfs_access(fs_volume *_vol, fs_vnode *_node, int mode);
status_t dosfs_readlink(fs_volume *_vol, fs_vnode *_node, char *buf,
size_t *bufsize);
status_t dosfs_opendir(fs_volume *_vol, fs_vnode *_node, void **cookie);
status_t dosfs_readdir(fs_volume *_vol, fs_vnode *_node, void *cookie,
struct dirent *buf, size_t bufsize, uint32 *num);
status_t dosfs_rewinddir(void *_vol, void *_node, void *cookie);
status_t dosfs_closedir(void *_vol, void *_node, void *cookie);
status_t dosfs_free_dircookie(void *_vol, void *_node, void *cookie);
status_t dosfs_rewinddir(fs_volume *_vol, fs_vnode *_node, void *cookie);
status_t dosfs_closedir(fs_volume *_vol, fs_vnode *_node, void *cookie);
status_t dosfs_free_dircookie(fs_volume *_vol, fs_vnode *_node,
void *cookie);
#endif

View File

@ -49,7 +49,7 @@ static status_t get_fsinfo(nspace *vol, uint32 *free_count, uint32 *last_allocat
int32 instances = 0;
static int
debug_fat(int argc, char **argv)
debug_fat_nspace(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++) {
@ -154,8 +154,8 @@ lock_removable_device(int fd, bool state)
static status_t
mount_fat_disk(const char *path, dev_t nsid, const int flags, nspace** newVol,
int fs_flags, int op_sync_mode)
mount_fat_disk(const char *path, fs_volume *_vol, const int flags,
nspace** newVol, int fs_flags, int op_sync_mode)
{
nspace *vol = NULL;
uint8 buf[512];
@ -432,7 +432,8 @@ mount_fat_disk(const char *path, dev_t nsid, const int flags, nspace** newVol,
// now we are convinced of the drive's validity
vol->id = nsid;
vol->volume = _vol;
vol->id = _vol->id;
strncpy(vol->device,path,256);
// this will be updated later if fsinfo exists
@ -679,8 +680,8 @@ dosfs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
static status_t
dosfs_mount(dev_t nsid, const char *device, uint32 flags,
const char *args, void **_data, ino_t *_rootID)
dosfs_mount(fs_volume *_vol, const char *device, uint32 flags,
const char *args, ino_t *_rootID)
{
int result;
nspace *vol;
@ -722,22 +723,20 @@ dosfs_mount(dev_t nsid, const char *device, uint32 flags,
flags |= 1;
#endif
if (_data == NULL) {
dprintf("dosfs_mount passed NULL data pointer\n");
return EINVAL;
}
// Try and mount volume as a FAT volume
if ((result = mount_fat_disk(device, nsid, flags, &vol, fs_flags, op_sync_mode)) == B_NO_ERROR) {
if ((result = mount_fat_disk(device, _vol, flags, &vol, fs_flags,
op_sync_mode)) == B_NO_ERROR) {
char name[32];
if (check_nspace_magic(vol, "dosfs_mount")) return EINVAL;
*_rootID = vol->root_vnode.vnid;
*_data = (void*)vol;
_vol->private_volume = (void *)vol;
_vol->ops = &gFATVolumeOps;
// You MUST do this. Create the vnode for the root.
result = publish_vnode(nsid, *_rootID, (void*)&(vol->root_vnode));
result = publish_vnode(_vol, *_rootID, (void*)&(vol->root_vnode),
&gFATVnodeOps, make_mode(vol, &vol->root_vnode), 0);
if (result != B_NO_ERROR) {
dprintf("error creating new vnode (%s)\n", strerror(result));
goto error;
@ -749,10 +748,8 @@ dosfs_mount(dev_t nsid, const char *device, uint32 flags,
}
#if DEBUG
load_driver_symbols("fat");
if (atomic_add(&instances, 1) == 0) {
add_debugger_command("fat", debug_fat, "dump a fat nspace structure");
add_debugger_command("fat", debug_fat_nspace, "dump a fat nspace structure");
add_debugger_command("dvnode", debug_dvnode, "dump a fat vnode structure");
add_debugger_command("dfvnid", debug_dfvnid, "find a vnid in the vnid cache");
add_debugger_command("dfloc", debug_dfloc, "find a loc in the vnid cache");
@ -835,11 +832,11 @@ static status_t get_fsinfo(nspace *vol, uint32 *free_count, uint32 *last_allocat
static status_t
dosfs_unmount(void *_vol)
dosfs_unmount(fs_volume *_vol)
{
int result = B_NO_ERROR;
nspace* vol = (nspace*)_vol;
nspace* vol = (nspace*)_vol->private_volume;
LOCK_VOL(vol);
@ -853,12 +850,12 @@ dosfs_unmount(void *_vol)
update_fsinfo(vol);
// Unlike in BeOS, we need to put the reference to our root node ourselves
put_vnode(vol->id, vol->root_vnode.vnid);
put_vnode(_vol, vol->root_vnode.vnid);
block_cache_delete(vol->fBlockCache, true);
#if DEBUG
if (atomic_add(&instances, -1) == 1) {
remove_debugger_command("fat", debug_fat);
remove_debugger_command("fat", debug_fat_nspace);
remove_debugger_command("dvnode", debug_dvnode);
remove_debugger_command("dfvnid", debug_dfvnid);
remove_debugger_command("dfloc", debug_dfloc);
@ -885,9 +882,9 @@ dosfs_unmount(void *_vol)
// dosfs_read_fs_stat - Fill in fs_info struct for device.
static status_t
dosfs_read_fs_stat(void *_vol, struct fs_info * fss)
dosfs_read_fs_stat(fs_volume *_vol, struct fs_info * fss)
{
nspace* vol = (nspace*)_vol;
nspace* vol = (nspace*)_vol->private_volume;
int i;
LOCK_VOL(vol);
@ -943,10 +940,10 @@ dosfs_read_fs_stat(void *_vol, struct fs_info * fss)
}
static status_t
dosfs_write_fs_stat(void *_vol, const struct fs_info * fss, uint32 mask)
dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
{
status_t result = B_ERROR;
nspace* vol = (nspace*)_vol;
nspace* vol = (nspace*)_vol->private_volume;
LOCK_VOL(vol);
@ -1039,12 +1036,12 @@ bi: UNLOCK_VOL(vol);
static status_t
dosfs_ioctl(void *_vol, void *_node, void *cookie, ulong code,
dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, ulong code,
void *buf, size_t len)
{
status_t result = B_OK;
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
TOUCH(cookie); TOUCH(buf); TOUCH(len);
@ -1148,9 +1145,9 @@ _dosfs_sync(nspace *vol)
static status_t
dosfs_sync(void *_vol)
dosfs_sync(fs_volume *_vol)
{
nspace *vol = (nspace *)_vol;
nspace *vol = (nspace *)_vol->private_volume;
status_t err;
DPRINTF(0, ("dosfs_sync called on volume %lx\n", vol->id));
@ -1164,10 +1161,10 @@ dosfs_sync(void *_vol)
static status_t
dosfs_fsync(void *_vol, void *_node)
dosfs_fsync(fs_volume *_vol, fs_vnode *_node)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
status_t err = B_OK;
LOCK_VOL(vol);
@ -1203,32 +1200,37 @@ dos_std_ops(int32 op, ...)
}
static file_system_module_info sFATFileSystem = {
{
"file_systems/fat" B_CURRENT_FS_API_VERSION,
0,
dos_std_ops,
},
"FAT32 File System",
0, // DDM flags
// scanning
dosfs_identify_partition,
dosfs_scan_partition,
dosfs_free_identify_partition_cookie,
NULL, // free_partition_content_cookie()
&dosfs_mount,
fs_volume_ops gFATVolumeOps = {
&dosfs_unmount,
&dosfs_read_fs_stat,
&dosfs_write_fs_stat,
&dosfs_sync,
&dosfs_read_vnode,
/* index directory & index operations */
NULL, //&fs_open_index_dir,
NULL, //&fs_close_index_dir,
NULL, //&fs_free_index_dir_cookie,
NULL, //&fs_read_index_dir,
NULL, //&fs_rewind_index_dir,
NULL, //&fs_create_index,
NULL, //&fs_remove_index,
NULL, //&fs_stat_index,
/* query operations */
NULL, //&fs_open_query,
NULL, //&fs_close_query,
NULL, //&fs_free_query_cookie,
NULL, //&fs_read_query,
NULL, //&fs_rewind_query,
};
fs_vnode_ops gFATVnodeOps = {
/* vnode operations */
&dosfs_walk,
&dosfs_get_vnode_name,
&dosfs_read_vnode,
&dosfs_release_vnode,
&dosfs_remove_vnode,
@ -1292,24 +1294,26 @@ static file_system_module_info sFATFileSystem = {
NULL, //&fs_write_attr_stat,
NULL, //&fs_rename_attr,
NULL, //&fs_remove_attr,
};
/* index directory & index operations */
NULL, //&fs_open_index_dir,
NULL, //&fs_close_index_dir,
NULL, //&fs_free_index_dir_cookie,
NULL, //&fs_read_index_dir,
NULL, //&fs_rewind_index_dir,
NULL, //&fs_create_index,
NULL, //&fs_remove_index,
NULL, //&fs_stat_index,
static file_system_module_info sFATFileSystem = {
{
"file_systems/fat" B_CURRENT_FS_API_VERSION,
0,
dos_std_ops,
},
/* query operations */
NULL, //&fs_open_query,
NULL, //&fs_close_query,
NULL, //&fs_free_query_cookie,
NULL, //&fs_read_query,
NULL, //&fs_rewind_query,
"FAT32 File System",
0, // DDM flags
// scanning
dosfs_identify_partition,
dosfs_scan_partition,
dosfs_free_identify_partition_cookie,
NULL, // free_partition_content_cookie()
&dosfs_mount,
};
module_info *modules[] = {

View File

@ -116,7 +116,8 @@ struct vcache_entry;
typedef struct _nspace
{
uint32 magic;
dev_t id; // ID passed in to fs_mount
fs_volume *volume; // fs_volume passed in to fs_mount
dev_t id;
int fd; // File descriptor
char device[256];
uint32 flags; // see <fcntl.be.h> for modes
@ -197,6 +198,9 @@ int check_nspace_magic(struct _nspace *t, char *funcname);
#define TOUCH(x) ((void)(x))
extern fs_vnode_ops gFATVnodeOps;
extern fs_volume_ops gFATVolumeOps;
/* debug levels */
extern int debug_attr, debug_dir, debug_dlist, debug_dosfs, debug_encodings,
debug_fat, debug_file, debug_iter, debug_vcache;

View File

@ -47,10 +47,26 @@ typedef struct filecookie
static CHECK_MAGIC(filecookie,struct filecookie, FILECOOKIE_MAGIC)
status_t
dosfs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize)
mode_t
make_mode(nspace *volume, vnode *node)
{
vnode *node = (vnode*)_node;
mode_t result = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
if (node->mode & FAT_SUBDIR) {
result &= ~S_IFREG;
result |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
}
if ((volume->flags & B_FS_IS_READONLY) || (node->mode & FAT_READ_ONLY))
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
return result;
}
status_t
dosfs_get_vnode_name(fs_volume *_ns, fs_vnode *_node, char *buffer,
size_t bufferSize)
{
vnode *node = (vnode*)_node->private_node;
strlcpy(buffer, node->filename, bufferSize);
return B_OK;
}
@ -105,7 +121,11 @@ status_t write_vnode_entry(nspace *vol, vnode *node)
diri_mark_dirty(&diri);
diri_free(&diri);
notify_listener(B_STAT_CHANGED, vol->id, 0, 0, node->vnid, NULL);
// TODO: figure out which stats have actually changed
notify_stat_changed(vol->id, node->vnid, B_STAT_MODE | B_STAT_UID
| B_STAT_GID | B_STAT_SIZE | B_STAT_ACCESS_TIME
| B_STAT_MODIFICATION_TIME | B_STAT_CREATION_TIME
| B_STAT_CHANGE_TIME);
return B_OK;
}
@ -114,10 +134,10 @@ status_t write_vnode_entry(nspace *vol, vnode *node)
// called when fs is done with vnode
// after close, etc. free vnode resources here
status_t
dosfs_release_vnode(void *_vol, void *_node, bool reenter)
dosfs_release_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
TOUCH(reenter);
@ -126,7 +146,7 @@ dosfs_release_vnode(void *_vol, void *_node, bool reenter)
return EINVAL;
}
DPRINTF(0, ("dosfs_write_vnode (ino_t %Lx)\n", ((vnode *)_node)->vnid));
DPRINTF(0, ("dosfs_write_vnode (ino_t %Lx)\n", node->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
LOCK_VOL(vol);
@ -152,10 +172,10 @@ dosfs_release_vnode(void *_vol, void *_node, bool reenter)
status_t
dosfs_rstat(void *_vol, void *_node, struct stat *st)
dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st)
{
nspace *vol = (nspace*)_vol;
vnode *node = (vnode*)_node;
nspace *vol = (nspace*)_vol->private_volume;
vnode *node = (vnode*)_node->private_node;
LOCK_VOL(vol);
@ -169,13 +189,7 @@ dosfs_rstat(void *_vol, void *_node, struct stat *st)
st->st_dev = vol->id;
st->st_ino = node->vnid;
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
if (node->mode & FAT_SUBDIR) {
st->st_mode &= ~S_IFREG;
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
}
if ((vol->flags & B_FS_IS_READONLY) || (node->mode & FAT_READ_ONLY))
st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
st->st_mode = make_mode(vol, node);
st->st_nlink = 1;
st->st_uid = 0;
@ -191,11 +205,12 @@ dosfs_rstat(void *_vol, void *_node, struct stat *st)
status_t
dosfs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
dosfs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st,
uint32 mask)
{
int err = B_OK;
nspace *vol = (nspace*)_vol;
vnode *node = (vnode*)_node;
nspace *vol = (nspace*)_vol->private_volume;
vnode *node = (vnode*)_node->private_node;
bool dirty = false;
LOCK_VOL(vol);
@ -258,7 +273,6 @@ dosfs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
if (dirty) {
write_vnode_entry(vol, node);
notify_listener(B_STAT_CHANGED, vol->id, 0, 0, node->vnid, NULL);
if (vol->fs_flags & FS_FLAGS_OP_SYNC) {
// sync the filesystem
@ -276,11 +290,11 @@ dosfs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
status_t
dosfs_open(void *_vol, void *_node, int omode, void **_cookie)
dosfs_open(fs_volume *_vol, fs_vnode *_node, int omode, void **_cookie)
{
status_t result = EINVAL;
nspace *vol = (nspace *)_vol;
vnode* node = (vnode*)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode* node = (vnode*)_node->private_node;
filecookie *cookie;
*_cookie = NULL;
@ -349,11 +363,11 @@ error:
status_t
dosfs_read(void *_vol, void *_node, void *_cookie, off_t pos,
dosfs_read(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
void *buf, size_t *len)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
filecookie *cookie = (filecookie *)_cookie;
//uint8 *buffer;
//struct csi iter;
@ -505,11 +519,11 @@ bi:
status_t
dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
const void *buf, size_t *len)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
filecookie *cookie = (filecookie *)_cookie;
//uint8 *buffer;
//struct csi iter;
@ -706,10 +720,10 @@ bi:
status_t
dosfs_close(void *_vol, void *_node, void *_cookie)
dosfs_close(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
LOCK_VOL(vol);
@ -720,7 +734,7 @@ dosfs_close(void *_vol, void *_node, void *_cookie)
return EINVAL;
}
DPRINTF(0, ("dosfs_close (vnode id %Lx)\n", ((vnode *)_node)->vnid));
DPRINTF(0, ("dosfs_close (vnode id %Lx)\n", node->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
_dosfs_sync(vol);
@ -734,10 +748,10 @@ dosfs_close(void *_vol, void *_node, void *_cookie)
status_t
dosfs_free_cookie(void *_vol, void *_node, void *_cookie)
dosfs_free_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
nspace *vol = _vol;
vnode *node = _node;
nspace *vol = _vol->private_volume;
vnode *node = _node->private_node;
filecookie *cookie = _cookie;
LOCK_VOL(vol);
@ -760,11 +774,11 @@ dosfs_free_cookie(void *_vol, void *_node, void *_cookie)
status_t
dosfs_create(void *_vol, void *_dir, const char *name, int omode,
dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
int perms, void **_cookie, ino_t *vnid)
{
nspace *vol = (nspace *)_vol;
vnode *dir = (vnode *)_dir, *file;
nspace *vol = (nspace *)_vol->private_volume;
vnode *dir = (vnode *)_dir->private_node, *file;
filecookie *cookie;
status_t result = EINVAL;
bool dups_exist;
@ -815,21 +829,21 @@ dosfs_create(void *_vol, void *_dir, const char *name, int omode,
if (result == B_OK) {
if (omode & O_EXCL) {
dprintf("exclusive dosfs_create called on existing file %s\n", name);
put_vnode(vol->id, file->vnid);
put_vnode(_vol, file->vnid);
result = EEXIST;
goto bi;
}
if (file->mode & FAT_SUBDIR) {
dprintf("can't dosfs_create over an existing subdirectory\n");
put_vnode(vol->id, file->vnid);
put_vnode(_vol, file->vnid);
result = EPERM;
goto bi;
}
if (file->disk_image) {
dprintf("can't dosfs_create over a disk image\n");
put_vnode(vol->id, file->vnid);
put_vnode(_vol, file->vnid);
result = EPERM;
goto bi;
}
@ -875,7 +889,7 @@ dosfs_create(void *_vol, void *_dir, const char *name, int omode,
*vnid = dummy.vnid;
dummy.magic = ~VNODE_MAGIC;
result = get_vnode(vol->id, *vnid, (void **)&file);
result = get_vnode(_vol, *vnid, (void **)&file);
if (result < B_OK) {
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
@ -892,7 +906,7 @@ dosfs_create(void *_vol, void *_dir, const char *name, int omode,
cookie->ccache.cluster = file->cluster;
*_cookie = cookie;
notify_listener(B_ENTRY_CREATED, vol->id, dir->vnid, 0, *vnid, name);
notify_entry_created(vol->id, dir->vnid, name, *vnid);
result = 0;
@ -910,10 +924,11 @@ bi: if (result != B_OK) free(cookie);
status_t
dosfs_mkdir(void *_vol, void *_dir, const char *name, int perms, ino_t *_vnid)
dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms,
ino_t *_vnid)
{
nspace *vol = (nspace *)_vol;
vnode *dir = (vnode *)_dir, dummy;
nspace *vol = (nspace *)_vol->private_volume;
vnode *dir = (vnode *)_dir->private_node, dummy;
status_t result = EINVAL;
struct csi csi;
uchar *buffer;
@ -1037,7 +1052,7 @@ dosfs_mkdir(void *_vol, void *_dir, const char *name, int perms, ino_t *_vnid)
free(buffer);
notify_listener(B_ENTRY_CREATED, vol->id, dir->vnid, 0, dummy.vnid, name);
notify_entry_created(vol->id, dir->vnid, name, dummy.vnid);
result = B_OK;
@ -1062,12 +1077,14 @@ bi: dummy.magic = ~VNODE_MAGIC;
status_t
dosfs_rename(void *_vol, void *_odir, const char *oldname,
void *_ndir, const char *newname)
dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
fs_vnode *_ndir, const char *newname)
{
status_t result = EINVAL;
nspace *vol = (nspace *)_vol;
vnode *odir = (vnode *)_odir, *ndir = (vnode *)_ndir, *file, *file2;
nspace *vol = (nspace *)_vol->private_volume;
vnode *odir = (vnode *)_odir->private_node;
vnode *ndir = (vnode *)_ndir->private_node;
vnode *file, *file2;
uint32 ns, ne;
bool dups_exist;
bool dirty = false;
@ -1137,11 +1154,11 @@ dosfs_rename(void *_vol, void *_odir, const char *oldname,
if (vnid == vol->root_vnode.vnid)
break;
result = get_vnode(vol->id, vnid, (void **)&dir);
result = get_vnode(_vol, vnid, (void **)&dir);
if (result < B_OK)
goto bi1;
parent = dir->dir_vnid;
put_vnode(vol->id, vnid);
put_vnode(_vol, vnid);
vnid = parent;
}
}
@ -1163,7 +1180,7 @@ dosfs_rename(void *_vol, void *_odir, const char *oldname,
ns = file2->sindex; ne = file2->eindex;
// let others know the old file is gone
notify_listener(B_ENTRY_REMOVED, vol->id, ndir->vnid, 0, file2->vnid, NULL);
notify_entry_removed(vol->id, ndir->vnid, oldname, file2->vnid);
// Make sure this vnode 1) is in the vcache and 2) no longer has a
// location associated with it. See discussion in dosfs_unlink()
@ -1173,8 +1190,8 @@ dosfs_rename(void *_vol, void *_odir, const char *oldname,
// note we don't have to lock the file because the fat chain doesn't
// get wiped from the disk until dosfs_remove_vnode() is called; we'll
// have a phantom chain in effect until the last file is closed.
remove_vnode(vol->id, file2->vnid); // must be done in this order
put_vnode(vol->id, file2->vnid);
remove_vnode(_vol, file2->vnid); // must be done in this order
put_vnode(_vol, file2->vnid);
dirty = true;
@ -1267,20 +1284,23 @@ dosfs_rename(void *_vol, void *_odir, const char *oldname,
if (file->filename) strcpy(file->filename, newname);
#endif
notify_listener(B_ENTRY_MOVED, vol->id, odir->vnid, ndir->vnid, file->vnid, newname);
notify_entry_moved(vol->id, odir->vnid, oldname, ndir->vnid, newname,
file->vnid);
// update MIME information
if(!(file->mode & FAT_SUBDIR)) {
set_mime_type(file, newname);
notify_listener(B_ATTR_CHANGED, vol->id, 0, 0, file->vnid, "BEOS:TYPE");
notify_attribute_changed(vol->id, file->vnid, "BEOS:TYPE",
B_ATTR_CHANGED);
}
result = 0;
bi2:
if (result != B_OK) put_vnode(vol->id, file2->vnid);
if (result != B_OK)
put_vnode(_vol, file2->vnid);
bi1:
put_vnode(vol->id, file->vnid);
put_vnode(_vol, file->vnid);
bi:
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && dirty)
_dosfs_sync(vol);
@ -1291,10 +1311,10 @@ bi:
status_t
dosfs_remove_vnode(void *_vol, void *_node, bool reenter)
dosfs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
{
nspace *vol = (nspace *)_vol;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
if (!reenter) { LOCK_VOL(vol); }
@ -1345,11 +1365,11 @@ dosfs_remove_vnode(void *_vol, void *_node, bool reenter)
// get rid of node or directory
static status_t
do_unlink(void *_vol, void *_dir, const char *name, bool is_file)
do_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name, bool is_file)
{
status_t result = EINVAL;
nspace *vol = (nspace *)_vol;
vnode *dir = (vnode *)_dir, *file;
nspace *vol = (nspace *)_vol->private_volume;
vnode *dir = (vnode *)_dir->private_node, *file;
ino_t vnid;
if (!strcmp(name, "."))
@ -1426,7 +1446,7 @@ do_unlink(void *_vol, void *_dir, const char *name, bool is_file)
// shrink the parent directory (errors here are not disastrous)
compact_directory(vol, dir);
notify_listener(B_ENTRY_REMOVED, vol->id, dir->vnid, 0, file->vnid, NULL);
notify_entry_removed(vol->id, dir->vnid, name, file->vnid);
/* Set the loc to a unique value. This effectively removes it from the
* vcache without releasing its vnid for reuse. It also nicely reserves
@ -1438,15 +1458,17 @@ do_unlink(void *_vol, void *_dir, const char *name, bool is_file)
// fsil doesn't call dosfs_write_vnode for us, so we have to free the
// vnode manually here.
remove_vnode(vol->id, file->vnid);
remove_vnode(_vol, file->vnid);
result = 0;
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi1:put_vnode(vol->id, vnid); // get 1 free
bi: UNLOCK_VOL(vol);
bi1:
put_vnode(_vol, vnid); // get 1 free
bi:
UNLOCK_VOL(vol);
if (result != B_OK) DPRINTF(0, ("do_unlink (%s)\n", strerror(result)));
@ -1454,7 +1476,7 @@ bi: UNLOCK_VOL(vol);
}
status_t
dosfs_unlink(void *vol, void *dir, const char *name)
dosfs_unlink(fs_volume *vol, fs_vnode *dir, const char *name)
{
DPRINTF(1, ("dosfs_unlink called\n"));
@ -1463,7 +1485,7 @@ dosfs_unlink(void *vol, void *dir, const char *name)
status_t
dosfs_rmdir(void *vol, void *dir, const char *name)
dosfs_rmdir(fs_volume *vol, fs_vnode *dir, const char *name)
{
DPRINTF(1, ("dosfs_rmdir called\n"));
@ -1472,7 +1494,7 @@ dosfs_rmdir(void *vol, void *dir, const char *name)
bool
dosfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie _cookie)
dosfs_can_page(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
// ToDo: we're obviously not even asked...
return false;
@ -1480,11 +1502,12 @@ dosfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie _cookie)
status_t
dosfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
dosfs_read_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
bool reenter)
{
nspace *vol = (nspace *)_fs;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
uint32 vecIndex = 0;
size_t vecOffset = 0;
size_t bytesLeft = *_numBytes;
@ -1532,11 +1555,12 @@ dosfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
status_t
dosfs_write_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
dosfs_write_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
bool reenter)
{
nspace *vol = (nspace *)_fs;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
uint32 vecIndex = 0;
size_t vecOffset = 0;
size_t bytesLeft = *_numBytes;
@ -1584,11 +1608,11 @@ dosfs_write_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
status_t
dosfs_get_file_map(void *_fs, void *_node, off_t pos, size_t len,
dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t pos, size_t len,
struct file_io_vec *vecs, size_t *_count)
{
nspace *vol = (nspace *)_fs;
vnode *node = (vnode *)_node;
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
struct csi iter;
int result = B_OK;
size_t bytes_read = 0;

View File

@ -5,34 +5,42 @@
#ifndef _DOSFS_FILE_H_
#define _DOSFS_FILE_H_
mode_t make_mode(nspace *volume, vnode *node);
status_t write_vnode_entry(nspace *vol, vnode *node);
status_t dosfs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize);
status_t dosfs_release_vnode(void *_vol, void *_node, bool reenter);
status_t dosfs_rstat(void *_vol, void *_node, struct stat *st);
status_t dosfs_open(void *_vol, void *_node, int omode, void **cookie);
status_t dosfs_read(void *_vol, void *_node, void *cookie, off_t pos,
void *buf, size_t *len);
status_t dosfs_free_cookie(void *vol, void *node, void *cookie);
status_t dosfs_close(void *vol, void *node, void *cookie);
status_t dosfs_get_vnode_name(fs_volume *_vol, fs_vnode *_node,
char *buffer, size_t bufferSize);
status_t dosfs_release_vnode(fs_volume *_vol, fs_vnode *_node,
bool reenter);
status_t dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st);
status_t dosfs_open(fs_volume *_vol, fs_vnode *_node, int omode,
void **cookie);
status_t dosfs_read(fs_volume *_vol, fs_vnode *_node, void *cookie,
off_t pos, void *buf, size_t *len);
status_t dosfs_free_cookie(fs_volume *vol, fs_vnode *node, void *cookie);
status_t dosfs_close(fs_volume *vol, fs_vnode *node, void *cookie);
status_t dosfs_remove_vnode(void *vol, void *node, bool reenter);
status_t dosfs_create(void *vol, void *dir, const char *name,
status_t dosfs_remove_vnode(fs_volume *vol, fs_vnode *node, bool reenter);
status_t dosfs_create(fs_volume *vol, fs_vnode *dir, const char *name,
int omode, int perms, void **cookie, ino_t *vnid);
status_t dosfs_mkdir(void *vol, void *dir, const char *name, int perms, ino_t *_vnid);
status_t dosfs_rename(void *vol, void *olddir, const char *oldname,
void *newdir, const char *newname);
status_t dosfs_unlink(void *vol, void *dir, const char *name);
status_t dosfs_rmdir(void *vol, void *dir, const char *name);
status_t dosfs_wstat(void *vol, void *node, const struct stat *st, uint32 mask);
status_t dosfs_write(void *vol, void *node, void *cookie, off_t pos,
const void *buf, size_t *len);
status_t dosfs_get_file_map(void *fs, void *node, off_t pos, size_t reqLen,
struct file_io_vec *vecs, size_t *_count);
bool dosfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie _cookie);
status_t dosfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter);
status_t dosfs_write_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter);
status_t dosfs_mkdir(fs_volume *vol, fs_vnode *dir, const char *name,
int perms, ino_t *_vnid);
status_t dosfs_rename(fs_volume *vol, fs_vnode *olddir, const char *oldname,
fs_vnode *newdir, const char *newname);
status_t dosfs_unlink(fs_volume *vol, fs_vnode *dir, const char *name);
status_t dosfs_rmdir(fs_volume *vol, fs_vnode *dir, const char *name);
status_t dosfs_wstat(fs_volume *vol, fs_vnode *node, const struct stat *st,
uint32 mask);
status_t dosfs_write(fs_volume *vol, fs_vnode *node, void *cookie,
off_t pos, const void *buf, size_t *len);
status_t dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t pos,
size_t reqLen, struct file_io_vec *vecs, size_t *_count);
bool dosfs_can_page(fs_volume *_vol, fs_vnode *_node, void *_cookie);
status_t dosfs_read_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
bool reenter);
status_t dosfs_write_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
bool reenter);
#endif