initial port of dosfs to Haiku, read is working, write not yet
please use carefully! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18655 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
49811b3ae3
commit
f50c1ececf
@ -1,5 +1,9 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel file_systems dos ;
|
||||
|
||||
UsePrivateHeaders kernel ;
|
||||
|
||||
SubDirCcFlags -DTRACK_FILENAME ;
|
||||
|
||||
KernelAddon dos : kernel file_systems :
|
||||
attr.c
|
||||
dir.c
|
||||
|
@ -18,13 +18,12 @@
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <lock.h>
|
||||
|
||||
#include "dosfs.h"
|
||||
#include "attr.h"
|
||||
#include "mime_table.h"
|
||||
|
||||
int32 kBeOSTypeCookie = 0x1234;
|
||||
|
||||
#define DPRINTF(a,b) if (debug_attr > (a)) dprintf b
|
||||
|
||||
status_t set_mime_type(vnode *node, const char *filename)
|
||||
@ -56,7 +55,9 @@ status_t set_mime_type(vnode *node, const char *filename)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
int dosfs_open_attrdir(void *_vol, void *_node, void **_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_open_attrdir(void *_vol, void *_node, void **_cookie)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
|
||||
@ -82,7 +83,8 @@ int dosfs_open_attrdir(void *_vol, void *_node, void **_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_close_attrdir(void *_vol, void *_node, void *_cookie)
|
||||
status_t
|
||||
dosfs_close_attrdir(void *_vol, void *_node, void *_cookie)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
|
||||
@ -104,7 +106,9 @@ int dosfs_close_attrdir(void *_vol, void *_node, void *_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_free_attrcookie(void *_vol, void *_node, void *_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_free_attrdir_cookie(void *_vol, void *_node, void *_cookie)
|
||||
{
|
||||
TOUCH(_vol); TOUCH(_node);
|
||||
|
||||
@ -121,7 +125,9 @@ int dosfs_free_attrcookie(void *_vol, void *_node, void *_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie)
|
||||
{
|
||||
TOUCH(_vol); TOUCH(_node);
|
||||
|
||||
@ -136,8 +142,10 @@ int dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_read_attrdir(void *_vol, void *_node, void *_cookie, long *num,
|
||||
struct dirent *entry, size_t bufsize)
|
||||
|
||||
status_t
|
||||
dosfs_read_attrdir(void *_vol, void *_node, void *_cookie,
|
||||
struct dirent *entry, size_t bufsize, uint32 *num)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
@ -173,20 +181,60 @@ int dosfs_read_attrdir(void *_vol, void *_node, void *_cookie, long *num,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_stat_attr(void *_vol, void *_node, const char *name, struct attr_info *buf)
|
||||
|
||||
status_t
|
||||
dosfs_open_attr(void *_vol, void *_node, const char *name, int openMode,
|
||||
fs_cookie *_cookie)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
|
||||
DPRINTF(0, ("dosfs_stat_attr (%s)\n", name));
|
||||
|
||||
if (strcmp(name, "BEOS:TYPE"))
|
||||
return ENOENT;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
if (node->mime == NULL) {
|
||||
UNLOCK_VOL(vol);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
UNLOCK_VOL(vol);
|
||||
|
||||
*_cookie = &kBeOSTypeCookie;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
dosfs_close_attr(void *_vol, void *_node, fs_cookie cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
dosfs_free_attr_cookie(void *_vol, void *_node, fs_cookie cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
dosfs_read_attr_stat(void *_vol, void *_node, fs_cookie _cookie, struct stat *stat)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
|
||||
DPRINTF(0, ("dosfs_read_attr_stat\n"));
|
||||
|
||||
if (_cookie != &kBeOSTypeCookie)
|
||||
return ENOENT;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
if (check_nspace_magic(vol, "dosfs_read_attr") ||
|
||||
check_vnode_magic(node, "dosfs_read_attr")) {
|
||||
if (check_nspace_magic(vol, "dosfs_read_attr_stat") ||
|
||||
check_vnode_magic(node, "dosfs_read_attr_stat")) {
|
||||
UNLOCK_VOL(vol);
|
||||
return EINVAL;
|
||||
}
|
||||
@ -196,27 +244,26 @@ int dosfs_stat_attr(void *_vol, void *_node, const char *name, struct attr_info
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
buf->type = MIME_STRING_TYPE;
|
||||
buf->size = strlen(node->mime) + 1;
|
||||
stat->st_type = MIME_STRING_TYPE;
|
||||
stat->st_size = strlen(node->mime) + 1;
|
||||
|
||||
UNLOCK_VOL(vol);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_read_attr(void *_vol, void *_node, const char *name, int type, void *buf,
|
||||
size_t *len, off_t pos)
|
||||
|
||||
status_t
|
||||
dosfs_read_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
|
||||
void *buffer, size_t *_length)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
|
||||
DPRINTF(0, ("dosfs_read_attr (%s)\n", name));
|
||||
DPRINTF(0, ("dosfs_read_attr\n"));
|
||||
|
||||
if (strcmp(name, "BEOS:TYPE"))
|
||||
if (_cookie != &kBeOSTypeCookie)
|
||||
return ENOENT;
|
||||
|
||||
if (type != MIME_STRING_TYPE)
|
||||
return ENOENT;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
if (check_nspace_magic(vol, "dosfs_read_attr") ||
|
||||
@ -235,9 +282,9 @@ int dosfs_read_attr(void *_vol, void *_node, const char *name, int type, void *b
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
strncpy(buf, node->mime + pos, *len - 1);
|
||||
((char *)buf)[*len - 1] = 0;
|
||||
*len = strlen(buf) + 1;
|
||||
strncpy(buffer, node->mime + pos, *_length - 1);
|
||||
((char *)buffer)[*_length - 1] = 0;
|
||||
*_length = strlen(buffer) + 1;
|
||||
|
||||
UNLOCK_VOL(vol);
|
||||
return 0;
|
||||
@ -245,21 +292,16 @@ int dosfs_read_attr(void *_vol, void *_node, const char *name, int type, void *b
|
||||
|
||||
// suck up application attempts to set mime types; this hides an unsightly
|
||||
// error message printed out by zip
|
||||
int dosfs_write_attr(void *_vol, void *_node, const char *name, int type,
|
||||
const void *buf, size_t *len, off_t pos)
|
||||
status_t
|
||||
dosfs_write_attr(void *_vol, void *_node, fs_cookie _cookie, off_t pos,
|
||||
const void *buffer, size_t *_length)
|
||||
{
|
||||
TOUCH(_vol); TOUCH(_node); TOUCH(name); TOUCH(type); TOUCH(buf);
|
||||
TOUCH(len); TOUCH(pos);
|
||||
DPRINTF(0, ("dosfs_write_attr\n"));
|
||||
|
||||
DPRINTF(0, ("dosfs_write_attr (%s)\n", name));
|
||||
*_length = 0;
|
||||
|
||||
*len = 0;
|
||||
|
||||
if (strcmp(name, "BEOS:TYPE"))
|
||||
if (_cookie != &kBeOSTypeCookie)
|
||||
return ENOSYS;
|
||||
|
||||
if (type != MIME_STRING_TYPE)
|
||||
return ENOSYS;
|
||||
|
||||
return 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -5,18 +5,24 @@
|
||||
#ifndef _DOSFS_ATTR_H_
|
||||
#define _DOSFS_ATTR_H_
|
||||
|
||||
#include <fs_attr.h>
|
||||
|
||||
status_t set_mime_type(vnode *node, const char *filename);
|
||||
|
||||
int dosfs_open_attrdir(void *_vol, void *_node, void **_cookie);
|
||||
int dosfs_close_attrdir(void *_vol, void *_node, void *_cookie);
|
||||
int dosfs_free_attrcookie(void *_vol, void *_node, void *_cookie);
|
||||
int dosfs_rewind_attrdir(void *_vol, void *_node, void *_cookie);
|
||||
int dosfs_read_attrdir(void *_vol, void *_node, void *_cookie, long *num,
|
||||
struct dirent *buf, size_t bufsize);
|
||||
int dosfs_stat_attr(void *_vol, void *_node, const char *name, struct attr_info *buf);
|
||||
int dosfs_read_attr(void *_vol, void *_node, const char *name, int type, void *buf,
|
||||
size_t *len, off_t pos);
|
||||
int dosfs_write_attr(void *_vol, void *_node, const char *name, int type,
|
||||
const void *buf, size_t *len, off_t pos);
|
||||
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,
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef _CACHE_H_
|
||||
#define _CACHE_H_
|
||||
|
||||
#include <BeBuild.h>
|
||||
|
||||
typedef struct hash_ent {
|
||||
int dev;
|
||||
off_t bnum;
|
||||
off_t hash_val;
|
||||
void *data;
|
||||
struct hash_ent *next;
|
||||
} hash_ent;
|
||||
|
||||
|
||||
typedef struct hash_table {
|
||||
hash_ent **table;
|
||||
int max;
|
||||
int mask; /* == max - 1 */
|
||||
int num_elements;
|
||||
} hash_table;
|
||||
|
||||
|
||||
#define HT_DEFAULT_MAX 128
|
||||
|
||||
|
||||
typedef struct cache_ent {
|
||||
int dev;
|
||||
off_t block_num;
|
||||
int bsize;
|
||||
volatile int flags;
|
||||
|
||||
void *data;
|
||||
void *clone; /* copy of data by set_block_info() */
|
||||
int lock;
|
||||
|
||||
void (*func)(off_t bnum, size_t num_blocks, void *arg);
|
||||
off_t logged_bnum;
|
||||
void *arg;
|
||||
|
||||
struct cache_ent *next, /* points toward mru end of list */
|
||||
*prev; /* points toward lru end of list */
|
||||
|
||||
} cache_ent;
|
||||
|
||||
#define CE_NORMAL 0x0000 /* a nice clean pristine page */
|
||||
#define CE_DIRTY 0x0002 /* needs to be written to disk */
|
||||
#define CE_BUSY 0x0004 /* this block has i/o happening, don't touch it */
|
||||
|
||||
|
||||
typedef struct cache_ent_list {
|
||||
cache_ent *lru; /* tail of the list */
|
||||
cache_ent *mru; /* head of the list */
|
||||
} cache_ent_list;
|
||||
|
||||
|
||||
typedef struct block_cache {
|
||||
lock lock;
|
||||
int flags;
|
||||
int cur_blocks;
|
||||
int max_blocks;
|
||||
hash_table ht;
|
||||
|
||||
cache_ent_list normal, /* list of "normal" blocks (clean & dirty) */
|
||||
locked; /* list of clean and locked blocks */
|
||||
} block_cache;
|
||||
|
||||
#if 0 /* XXXdbg -- need to deal with write through caches */
|
||||
#define DC_WRITE_THROUGH 0x0001 /* cache is write-through (for floppies) */
|
||||
#endif
|
||||
|
||||
#define ALLOW_WRITES 1
|
||||
#define NO_WRITES 0
|
||||
|
||||
extern _IMPEXP_KERNEL int init_block_cache(int max_blocks, int flags);
|
||||
extern _IMPEXP_KERNEL void shutdown_block_cache(void);
|
||||
|
||||
extern _IMPEXP_KERNEL void force_cache_flush(int dev, int prefer_log_blocks);
|
||||
extern _IMPEXP_KERNEL int flush_blocks(int dev, off_t bnum, int nblocks);
|
||||
extern _IMPEXP_KERNEL int flush_device(int dev, int warn_locked);
|
||||
|
||||
extern _IMPEXP_KERNEL int init_cache_for_device(int fd, off_t max_blocks);
|
||||
extern _IMPEXP_KERNEL int remove_cached_device_blocks(int dev, int allow_write);
|
||||
|
||||
extern _IMPEXP_KERNEL void *get_block(int dev, off_t bnum, int bsize);
|
||||
extern _IMPEXP_KERNEL void *get_empty_block(int dev, off_t bnum, int bsize);
|
||||
extern _IMPEXP_KERNEL int release_block(int dev, off_t bnum);
|
||||
extern _IMPEXP_KERNEL int mark_blocks_dirty(int dev, off_t bnum, int nblocks);
|
||||
|
||||
|
||||
extern _IMPEXP_KERNEL int cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize);
|
||||
extern _IMPEXP_KERNEL int cached_write(int dev, off_t bnum, const void *data,
|
||||
off_t num_blocks, int bsize);
|
||||
extern _IMPEXP_KERNEL int cached_write_locked(int dev, off_t bnum, const void *data,
|
||||
off_t num_blocks, int bsize);
|
||||
extern _IMPEXP_KERNEL int set_blocks_info(int dev, off_t *blocks, int nblocks,
|
||||
void (*func)(off_t bnum, size_t nblocks, void *arg),
|
||||
void *arg);
|
||||
|
||||
|
||||
extern _IMPEXP_KERNEL size_t read_phys_blocks (int fd, off_t bnum, void *data, uint num_blocks, int bsize);
|
||||
extern _IMPEXP_KERNEL size_t write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize);
|
||||
|
||||
#endif /* _CACHE_H_ */
|
@ -4,12 +4,10 @@
|
||||
*/
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <lock.h>
|
||||
#include <cache.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <fs_cache.h>
|
||||
#include <fs_info.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -846,7 +844,9 @@ status_t create_dir_entry(nspace *vol, vnode *dir, vnode *node,
|
||||
return _create_dir_entry_(vol, dir, &info, (char *)nshort, (char *)nlong, len, ns, ne);
|
||||
}
|
||||
|
||||
int dosfs_read_vnode(void *_vol, vnode_id vnid, char reenter, void **_node)
|
||||
|
||||
status_t
|
||||
dosfs_read_vnode(void *_vol, vnode_id vnid, void **_node, bool reenter)
|
||||
{
|
||||
nspace *vol = (nspace*)_vol;
|
||||
int result = B_NO_ERROR;
|
||||
@ -956,6 +956,7 @@ int dosfs_read_vnode(void *_vol, vnode_id vnid, char reenter, void **_node)
|
||||
entry->filename = malloc(sizeof(filename) + 1);
|
||||
if (entry->filename) strcpy(entry->filename, filename);
|
||||
#endif
|
||||
entry->cache = file_cache_create(vol->id, vnid, entry->st_size, vol->fd);
|
||||
if(!(entry->mode & FAT_SUBDIR))
|
||||
set_mime_type(entry, filename);
|
||||
|
||||
@ -969,17 +970,16 @@ bi: if (!reenter) UNLOCK_VOL(vol);
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_walk(void *_vol, void *_dir, const char *file, char **newpath, vnode_id *vnid)
|
||||
|
||||
status_t
|
||||
dosfs_walk(void *_vol, void *_dir, const char *file, vnode_id *_vnid, int *_type)
|
||||
{
|
||||
/* 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;
|
||||
vnode *vnode = NULL;
|
||||
int result = ENOENT;
|
||||
|
||||
/* we can ignore newpath since there are no symbolic links */
|
||||
TOUCH(newpath);
|
||||
status_t result = ENOENT;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
@ -991,11 +991,11 @@ int dosfs_walk(void *_vol, void *_dir, const char *file, char **newpath, vnode_i
|
||||
|
||||
DPRINTF(0, ("dosfs_walk: find %Lx/%s\n", dir->vnid, file));
|
||||
|
||||
result = findfile_case(vol, dir, file, vnid, &vnode);
|
||||
result = findfile_case(vol, dir, file, _vnid, &vnode);
|
||||
if (result != B_OK) {
|
||||
DPRINTF(0, ("dosfs_walk (%s)\n", strerror(result)));
|
||||
} else {
|
||||
DPRINTF(0, ("dosfs_walk: found vnid %Lx\n", *vnid));
|
||||
DPRINTF(0, ("dosfs_walk: found vnid %Lx\n", *_vnid));
|
||||
}
|
||||
|
||||
UNLOCK_VOL(vol);
|
||||
@ -1003,7 +1003,8 @@ int dosfs_walk(void *_vol, void *_dir, const char *file, char **newpath, vnode_i
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_access(void *_vol, void *_node, int mode)
|
||||
status_t
|
||||
dosfs_access(void *_vol, void *_node, int mode)
|
||||
{
|
||||
status_t result = B_OK;
|
||||
nspace *vol = (nspace *)_vol;
|
||||
@ -1037,7 +1038,9 @@ int dosfs_access(void *_vol, void *_node, int mode)
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize)
|
||||
|
||||
status_t
|
||||
dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize)
|
||||
{
|
||||
TOUCH(_vol); TOUCH(_node); TOUCH(buf); TOUCH(bufsize);
|
||||
|
||||
@ -1047,7 +1050,9 @@ int dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int dosfs_opendir(void *_vol, void *_node, void **_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_opendir(void *_vol, void *_node, void **_cookie)
|
||||
{
|
||||
nspace *vol = (nspace*)_vol;
|
||||
vnode *node = (vnode*)_node;
|
||||
@ -1102,8 +1107,10 @@ bi:
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_readdir(void *_vol, void *_dir, void *_cookie, long *num,
|
||||
struct dirent *entry, size_t bufsize)
|
||||
|
||||
status_t
|
||||
dosfs_readdir(void *_vol, void *_dir, void *_cookie,
|
||||
struct dirent *entry, size_t bufsize, uint32 *num)
|
||||
{
|
||||
int result = ENOENT;
|
||||
nspace* vol = (nspace*)_vol;
|
||||
@ -1171,7 +1178,9 @@ bi:
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_rewinddir(void *_vol, void *_node, void* _cookie)
|
||||
|
||||
status_t
|
||||
dosfs_rewinddir(void *_vol, void *_node, void* _cookie)
|
||||
{
|
||||
nspace *vol = _vol;
|
||||
vnode *node = _node;
|
||||
@ -1195,7 +1204,9 @@ int dosfs_rewinddir(void *_vol, void *_node, void* _cookie)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
int dosfs_closedir(void *_vol, void *_node, void *_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_closedir(void *_vol, void *_node, void *_cookie)
|
||||
{
|
||||
TOUCH(_vol); TOUCH(_node); TOUCH(_cookie);
|
||||
|
||||
@ -1204,7 +1215,9 @@ int dosfs_closedir(void *_vol, void *_node, void *_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_free_dircookie(void *_vol, void *node, void *_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_free_dircookie(void *_vol, void *node, void *_cookie)
|
||||
{
|
||||
nspace *vol = _vol;
|
||||
dircookie *cookie = _cookie;
|
||||
|
@ -21,16 +21,16 @@ 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);
|
||||
|
||||
int dosfs_read_vnode(void *_vol, vnode_id vnid, char r, void **node);
|
||||
int dosfs_walk(void *_vol, void *_dir, const char *file,
|
||||
char **newpath, vnode_id *vnid);
|
||||
int dosfs_access(void *_vol, void *_node, int mode);
|
||||
int dosfs_readlink(void *_vol, void *_node, char *buf, size_t *bufsize);
|
||||
int dosfs_opendir(void *_vol, void *_node, void **cookie);
|
||||
int dosfs_readdir(void *_vol, void *_node, void *cookie,
|
||||
long *num, struct dirent *buf, size_t bufsize);
|
||||
int dosfs_rewinddir(void *_vol, void *_node, void *cookie);
|
||||
int dosfs_closedir(void *_vol, void *_node, void *cookie);
|
||||
int dosfs_free_dircookie(void *_vol, void *_node, void *cookie);
|
||||
status_t dosfs_read_vnode(void *_vol, vnode_id vnid, void **node, bool reenter);
|
||||
status_t dosfs_walk(void *_vol, void *_dir, const char *file,
|
||||
vnode_id *_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,
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
@ -20,8 +20,8 @@ TODO:
|
||||
#define DPRINTF(a,b) if (debug_dlist > (a)) dprintf b
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <fsproto.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dosfs.h"
|
||||
|
@ -14,12 +14,10 @@
|
||||
|
||||
#include <scsi.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#ifndef COMPILE_IN_BEOS
|
||||
#include <fs_info.h>
|
||||
#include <fs_interface.h>
|
||||
#include <fs_cache.h>
|
||||
#include <fs_volume.h>
|
||||
#endif
|
||||
#include <lock.h>
|
||||
#include <cache.h>
|
||||
|
||||
#include "dosfs.h"
|
||||
#include "attr.h"
|
||||
@ -49,7 +47,7 @@ static status_t get_fsinfo(nspace *vol, uint32 *free_count, uint32 *last_allocat
|
||||
|
||||
int32 instances = 0;
|
||||
|
||||
int debug_dos(int argc, char **argv)
|
||||
static int debug_dos(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
for (i=1;i<argc;i++) {
|
||||
@ -86,7 +84,7 @@ int debug_dos(int argc, char **argv)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
int debug_dvnode(int argc, char **argv)
|
||||
static int debug_dvnode(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -116,7 +114,7 @@ int debug_dvnode(int argc, char **argv)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
int debug_dc2s(int argc, char **argv)
|
||||
static int debug_dc2s(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
nspace *vol;
|
||||
@ -146,7 +144,7 @@ static int lock_removable_device(int fd, bool state)
|
||||
return ioctl(fd, B_SCSI_PREVENT_ALLOW, &state, sizeof(state));
|
||||
}
|
||||
|
||||
static status_t mount_fat_disk(const char *path, nspace_id nsid,
|
||||
static status_t mount_fat_disk(const char *path, mount_id nsid,
|
||||
const int flags, nspace** newVol, int fs_flags, int op_sync_mode)
|
||||
{
|
||||
nspace *vol = NULL;
|
||||
@ -438,7 +436,8 @@ static status_t mount_fat_disk(const char *path, nspace_id nsid,
|
||||
}
|
||||
|
||||
// initialize block cache
|
||||
if (init_cache_for_device(vol->fd, (off_t)vol->total_sectors) < 0) {
|
||||
vol->fBlockCache = block_cache_create(vol->fd, vol->total_sectors, vol->bytes_per_sector);
|
||||
if (vol->fBlockCache == NULL) {
|
||||
dprintf("error initializing block cache\n");
|
||||
goto error;
|
||||
}
|
||||
@ -537,7 +536,7 @@ error3:
|
||||
error2:
|
||||
uninit_vcache(vol);
|
||||
error1:
|
||||
remove_cached_device_blocks(vol->fd, NO_WRITES);
|
||||
block_cache_delete(vol->fBlockCache, false);
|
||||
error:
|
||||
if (!(vol->flags & B_FS_IS_READONLY) && (vol->flags & B_FS_IS_REMOVABLE) && (vol->fs_flags & FS_FLAGS_LOCK_DOOR))
|
||||
lock_removable_device(vol->fd, false);
|
||||
@ -547,8 +546,36 @@ error0:
|
||||
return (err >= B_NO_ERROR) ? EINVAL : err;
|
||||
}
|
||||
|
||||
static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *parms,
|
||||
size_t len, void **data, vnode_id *vnid)
|
||||
|
||||
// #pragma mark - Scanning
|
||||
|
||||
|
||||
static float
|
||||
dosfs_identify_partition(int fd, partition_data *partition, void **_cookie)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
dosfs_scan_partition(int fd, partition_data *partition, void *_cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dosfs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static status_t
|
||||
dosfs_mount(mount_id nsid, const char *device, uint32 flags,
|
||||
const char *args, void **_data, vnode_id *_rootID)
|
||||
{
|
||||
int result;
|
||||
nspace *vol;
|
||||
@ -579,17 +606,17 @@ static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *pa
|
||||
}
|
||||
|
||||
unload_driver_settings(handle);
|
||||
|
||||
/* parms and len are command line options; dosfs doesn't use any so
|
||||
|
||||
/* args is a command line option; dosfs doesn't use any so
|
||||
we can ignore these arguments */
|
||||
TOUCH(parms); TOUCH(len);
|
||||
TOUCH(args);
|
||||
|
||||
#if __RO__
|
||||
// make it read-only
|
||||
flags |= 1;
|
||||
#endif
|
||||
|
||||
if (data == NULL) {
|
||||
if (_data == NULL) {
|
||||
dprintf("dosfs_mount passed NULL data pointer\n");
|
||||
return EINVAL;
|
||||
}
|
||||
@ -600,17 +627,17 @@ static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *pa
|
||||
|
||||
if (check_nspace_magic(vol, "dosfs_mount")) return EINVAL;
|
||||
|
||||
*vnid = vol->root_vnode.vnid;
|
||||
*data = (void*)vol;
|
||||
*_rootID = vol->root_vnode.vnid;
|
||||
*_data = (void*)vol;
|
||||
|
||||
// You MUST do this. Create the vnode for the root.
|
||||
result = new_vnode(nsid, *vnid, (void*)&(vol->root_vnode));
|
||||
result = publish_vnode(nsid, *_rootID, (void*)&(vol->root_vnode));
|
||||
if (result != B_NO_ERROR) {
|
||||
dprintf("error creating new vnode (%s)\n", strerror(result));
|
||||
goto error;
|
||||
}
|
||||
sprintf(name, "fat lock %lx", vol->id);
|
||||
if ((result = new_lock(&(vol->vlock), name)) != 0) {
|
||||
if ((result = recursive_lock_init(&(vol->vlock), name)) != 0) {
|
||||
dprintf("error creating lock (%s)\n", strerror(result));
|
||||
goto error;
|
||||
}
|
||||
@ -631,7 +658,7 @@ static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *pa
|
||||
return result;
|
||||
|
||||
error:
|
||||
remove_cached_device_blocks(vol->fd, NO_WRITES);
|
||||
block_cache_delete(vol->fBlockCache, false);
|
||||
dlist_uninit(vol);
|
||||
uninit_vcache(vol);
|
||||
free(vol);
|
||||
@ -643,7 +670,9 @@ static void update_fsinfo(nspace *vol)
|
||||
if ((vol->fat_bits == 32) && (vol->fsinfo_sector != 0xffff) &&
|
||||
((vol->flags & B_FS_IS_READONLY) == false)) {
|
||||
uchar *buffer;
|
||||
if ((buffer = (uchar *)get_block(vol->fd, vol->fsinfo_sector, vol->bytes_per_sector)) != NULL) {
|
||||
int32 tid = cache_start_transaction(vol->fBlockCache);
|
||||
if ((buffer = (uchar *)block_cache_get_writable_etc(vol->fBlockCache,
|
||||
vol->fsinfo_sector, 0, vol->bytes_per_sector, tid)) != NULL) {
|
||||
if ((read32(buffer,0) == 0x41615252) && (read32(buffer,0x1e4) == 0x61417272) && (read16(buffer,0x1fe) == 0xaa55)) {
|
||||
//number of free clusters
|
||||
buffer[0x1e8] = (vol->free_clusters & 0xff);
|
||||
@ -655,12 +684,14 @@ static void update_fsinfo(nspace *vol)
|
||||
buffer[0x1ed] = ((vol->last_allocated >> 8) & 0xff);
|
||||
buffer[0x1ee] = ((vol->last_allocated >> 16) & 0xff);
|
||||
buffer[0x1ef] = ((vol->last_allocated >> 24) & 0xff);
|
||||
mark_blocks_dirty(vol->fd, vol->fsinfo_sector, 1);
|
||||
block_cache_set_dirty(vol->fBlockCache, vol->fsinfo_sector, true, tid);
|
||||
} else {
|
||||
dprintf("update_fsinfo: fsinfo block has invalid magic number\n");
|
||||
}
|
||||
release_block(vol->fd, vol->fsinfo_sector);
|
||||
block_cache_put(vol->fBlockCache, vol->fsinfo_sector);
|
||||
cache_end_transaction(vol->fBlockCache, tid, NULL, NULL);
|
||||
} else {
|
||||
cache_end_transaction(vol->fBlockCache, tid, NULL, NULL);
|
||||
dprintf("update_fsinfo: error getting fsinfo sector %x\n", vol->fsinfo_sector);
|
||||
}
|
||||
}
|
||||
@ -674,7 +705,7 @@ static status_t get_fsinfo(nspace *vol, uint32 *free_count, uint32 *last_allocat
|
||||
if ((vol->fat_bits != 32) || (vol->fsinfo_sector == 0xffff))
|
||||
return B_ERROR;
|
||||
|
||||
if ((buffer = (uchar *)get_block(vol->fd, vol->fsinfo_sector, vol->bytes_per_sector)) == NULL) {
|
||||
if ((buffer = (uchar *)block_cache_get_etc(vol->fBlockCache, vol->fsinfo_sector, 0, vol->bytes_per_sector)) == NULL) {
|
||||
dprintf("get_fsinfo: error getting fsinfo sector %x\n", vol->fsinfo_sector);
|
||||
return EIO;
|
||||
}
|
||||
@ -688,11 +719,13 @@ static status_t get_fsinfo(nspace *vol, uint32 *free_count, uint32 *last_allocat
|
||||
result = B_ERROR;
|
||||
}
|
||||
|
||||
release_block(vol->fd, vol->fsinfo_sector);
|
||||
block_cache_put(vol->fBlockCache, vol->fsinfo_sector);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int dosfs_unmount(void *_vol)
|
||||
|
||||
static status_t
|
||||
dosfs_unmount(void *_vol)
|
||||
{
|
||||
int result = B_NO_ERROR;
|
||||
|
||||
@ -708,8 +741,7 @@ static int dosfs_unmount(void *_vol)
|
||||
DPRINTF(0, ("dosfs_unmount volume %lx\n", vol->id));
|
||||
|
||||
update_fsinfo(vol);
|
||||
flush_device(vol->fd, 0);
|
||||
remove_cached_device_blocks(vol->fd, ALLOW_WRITES);
|
||||
block_cache_delete(vol->fBlockCache, true);
|
||||
|
||||
#if DEBUG
|
||||
if (atomic_add(&instances, -1) == 1) {
|
||||
@ -727,7 +759,7 @@ static int dosfs_unmount(void *_vol)
|
||||
if (!(vol->flags & B_FS_IS_READONLY) && (vol->flags & B_FS_IS_REMOVABLE) && (vol->fs_flags & FS_FLAGS_LOCK_DOOR))
|
||||
lock_removable_device(vol->fd, false);
|
||||
result = close(vol->fd);
|
||||
free_lock(&(vol->vlock));
|
||||
recursive_lock_destroy(&(vol->vlock));
|
||||
vol->magic = ~VNODE_MAGIC;
|
||||
free(vol);
|
||||
|
||||
@ -738,20 +770,21 @@ static int dosfs_unmount(void *_vol)
|
||||
return result;
|
||||
}
|
||||
|
||||
// dosfs_rfsstat - Fill in fs_info struct for device.
|
||||
static int dosfs_rfsstat(void *_vol, struct fs_info * fss)
|
||||
// dosfs_read_fs_stat - Fill in fs_info struct for device.
|
||||
static status_t
|
||||
dosfs_read_fs_stat(void *_vol, struct fs_info * fss)
|
||||
{
|
||||
nspace* vol = (nspace*)_vol;
|
||||
int i;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
if (check_nspace_magic(vol, "dosfs_rfsstat")) {
|
||||
if (check_nspace_magic(vol, "dosfs_read_fs_stat")) {
|
||||
UNLOCK_VOL(vol);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
DPRINTF(1, ("dosfs_rfsstat called\n"));
|
||||
DPRINTF(1, ("dosfs_read_fs_stat called\n"));
|
||||
|
||||
// fss->dev and fss->root filled in by kernel
|
||||
|
||||
@ -793,22 +826,23 @@ static int dosfs_rfsstat(void *_vol, struct fs_info * fss)
|
||||
|
||||
UNLOCK_VOL(vol);
|
||||
|
||||
return 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static int dosfs_wfsstat(void *_vol, struct fs_info * fss, long mask)
|
||||
static status_t
|
||||
dosfs_write_fs_stat(void *_vol, const struct fs_info * fss, uint32 mask)
|
||||
{
|
||||
int result = B_ERROR;
|
||||
status_t result = B_ERROR;
|
||||
nspace* vol = (nspace*)_vol;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
if (check_nspace_magic(vol, "dosfs_wfsstat")) {
|
||||
if (check_nspace_magic(vol, "dosfs_write_fs_stat")) {
|
||||
UNLOCK_VOL(vol);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
DPRINTF(0, ("dosfs_wfsstat called\n"));
|
||||
DPRINTF(0, ("dosfs_write_fs_stat called\n"));
|
||||
|
||||
/* if it's a r/o file system and not the special hack, then don't allow
|
||||
* volume renaming */
|
||||
@ -817,7 +851,7 @@ static int dosfs_wfsstat(void *_vol, struct fs_info * fss, long mask)
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
if (mask & WFSSTAT_NAME) {
|
||||
if (mask & FS_WRITE_FSINFO_NAME) {
|
||||
// sanitize name
|
||||
char name[11];
|
||||
int i,j;
|
||||
@ -840,7 +874,9 @@ static int dosfs_wfsstat(void *_vol, struct fs_info * fss, long mask)
|
||||
if (vol->vol_entry == -1) {
|
||||
// stored in the bpb
|
||||
uchar *buffer;
|
||||
if ((buffer = get_block(vol->fd, 0, vol->bytes_per_sector)) == NULL) {
|
||||
int32 tid = cache_start_transaction(vol->fBlockCache);
|
||||
if ((buffer = block_cache_get_writable_etc(vol->fBlockCache, 0, 0, vol->bytes_per_sector, tid)) == NULL) {
|
||||
cache_end_transaction(vol->fBlockCache, tid, NULL, NULL);
|
||||
result = EIO;
|
||||
goto bi;
|
||||
}
|
||||
@ -849,10 +885,11 @@ static int dosfs_wfsstat(void *_vol, struct fs_info * fss, long mask)
|
||||
result = B_ERROR;
|
||||
} else {
|
||||
memcpy(buffer + 0x2b, name, 11);
|
||||
mark_blocks_dirty(vol->fd, 0, 1);
|
||||
block_cache_set_dirty(vol->fBlockCache, 0, true, tid);
|
||||
result = 0;
|
||||
}
|
||||
release_block(vol->fd, 0);
|
||||
block_cache_put(vol->fBlockCache, 0);
|
||||
cache_end_transaction(vol->fBlockCache, tid, NULL, NULL);
|
||||
} else if (vol->vol_entry >= 0) {
|
||||
struct diri diri;
|
||||
uint8 *buffer;
|
||||
@ -887,7 +924,9 @@ bi: UNLOCK_VOL(vol);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int dosfs_ioctl(void *_vol, void *_node, void *cookie, int code,
|
||||
|
||||
static status_t
|
||||
dosfs_ioctl(void *_vol, void *_node, void *cookie, ulong code,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
status_t result = B_OK;
|
||||
@ -912,9 +951,10 @@ static int dosfs_ioctl(void *_vol, void *_node, void *cookie, int code,
|
||||
if (buf) *(bigtime_t *)buf = node->st_time;
|
||||
break;
|
||||
|
||||
case 69666 :
|
||||
/*case 69666 :
|
||||
result = fragment(vol, buf);
|
||||
break;
|
||||
*/
|
||||
|
||||
case 100000 :
|
||||
dprintf("built at %s on %s\n", build_time, build_date);
|
||||
@ -970,7 +1010,7 @@ static int dosfs_ioctl(void *_vol, void *_node, void *cookie, int code,
|
||||
break;
|
||||
|
||||
default :
|
||||
dprintf("dosfs_ioctl: vol %lx, vnode %Lx code = %d\n", vol->id, node->vnid, code);
|
||||
dprintf("dosfs_ioctl: vol %lx, vnode %Lx code = %ld\n", vol->id, node->vnid, code);
|
||||
result = EINVAL;
|
||||
break;
|
||||
}
|
||||
@ -980,21 +1020,25 @@ static int dosfs_ioctl(void *_vol, void *_node, void *cookie, int code,
|
||||
return result;
|
||||
}
|
||||
|
||||
int _dosfs_sync(nspace *vol)
|
||||
|
||||
status_t
|
||||
_dosfs_sync(nspace *vol)
|
||||
{
|
||||
if (check_nspace_magic(vol, "dosfs_sync"))
|
||||
return EINVAL;
|
||||
|
||||
update_fsinfo(vol);
|
||||
flush_device(vol->fd, 0);
|
||||
block_cache_sync(vol->fBlockCache);
|
||||
|
||||
return 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static int dosfs_sync(void *_vol)
|
||||
|
||||
static status_t
|
||||
dosfs_sync(void *_vol)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
int err;
|
||||
status_t err;
|
||||
|
||||
DPRINTF(0, ("dosfs_sync called on volume %lx\n", vol->id));
|
||||
|
||||
@ -1005,76 +1049,144 @@ static int dosfs_sync(void *_vol)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dosfs_fsync(void *vol, void *node)
|
||||
|
||||
static status_t
|
||||
dosfs_fsync(void *vol, void *node)
|
||||
{
|
||||
TOUCH(node);
|
||||
|
||||
return dosfs_sync(vol);
|
||||
}
|
||||
|
||||
vnode_ops fs_entry = {
|
||||
&dosfs_read_vnode,
|
||||
&dosfs_write_vnode,
|
||||
&dosfs_remove_vnode,
|
||||
NULL,
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static status_t
|
||||
dos_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
return B_OK;
|
||||
case B_MODULE_UNINIT:
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static file_system_module_info sDosFileSystem = {
|
||||
{
|
||||
"file_systems/dos" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
dos_std_ops,
|
||||
},
|
||||
|
||||
"FAT32 File System",
|
||||
|
||||
// scanning
|
||||
dosfs_identify_partition,
|
||||
dosfs_scan_partition,
|
||||
dosfs_free_identify_partition_cookie,
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&dosfs_mount,
|
||||
&dosfs_unmount,
|
||||
&dosfs_read_fs_stat,
|
||||
&dosfs_write_fs_stat,
|
||||
&dosfs_sync,
|
||||
|
||||
/* vnode operations */
|
||||
&dosfs_walk,
|
||||
&dosfs_access,
|
||||
&dosfs_create,
|
||||
&dosfs_mkdir,
|
||||
NULL,
|
||||
NULL,
|
||||
&dosfs_rename,
|
||||
&dosfs_unlink,
|
||||
&dosfs_rmdir,
|
||||
&dosfs_get_vnode_name,
|
||||
&dosfs_read_vnode,
|
||||
&dosfs_release_vnode,
|
||||
&dosfs_remove_vnode,
|
||||
|
||||
/* VM file access */
|
||||
NULL, //&fs_can_page,
|
||||
NULL, //&fs_read_pages,
|
||||
NULL, //&fs_write_pages,
|
||||
|
||||
&dosfs_get_file_map,
|
||||
|
||||
&dosfs_ioctl,
|
||||
NULL, //&fs_set_flags,
|
||||
NULL, //&fs_select
|
||||
NULL, //&fs_deselect
|
||||
&dosfs_fsync,
|
||||
|
||||
&dosfs_readlink,
|
||||
&dosfs_opendir,
|
||||
&dosfs_closedir,
|
||||
&dosfs_free_dircookie,
|
||||
&dosfs_rewinddir,
|
||||
&dosfs_readdir,
|
||||
NULL, // write link
|
||||
NULL, //&fs_create_symlink,
|
||||
|
||||
NULL, //&fs_link,
|
||||
&dosfs_unlink,
|
||||
&dosfs_rename,
|
||||
|
||||
&dosfs_access,
|
||||
&dosfs_rstat,
|
||||
&dosfs_wstat,
|
||||
|
||||
/* file operations */
|
||||
&dosfs_create,
|
||||
&dosfs_open,
|
||||
&dosfs_close,
|
||||
&dosfs_free_cookie,
|
||||
&dosfs_read,
|
||||
&dosfs_write,
|
||||
NULL,
|
||||
NULL,
|
||||
&dosfs_ioctl,
|
||||
NULL,
|
||||
&dosfs_rstat,
|
||||
&dosfs_wstat,
|
||||
&dosfs_fsync,
|
||||
NULL,
|
||||
&dosfs_mount,
|
||||
&dosfs_unmount,
|
||||
&dosfs_sync,
|
||||
&dosfs_rfsstat,
|
||||
&dosfs_wfsstat,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
/* directory operations */
|
||||
&dosfs_mkdir,
|
||||
&dosfs_rmdir,
|
||||
&dosfs_opendir,
|
||||
&dosfs_closedir,
|
||||
&dosfs_free_dircookie,
|
||||
&dosfs_readdir,
|
||||
&dosfs_rewinddir,
|
||||
|
||||
/* attribute directory operations */
|
||||
&dosfs_open_attrdir,
|
||||
&dosfs_close_attrdir,
|
||||
&dosfs_free_attrcookie,
|
||||
&dosfs_rewind_attrdir,
|
||||
&dosfs_free_attrdir_cookie,
|
||||
&dosfs_read_attrdir,
|
||||
&dosfs_write_attr,
|
||||
&dosfs_rewind_attrdir,
|
||||
|
||||
/* attribute operations */
|
||||
NULL, //&fs_create_attr,
|
||||
&dosfs_open_attr,
|
||||
&dosfs_close_attr,
|
||||
&dosfs_free_attr_cookie,
|
||||
&dosfs_read_attr,
|
||||
NULL,
|
||||
NULL,
|
||||
&dosfs_stat_attr,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
&dosfs_write_attr,
|
||||
|
||||
&dosfs_read_attr_stat,
|
||||
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,
|
||||
|
||||
/* query operations */
|
||||
NULL, //&fs_open_query,
|
||||
NULL, //&fs_close_query,
|
||||
NULL, //&fs_free_query_cookie,
|
||||
NULL, //&fs_read_query,
|
||||
NULL, //&fs_rewind_query,
|
||||
};
|
||||
|
||||
int32 api_version = B_CUR_FS_API_VERSION;
|
||||
module_info *modules[] = {
|
||||
(module_info *)&sDosFileSystem,
|
||||
NULL,
|
||||
};
|
||||
|
@ -5,21 +5,16 @@
|
||||
#ifndef _DOSFS_H_
|
||||
#define _DOSFS_H_
|
||||
|
||||
#if USE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#else
|
||||
|
||||
/* allocate memory from swappable heap */
|
||||
#define malloc smalloc
|
||||
#define free sfree
|
||||
#define calloc scalloc
|
||||
#define realloc srealloc
|
||||
|
||||
#include <kalloc.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <fs_interface.h>
|
||||
#include <lock.h>
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
typedef recursive_lock lock;
|
||||
#define LOCK(l) recursive_lock_lock(&l);
|
||||
#define UNLOCK(l) recursive_lock_unlock(&l);
|
||||
|
||||
|
||||
/* for multiple reader/single writer locks */
|
||||
#define READERS 100000
|
||||
@ -68,8 +63,6 @@
|
||||
#define VNODE_PARENT_DIR_CLUSTER(vnode) \
|
||||
CLUSTER_OF_DIR_CLUSTER_VNID((vnode)->dir_vnid)
|
||||
|
||||
#include <lock.h>
|
||||
|
||||
#define VNODE_MAGIC 'treB'
|
||||
|
||||
typedef struct vnode
|
||||
@ -77,6 +70,7 @@ typedef struct vnode
|
||||
uint32 magic;
|
||||
vnode_id vnid; // self id
|
||||
vnode_id dir_vnid; // parent vnode id (directory containing entry)
|
||||
void *cache; // for file cache
|
||||
|
||||
uint32 disk_image; // 0 = no, 1 = BEOS, 2 = IMAGE.BE
|
||||
|
||||
@ -104,7 +98,7 @@ typedef struct vnode
|
||||
|
||||
#if TRACK_FILENAME
|
||||
char *filename;
|
||||
#endif
|
||||
#endif
|
||||
} vnode;
|
||||
|
||||
// mode bits
|
||||
@ -122,10 +116,11 @@ struct vcache_entry;
|
||||
typedef struct _nspace
|
||||
{
|
||||
uint32 magic;
|
||||
nspace_id id; // ID passed in to fs_mount
|
||||
mount_id id; // ID passed in to fs_mount
|
||||
int fd; // File descriptor
|
||||
char device[256];
|
||||
uint32 flags; // see <fcntl.be.h> for modes
|
||||
void *fBlockCache;
|
||||
|
||||
// info from bpb
|
||||
uint32 bytes_per_sector;
|
||||
@ -206,6 +201,6 @@ int check_nspace_magic(struct _nspace *t, char *funcname);
|
||||
extern int debug_attr, debug_dir, debug_dlist, debug_dosfs, debug_encodings,
|
||||
debug_fat, debug_file, debug_iter, debug_vcache;
|
||||
|
||||
int _dosfs_sync(nspace *vol);
|
||||
status_t _dosfs_sync(nspace *vol);
|
||||
|
||||
#endif
|
||||
|
@ -4,10 +4,7 @@
|
||||
*/
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <lock.h>
|
||||
#include <cache.h>
|
||||
|
||||
#include <fs_cache.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ByteOrder.h>
|
||||
@ -24,9 +21,10 @@
|
||||
|
||||
#define DPRINTF(a,b) if (debug_fat > (a)) dprintf b
|
||||
|
||||
static status_t mirror_fats(nspace *vol, uint32 sector, uint8 *buffer)
|
||||
static status_t mirror_fats(nspace *vol, uint32 sector, uint8 *buffer, int32 tid)
|
||||
{
|
||||
uint32 i;
|
||||
char *buf = buffer;
|
||||
|
||||
if (!vol->fat_mirrored)
|
||||
return B_OK;
|
||||
@ -34,18 +32,22 @@ static status_t mirror_fats(nspace *vol, uint32 sector, uint8 *buffer)
|
||||
sector -= vol->active_fat * vol->sectors_per_fat;
|
||||
|
||||
for (i=0;i<vol->fat_count;i++) {
|
||||
char *blockData;
|
||||
if (i == vol->active_fat)
|
||||
continue;
|
||||
cached_write(vol->fd, sector + i*vol->sectors_per_fat, buffer, 1, vol->bytes_per_sector);
|
||||
blockData = block_cache_get_writable_etc(vol->fBlockCache, sector + i*vol->sectors_per_fat, 0, 1, tid);
|
||||
memcpy(blockData, buf, vol->bytes_per_sector);
|
||||
buf += vol->bytes_per_sector;
|
||||
block_cache_put(vol->fBlockCache, sector + i*vol->sectors_per_fat);
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static int32 _count_free_clusters_fat32(nspace *vol)
|
||||
{
|
||||
int32 count = 0;
|
||||
uint8 *block;
|
||||
const uint8 *block;
|
||||
uint32 fat_sector;
|
||||
uint32 i;
|
||||
uint32 cur_sector;
|
||||
@ -53,7 +55,7 @@ static int32 _count_free_clusters_fat32(nspace *vol)
|
||||
cur_sector = vol->reserved_sectors + vol->active_fat * vol->sectors_per_fat;
|
||||
|
||||
for(fat_sector = 0; fat_sector < vol->sectors_per_fat; fat_sector++) {
|
||||
block = (uint8 *)get_block(vol->fd, cur_sector, vol->bytes_per_sector);
|
||||
block = (uint8 *)block_cache_get(vol->fBlockCache, cur_sector);
|
||||
if(block == NULL) {
|
||||
return EIO;
|
||||
}
|
||||
@ -63,7 +65,7 @@ static int32 _count_free_clusters_fat32(nspace *vol)
|
||||
if(val == 0) count++;
|
||||
}
|
||||
|
||||
release_block(vol->fd, cur_sector);
|
||||
block_cache_put(vol->fBlockCache, cur_sector);
|
||||
cur_sector++;
|
||||
}
|
||||
|
||||
@ -85,6 +87,7 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
uint32 sector;
|
||||
uint32 off, val = 0; /* quiet warning */
|
||||
uint8 *block1, *block2 = NULL; /* quiet warning */
|
||||
int32 tid = -1;
|
||||
|
||||
// mark end of chain for allocations
|
||||
uint32 V = (action == _IOCTL_SET_ENTRY_) ? N : 0x0fffffff;
|
||||
@ -94,8 +97,7 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
if (check_nspace_magic(vol, "_fat_ioctl_")) return EINVAL;
|
||||
|
||||
DPRINTF(3, ("_fat_ioctl_: action %lx, cluster %lx, N %lx\n", action, cluster, N));
|
||||
|
||||
|
||||
|
||||
if (action == _IOCTL_COUNT_FREE_) {
|
||||
if(vol->fat_bits == 32)
|
||||
// use a optimized version of the cluster counting algorithms
|
||||
@ -118,19 +120,31 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
sector = vol->reserved_sectors + vol->active_fat * vol->sectors_per_fat +
|
||||
off / vol->bytes_per_sector;
|
||||
off %= vol->bytes_per_sector;
|
||||
|
||||
if ((block1 = (uint8 *)get_block(vol->fd, sector, vol->bytes_per_sector)) == NULL) {
|
||||
|
||||
if (action != _IOCTL_SET_ENTRY_ && action != _IOCTL_ALLOCATE_N_ENTRIES_) {
|
||||
block1 = (uint8 *)block_cache_get(vol->fBlockCache, sector);
|
||||
} else {
|
||||
tid = cache_start_transaction(vol->fBlockCache);
|
||||
block1 = (uint8 *)block_cache_get_writable(vol->fBlockCache, sector, tid);
|
||||
}
|
||||
|
||||
if (block1 == NULL) {
|
||||
DPRINTF(0, ("_fat_ioctl_: error reading fat (sector %lx)\n", sector));
|
||||
return EIO;
|
||||
}
|
||||
|
||||
|
||||
for (i=0;i<vol->total_clusters;i++) {
|
||||
ASSERT(IS_DATA_CLUSTER(cluster));
|
||||
ASSERT(off == ((cluster * vol->fat_bits / 8) % vol->bytes_per_sector));
|
||||
|
||||
if (vol->fat_bits == 12) {
|
||||
if (off == vol->bytes_per_sector - 1) {
|
||||
if ((block2 = (uint8 *)get_block(vol->fd, ++sector, vol->bytes_per_sector)) == NULL) {
|
||||
if (action != _IOCTL_SET_ENTRY_ && action != _IOCTL_ALLOCATE_N_ENTRIES_)
|
||||
block2 = (uint8 *)block_cache_get(vol->fBlockCache, ++sector);
|
||||
else
|
||||
block2 = (uint8 *)block_cache_get_writable(vol->fBlockCache, ++sector, tid);
|
||||
|
||||
if (block2 == NULL) {
|
||||
DPRINTF(0, ("_fat_ioctl_: error reading fat (sector %lx)\n", sector));
|
||||
result = EIO;
|
||||
sector--;
|
||||
@ -162,8 +176,8 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
block1[off] &= (andmask & 0xff);
|
||||
block1[off] |= (ormask & 0xff);
|
||||
if (off == vol->bytes_per_sector - 1) {
|
||||
mark_blocks_dirty(vol->fd, sector - 1, 1);
|
||||
mirror_fats(vol, sector - 1, block1);
|
||||
//mark_blocks_dirty(vol->fd, sector - 1, 1);
|
||||
mirror_fats(vol, sector - 1, block1, tid);
|
||||
block2[0] &= (andmask >> 8);
|
||||
block2[0] |= (ormask >> 8);
|
||||
} else {
|
||||
@ -174,7 +188,7 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
|
||||
if (off == vol->bytes_per_sector - 1) {
|
||||
off = (cluster & 1) ? 1 : 0;
|
||||
release_block(vol->fd, sector - 1);
|
||||
block_cache_put(vol->fBlockCache, sector - 1);
|
||||
block1 = block2;
|
||||
} else {
|
||||
off += (cluster & 1) ? 2 : 1;
|
||||
@ -220,13 +234,13 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
result = val;
|
||||
goto bi;
|
||||
} else if (action == _IOCTL_SET_ENTRY_) {
|
||||
mark_blocks_dirty(vol->fd, sector, 1);
|
||||
mirror_fats(vol, sector, block1);
|
||||
//mark_blocks_dirty(vol->fd, sector, 1);
|
||||
mirror_fats(vol, sector, block1, tid);
|
||||
goto bi;
|
||||
} else if ((action == _IOCTL_ALLOCATE_N_ENTRIES_) && (val == 0)) {
|
||||
vol->free_clusters--;
|
||||
mark_blocks_dirty(vol->fd, sector, 1);
|
||||
mirror_fats(vol, sector, block1);
|
||||
//mark_blocks_dirty(vol->fd, sector, 1);
|
||||
mirror_fats(vol, sector, block1, tid);
|
||||
if (n == 0) {
|
||||
ASSERT(first == 0);
|
||||
first = last = cluster;
|
||||
@ -249,20 +263,29 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
|
||||
// iterate cluster and sector if needed
|
||||
if (++cluster == vol->total_clusters + 2) {
|
||||
release_block(vol->fd, sector);
|
||||
block_cache_put(vol->fBlockCache, sector);
|
||||
|
||||
cluster = 2;
|
||||
off = 2 * vol->fat_bits / 8;
|
||||
sector = vol->reserved_sectors + vol->active_fat * vol->sectors_per_fat;
|
||||
|
||||
block1 = (uint8 *)get_block(vol->fd, sector, vol->bytes_per_sector);
|
||||
if (action != _IOCTL_SET_ENTRY_ && action != _IOCTL_ALLOCATE_N_ENTRIES_)
|
||||
block1 = (uint8 *)block_cache_get(vol->fBlockCache, sector);
|
||||
else
|
||||
block1 = (uint8 *)block_cache_get_writable(vol->fBlockCache, sector, tid);
|
||||
}
|
||||
|
||||
if (off >= vol->bytes_per_sector) {
|
||||
release_block(vol->fd, sector);
|
||||
off -= vol->bytes_per_sector; sector++;
|
||||
block_cache_put(vol->fBlockCache, sector);
|
||||
|
||||
off -= vol->bytes_per_sector;
|
||||
sector++;
|
||||
ASSERT(sector < vol->reserved_sectors + (vol->active_fat + 1) * vol->sectors_per_fat);
|
||||
block1 = (uint8 *)get_block(vol->fd, sector, vol->bytes_per_sector);
|
||||
|
||||
if (action != _IOCTL_SET_ENTRY_ && action != _IOCTL_ALLOCATE_N_ENTRIES_)
|
||||
block1 = (uint8 *)block_cache_get(vol->fBlockCache, sector);
|
||||
else
|
||||
block1 = (uint8 *)block_cache_get_writable(vol->fBlockCache, sector, tid);
|
||||
}
|
||||
|
||||
if (block1 == NULL) {
|
||||
@ -273,7 +296,10 @@ static int32 _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
|
||||
}
|
||||
|
||||
bi:
|
||||
if (block1) release_block(vol->fd, sector);
|
||||
if (block1)
|
||||
block_cache_put(vol->fBlockCache, sector);
|
||||
if (tid >= 0)
|
||||
cache_end_transaction(vol->fBlockCache, tid, NULL, NULL);
|
||||
|
||||
if (action == _IOCTL_ALLOCATE_N_ENTRIES_) {
|
||||
if (result < 0) {
|
||||
@ -290,9 +316,9 @@ bi:
|
||||
}
|
||||
}
|
||||
|
||||
if (result < B_OK)
|
||||
if (result < B_OK) {
|
||||
DPRINTF(0, ("_fat_ioctl_ error: action = %lx cluster = %lx N = %lx (%s)\n", action, cluster, N, strerror(result)));
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -553,6 +579,7 @@ void dump_fat_chain(nspace *vol, uint32 cluster)
|
||||
dprintf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
status_t fragment(nspace *vol, uint32 *pattern)
|
||||
{
|
||||
uint32 sector, offset, previous_entry, i, val;
|
||||
@ -642,3 +669,4 @@ status_t fragment(nspace *vol, uint32 *pattern)
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
*/
|
@ -2,15 +2,16 @@
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <fs_cache.h>
|
||||
#include <fs_info.h>
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
#include <NodeMonitor.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <lock.h>
|
||||
#include <cache.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "iter.h"
|
||||
@ -44,14 +45,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)
|
||||
{
|
||||
vnode *node = (vnode*)_node;
|
||||
strlcpy(buffer, node->filename, bufferSize);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t write_vnode_entry(nspace *vol, vnode *node)
|
||||
{
|
||||
uint32 i;
|
||||
struct diri diri;
|
||||
uint8 *buffer;
|
||||
|
||||
|
||||
// TODO : is it needed ? vfs job ?
|
||||
// don't update entries of deleted files
|
||||
if (is_vnode_removed(vol->id, node->vnid) > 0) return 0;
|
||||
//if (is_vnode_removed(vol->id, node->vnid) > 0) return 0;
|
||||
|
||||
// XXX: should check if directory position is still valid even
|
||||
// though we do the is_vnode_removed check above
|
||||
@ -96,9 +109,11 @@ status_t write_vnode_entry(nspace *vol, vnode *node)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// called when fs is done with vnode
|
||||
// after close, etc. free vnode resources here
|
||||
int dosfs_write_vnode(void *_vol, void *_node, char reenter)
|
||||
status_t
|
||||
dosfs_release_vnode(void *_vol, void *_node, bool reenter)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
@ -122,8 +137,11 @@ int dosfs_write_vnode(void *_vol, void *_node, char reenter)
|
||||
#if TRACK_FILENAME
|
||||
if (node->filename) free(node->filename);
|
||||
#endif
|
||||
|
||||
if (node->vnid != vol->root_vnode.vnid) {
|
||||
node->magic = ~VNODE_MAGIC; // munge magic number to be safe
|
||||
if (node->cache != NULL)
|
||||
file_cache_delete(node->cache);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
@ -131,7 +149,9 @@ int dosfs_write_vnode(void *_vol, void *_node, char reenter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_rstat(void *_vol, void *_node, struct stat *st)
|
||||
|
||||
status_t
|
||||
dosfs_rstat(void *_vol, void *_node, struct stat *st)
|
||||
{
|
||||
nspace *vol = (nspace*)_vol;
|
||||
vnode *node = (vnode*)_node;
|
||||
@ -168,7 +188,9 @@ int dosfs_rstat(void *_vol, void *_node, struct stat *st)
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
int dosfs_wstat(void *_vol, void *_node, struct stat *st, long mask)
|
||||
|
||||
status_t
|
||||
dosfs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
|
||||
{
|
||||
int err = B_OK;
|
||||
nspace *vol = (nspace*)_vol;
|
||||
@ -197,7 +219,7 @@ int dosfs_wstat(void *_vol, void *_node, struct stat *st, long mask)
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if (mask & WSTAT_MODE) {
|
||||
if (mask & FS_WRITE_STAT_MODE) {
|
||||
DPRINTF(0, ("setting file mode to %o\n", st->st_mode));
|
||||
if (st->st_mode & S_IWUSR)
|
||||
node->mode &= ~FAT_READ_ONLY;
|
||||
@ -206,7 +228,7 @@ int dosfs_wstat(void *_vol, void *_node, struct stat *st, long mask)
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (mask & WSTAT_SIZE) {
|
||||
if (mask & FS_WRITE_STAT_SIZE) {
|
||||
DPRINTF(0, ("setting file size to %Lx\n", st->st_size));
|
||||
if (node->mode & FAT_SUBDIR) {
|
||||
dprintf("dosfs_wstat: can't set file size of directory!\n");
|
||||
@ -221,11 +243,12 @@ int dosfs_wstat(void *_vol, void *_node, struct stat *st, long mask)
|
||||
node->st_size = st->st_size;
|
||||
node->iteration++;
|
||||
dirty = true;
|
||||
file_cache_set_size(node->cache, node->st_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & WSTAT_MTIME) {
|
||||
if (mask & FS_WRITE_STAT_MTIME) {
|
||||
DPRINTF(0, ("setting modification time\n"));
|
||||
node->st_time = st->st_mtime;
|
||||
dirty = true;
|
||||
@ -249,9 +272,11 @@ int dosfs_wstat(void *_vol, void *_node, struct stat *st, long mask)
|
||||
return err;
|
||||
}
|
||||
|
||||
int dosfs_open(void *_vol, void *_node, int omode, void **_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_open(void *_vol, void *_node, int omode, void **_cookie)
|
||||
{
|
||||
int result = EINVAL;
|
||||
status_t result = EINVAL;
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode* node = (vnode*)_node;
|
||||
filecookie *cookie;
|
||||
@ -320,18 +345,20 @@ error:
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_read(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
|
||||
status_t
|
||||
dosfs_read(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
void *buf, size_t *len)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
filecookie *cookie = (filecookie *)_cookie;
|
||||
uint8 *buffer;
|
||||
struct csi iter;
|
||||
//uint8 *buffer;
|
||||
//struct csi iter;
|
||||
int result = B_OK;
|
||||
size_t bytes_read = 0;
|
||||
uint32 cluster1;
|
||||
off_t diff;
|
||||
//size_t bytes_read = 0;
|
||||
//uint32 cluster1;
|
||||
//off_t diff;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
@ -343,6 +370,7 @@ int dosfs_read(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
||||
if (node->mode & FAT_SUBDIR) {
|
||||
DPRINTF(0, ("dosfs_read called on subdirectory %Lx\n", node->vnid));
|
||||
*len = 0;
|
||||
@ -355,13 +383,18 @@ int dosfs_read(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
if (pos < 0) pos = 0;
|
||||
|
||||
if ((node->st_size == 0) || (*len == 0) || (pos >= node->st_size)) {
|
||||
bytes_read = 0;
|
||||
//bytes_read = 0;
|
||||
*len = 0;
|
||||
goto bi;
|
||||
}
|
||||
|
||||
// truncate bytes to read to file size
|
||||
if (pos + *len >= node->st_size)
|
||||
*len = node->st_size - pos;
|
||||
|
||||
result = file_cache_read(node->cache, pos, buf, len);
|
||||
|
||||
#if 0
|
||||
|
||||
if ((cookie->ccache.iteration == node->iteration) &&
|
||||
(pos >= cookie->ccache.index * vol->bytes_per_sector * vol->sectors_per_cluster)) {
|
||||
@ -455,9 +488,9 @@ int dosfs_read(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
}
|
||||
|
||||
result = B_OK;
|
||||
#endif
|
||||
|
||||
bi:
|
||||
*len = bytes_read;
|
||||
|
||||
if (result != B_OK) {
|
||||
DPRINTF(0, ("dosfs_read (%s)\n", strerror(result)));
|
||||
} else {
|
||||
@ -468,18 +501,21 @@ bi:
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
|
||||
status_t
|
||||
dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
const void *buf, size_t *len)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
filecookie *cookie = (filecookie *)_cookie;
|
||||
uint8 *buffer;
|
||||
struct csi iter;
|
||||
//uint8 *buffer;
|
||||
//struct csi iter;
|
||||
int result = B_OK;
|
||||
size_t bytes_written = 0;
|
||||
uint32 cluster1;
|
||||
off_t diff;
|
||||
//size_t bytes_written = 0;
|
||||
//uint32 cluster1;
|
||||
//off_t diff;
|
||||
|
||||
|
||||
LOCK_VOL(vol);
|
||||
|
||||
@ -500,9 +536,10 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
}
|
||||
|
||||
DPRINTF(0, ("dosfs_write called %lx bytes at %Lx from buffer at %lx (vnode id %Lx)\n", *len, pos, (uint32)buf, node->vnid));
|
||||
|
||||
|
||||
if ((cookie->mode & O_RWMASK) == O_RDONLY) {
|
||||
dprintf("dosfs_write: called on file opened as read-only\n");
|
||||
*len = 0;
|
||||
result = EPERM;
|
||||
goto bi;
|
||||
}
|
||||
@ -515,6 +552,7 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
|
||||
if (pos >= MAX_FILE_SIZE) {
|
||||
dprintf("dosfs_write: write position exceeds fat limits\n");
|
||||
*len = 0;
|
||||
result = E2BIG;
|
||||
goto bi;
|
||||
}
|
||||
@ -522,6 +560,8 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
if (pos + *len >= MAX_FILE_SIZE) {
|
||||
*len = (size_t)(MAX_FILE_SIZE - pos);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
if (node->st_size &&
|
||||
(cookie->ccache.iteration == node->iteration) &&
|
||||
@ -534,6 +574,7 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
cluster1 = 0xffffffff;
|
||||
diff = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// extend file size if needed
|
||||
if (pos + *len > node->st_size) {
|
||||
@ -552,8 +593,12 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
|
||||
DPRINTF(0, ("setting file size to %Lx (%lx clusters)\n", node->st_size, clusters));
|
||||
node->dirty = true;
|
||||
file_cache_set_size(node->cache, node->st_size);
|
||||
}
|
||||
|
||||
|
||||
result = file_cache_write(node->cache, pos, buf, len);
|
||||
|
||||
#if 0
|
||||
if (cluster1 == 0xffffffff) {
|
||||
cluster1 = node->cluster;
|
||||
diff = pos;
|
||||
@ -643,10 +688,9 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
|
||||
}
|
||||
|
||||
result = B_OK;
|
||||
|
||||
#endif
|
||||
|
||||
bi:
|
||||
*len = bytes_written;
|
||||
|
||||
if (result != B_OK) {
|
||||
DPRINTF(0, ("dosfs_write (%s)\n", strerror(result)));
|
||||
} else {
|
||||
@ -657,7 +701,9 @@ bi:
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_close(void *_vol, void *_node, void *_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_close(void *_vol, void *_node, void *_cookie)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
@ -683,7 +729,9 @@ int dosfs_close(void *_vol, void *_node, void *_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_free_cookie(void *_vol, void *_node, void *_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_free_cookie(void *_vol, void *_node, void *_cookie)
|
||||
{
|
||||
nspace *vol = _vol;
|
||||
vnode *node = _node;
|
||||
@ -707,8 +755,10 @@ int dosfs_free_cookie(void *_vol, void *_node, void *_cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dosfs_create(void *_vol, void *_dir, const char *name, int omode,
|
||||
int perms, vnode_id *vnid, void **_cookie)
|
||||
|
||||
status_t
|
||||
dosfs_create(void *_vol, void *_dir, const char *name, int omode,
|
||||
int perms, void **_cookie, vnode_id *vnid)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *dir = (vnode *)_dir, *file;
|
||||
@ -732,18 +782,19 @@ int dosfs_create(void *_vol, void *_dir, const char *name, int omode,
|
||||
}
|
||||
|
||||
DPRINTF(0, ("dosfs_create called: %Lx/%s perms=%o omode=%o\n", dir->vnid, name, perms, omode));
|
||||
|
||||
|
||||
if (vol->flags & B_FS_IS_READONLY) {
|
||||
dprintf("dosfs_create called on read-only volume\n");
|
||||
UNLOCK_VOL(vol);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
if (is_vnode_removed(vol->id, dir->vnid) > 0) {
|
||||
// TODO : is it needed ? vfs job ?
|
||||
/*if (is_vnode_removed(vol->id, dir->vnid) > 0) {
|
||||
dprintf("dosfs_create() called in removed directory. disallowed.\n");
|
||||
UNLOCK_VOL(vol);
|
||||
return EPERM;
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((omode & O_RWMASK) == O_RDONLY) {
|
||||
dprintf("invalid permissions used in creating file\n");
|
||||
@ -854,7 +905,9 @@ bi: if (result != B_OK) free(cookie);
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_mkdir(void *_vol, void *_dir, const char *name, int perms)
|
||||
|
||||
status_t
|
||||
dosfs_mkdir(void *_vol, void *_dir, const char *name, int perms, vnode_id *_vnid)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *dir = (vnode *)_dir, dummy;
|
||||
@ -871,11 +924,12 @@ int dosfs_mkdir(void *_vol, void *_dir, const char *name, int perms)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (is_vnode_removed(vol->id, dir->vnid) > 0) {
|
||||
// TODO : is it needed ? vfs job ?
|
||||
/*if (is_vnode_removed(vol->id, dir->vnid) > 0) {
|
||||
dprintf("dosfs_mkdir() called in removed directory. disallowed.\n");
|
||||
UNLOCK_VOL(vol);
|
||||
return EPERM;
|
||||
}
|
||||
}*/
|
||||
|
||||
DPRINTF(0, ("dosfs_mkdir called: %Lx/%s (perm %o)\n", dir->vnid, name, perms));
|
||||
|
||||
@ -1003,7 +1057,9 @@ bi: dummy.magic = ~VNODE_MAGIC;
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_rename(void *_vol, void *_odir, const char *oldname,
|
||||
|
||||
status_t
|
||||
dosfs_rename(void *_vol, void *_odir, const char *oldname,
|
||||
void *_ndir, const char *newname)
|
||||
{
|
||||
status_t result = EINVAL;
|
||||
@ -1230,7 +1286,9 @@ bi:
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_remove_vnode(void *_vol, void *_node, char reenter)
|
||||
|
||||
status_t
|
||||
dosfs_remove_vnode(void *_vol, void *_node, bool reenter)
|
||||
{
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *node = (vnode *)_node;
|
||||
@ -1279,13 +1337,14 @@ int dosfs_remove_vnode(void *_vol, void *_node, char reenter)
|
||||
UNLOCK_VOL(vol);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// get rid of node or directory
|
||||
static int do_unlink(void *_vol, void *_dir, const char *name, bool is_file)
|
||||
static status_t
|
||||
do_unlink(void *_vol, void *_dir, const char *name, bool is_file)
|
||||
{
|
||||
int result = EINVAL;
|
||||
status_t result = EINVAL;
|
||||
nspace *vol = (nspace *)_vol;
|
||||
vnode *dir = (vnode *)_dir, *file;
|
||||
vnode_id vnid;
|
||||
@ -1391,16 +1450,167 @@ bi: UNLOCK_VOL(vol);
|
||||
return result;
|
||||
}
|
||||
|
||||
int dosfs_unlink(void *vol, void *dir, const char *name)
|
||||
status_t
|
||||
dosfs_unlink(void *vol, void *dir, const char *name)
|
||||
{
|
||||
DPRINTF(1, ("dosfs_unlink called\n"));
|
||||
|
||||
return do_unlink(vol,dir,name,true);
|
||||
return do_unlink(vol, dir, name, true);
|
||||
}
|
||||
|
||||
int dosfs_rmdir(void *vol, void *dir, const char *name)
|
||||
|
||||
status_t
|
||||
dosfs_rmdir(void *vol, void *dir, const char *name)
|
||||
{
|
||||
DPRINTF(1, ("dosfs_rmdir called\n"));
|
||||
|
||||
return do_unlink(vol,dir,name,false);
|
||||
return do_unlink(vol, dir, name, false);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
dosfs_get_file_map(void *_fs, void *_node, off_t pos, size_t len,
|
||||
struct file_io_vec *vecs, size_t *_count)
|
||||
{
|
||||
nspace *vol = (nspace *)_fs;
|
||||
vnode *node = (vnode *)_node;
|
||||
struct csi iter;
|
||||
int result = B_OK;
|
||||
size_t bytes_read = 0;
|
||||
uint32 cluster1;
|
||||
off_t diff;
|
||||
size_t index = 0, max = *_count;
|
||||
|
||||
LOCK_VOL(vol);
|
||||
*_count = 0;
|
||||
|
||||
if (check_nspace_magic((nspace *)vol, "dosfs_get_file_map") ||
|
||||
check_vnode_magic(node, "dosfs_get_file_map")) {
|
||||
UNLOCK_VOL(vol);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (node->mode & FAT_SUBDIR) {
|
||||
DPRINTF(0, ("dosfs_get_file_map called on subdirectory %Lx\n", node->vnid));
|
||||
UNLOCK_VOL(vol);
|
||||
return EISDIR;
|
||||
}
|
||||
|
||||
DPRINTF(0, ("dosfs_get_file_map called %lx bytes at %Lx (vnode id %Lx)\n", len, pos, node->vnid));
|
||||
|
||||
if (pos < 0) pos = 0;
|
||||
|
||||
if ((node->st_size == 0) || (len == 0) || (pos >= node->st_size)) {
|
||||
bytes_read = 0;
|
||||
goto bi;
|
||||
}
|
||||
|
||||
// truncate bytes to read to file size
|
||||
if (pos + len >= node->st_size)
|
||||
len = node->st_size - pos;
|
||||
|
||||
/* the fat chain changed, so we have to start from the beginning */
|
||||
cluster1 = node->cluster;
|
||||
diff = pos;
|
||||
diff /= vol->bytes_per_sector; /* convert to sectors */
|
||||
|
||||
if ((result = init_csi(vol, cluster1, 0, &iter)) != B_OK) {
|
||||
dprintf("dosfs_get_file_map: invalid starting cluster (%lx)\n", cluster1);
|
||||
goto bi;
|
||||
}
|
||||
|
||||
if (diff && ((result = iter_csi(&iter, diff)) != B_OK)) {
|
||||
dprintf("dosfs_get_file_map: end of file reached (init)\n");
|
||||
result = EIO;
|
||||
goto bi;
|
||||
}
|
||||
|
||||
ASSERT(iter.cluster == get_nth_fat_entry(vol, node->cluster, pos / vol->bytes_per_sector / vol->sectors_per_cluster));
|
||||
|
||||
if ((pos % vol->bytes_per_sector) != 0) {
|
||||
// read in partial first sector if necessary
|
||||
size_t amt = vol->bytes_per_sector - (pos % vol->bytes_per_sector);
|
||||
if (amt > len)
|
||||
amt = len;
|
||||
vecs[index].offset = csi_to_block(&iter) * vol->bytes_per_sector + (pos % vol->bytes_per_sector);
|
||||
vecs[index].length = amt;
|
||||
index++;
|
||||
if (index >= max) {
|
||||
// we're out of file_io_vecs; let's bail out
|
||||
result = B_BUFFER_OVERFLOW;
|
||||
goto bi;
|
||||
}
|
||||
|
||||
bytes_read += amt;
|
||||
|
||||
if (bytes_read < len)
|
||||
if ((result = iter_csi(&iter, 1)) != B_OK) {
|
||||
dprintf("dosfs_get_file_map: end of file reached\n");
|
||||
result = EIO;
|
||||
goto bi;
|
||||
}
|
||||
}
|
||||
|
||||
// read middle sectors
|
||||
while (bytes_read + vol->bytes_per_sector <= len) {
|
||||
struct csi old_csi;
|
||||
uint32 sectors = 1;
|
||||
off_t block = csi_to_block(&iter);
|
||||
status_t err;
|
||||
|
||||
while (1) {
|
||||
old_csi = iter;
|
||||
err = iter_csi(&iter, 1);
|
||||
if ((len - bytes_read) < (sectors + 1) * iter.vol->bytes_per_sector)
|
||||
break;
|
||||
if ((err < B_OK) || (block + sectors != csi_to_block(&iter)))
|
||||
break;
|
||||
sectors++;
|
||||
}
|
||||
|
||||
vecs[index].offset = block * vol->bytes_per_sector;
|
||||
vecs[index].length = sectors * vol->bytes_per_sector;
|
||||
bytes_read += sectors * vol->bytes_per_sector;
|
||||
index++;
|
||||
iter = old_csi;
|
||||
|
||||
if (index >= max) {
|
||||
// we're out of file_io_vecs; let's bail out
|
||||
result = B_BUFFER_OVERFLOW;
|
||||
goto bi;
|
||||
}
|
||||
|
||||
if (bytes_read < len)
|
||||
if ((result = iter_csi(&iter, 1)) != B_OK) {
|
||||
dprintf("dosfs_get_file_map: end of file reached\n");
|
||||
result = EIO;
|
||||
goto bi;
|
||||
}
|
||||
}
|
||||
|
||||
// read part of remaining sector if needed
|
||||
if (bytes_read < len) {
|
||||
size_t amt = len - bytes_read;
|
||||
vecs[index].offset = csi_to_block(&iter) * vol->bytes_per_sector;
|
||||
vecs[index].length = amt;
|
||||
index++;
|
||||
bytes_read += amt;
|
||||
|
||||
if (index >= max) {
|
||||
// we're out of file_io_vecs; let's bail out
|
||||
result = B_BUFFER_OVERFLOW;
|
||||
goto bi;
|
||||
}
|
||||
}
|
||||
|
||||
result = B_OK;
|
||||
bi:
|
||||
*_count = index;
|
||||
|
||||
if (result != B_OK) {
|
||||
DPRINTF(0, ("dosfs_get_file_map (%s)\n", strerror(result)));
|
||||
}
|
||||
UNLOCK_VOL(vol);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -7,24 +7,27 @@
|
||||
|
||||
status_t write_vnode_entry(nspace *vol, vnode *node);
|
||||
|
||||
int dosfs_write_vnode(void *_vol, void *_node, char r);
|
||||
int dosfs_rstat(void *_vol, void *_node, struct stat *st);
|
||||
int dosfs_open(void *_vol, void *_node, int omode, void **cookie);
|
||||
int dosfs_read(void *_vol, void *_node, void *cookie, off_t pos,
|
||||
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);
|
||||
int dosfs_free_cookie(void *vol, void *node, void *cookie);
|
||||
int dosfs_close(void *vol, void *node, void *cookie);
|
||||
status_t dosfs_free_cookie(void *vol, void *node, void *cookie);
|
||||
status_t dosfs_close(void *vol, void *node, void *cookie);
|
||||
|
||||
int dosfs_remove_vnode(void *vol, void *node, char r);
|
||||
int dosfs_create(void *vol, void *dir, const char *name,
|
||||
int perms, int omode, vnode_id *vnid, void **cookie);
|
||||
int dosfs_mkdir(void *vol, void *dir, const char *name, int perms);
|
||||
int dosfs_rename(void *vol, void *olddir, const char *oldname,
|
||||
status_t dosfs_remove_vnode(void *vol, void *node, bool reenter);
|
||||
status_t dosfs_create(void *vol, void *dir, const char *name,
|
||||
int omode, int perms, void **cookie, vnode_id *vnid);
|
||||
status_t dosfs_mkdir(void *vol, void *dir, const char *name, int perms, vnode_id *_vnid);
|
||||
status_t dosfs_rename(void *vol, void *olddir, const char *oldname,
|
||||
void *newdir, const char *newname);
|
||||
int dosfs_unlink(void *vol, void *dir, const char *name);
|
||||
int dosfs_rmdir(void *vol, void *dir, const char *name);
|
||||
int dosfs_wstat(void *vol, void *node, struct stat *st, long mask);
|
||||
int dosfs_write(void *vol, void *node, void *cookie, off_t pos,
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
@ -1,245 +0,0 @@
|
||||
/*
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef _FSPROTO_H
|
||||
#define _FSPROTO_H
|
||||
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <iovec.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <fs_attr.h>
|
||||
#include <fs_info.h>
|
||||
#include <BeBuild.h>
|
||||
#include <Drivers.h>
|
||||
|
||||
typedef dev_t nspace_id;
|
||||
typedef ino_t vnode_id;
|
||||
|
||||
/*
|
||||
* PUBLIC PART OF THE FILE SYSTEM PROTOCOL
|
||||
*/
|
||||
|
||||
#define WSTAT_MODE 0x0001
|
||||
#define WSTAT_UID 0x0002
|
||||
#define WSTAT_GID 0x0004
|
||||
#define WSTAT_SIZE 0x0008
|
||||
#define WSTAT_ATIME 0x0010
|
||||
#define WSTAT_MTIME 0x0020
|
||||
#define WSTAT_CRTIME 0x0040
|
||||
|
||||
#define WFSSTAT_NAME 0x0001
|
||||
|
||||
#define B_ENTRY_CREATED 1
|
||||
#define B_ENTRY_REMOVED 2
|
||||
#define B_ENTRY_MOVED 3
|
||||
#define B_STAT_CHANGED 4
|
||||
#define B_ATTR_CHANGED 5
|
||||
#define B_DEVICE_MOUNTED 6
|
||||
#define B_DEVICE_UNMOUNTED 7
|
||||
|
||||
#define B_STOP_WATCHING 0x0000
|
||||
#define B_WATCH_NAME 0x0001
|
||||
#define B_WATCH_STAT 0x0002
|
||||
#define B_WATCH_ATTR 0x0004
|
||||
#define B_WATCH_DIRECTORY 0x0008
|
||||
|
||||
#define SELECT_READ 1
|
||||
#define SELECT_WRITE 2
|
||||
#define SELECT_EXCEPTION 3
|
||||
|
||||
#define B_CUR_FS_API_VERSION 2
|
||||
|
||||
struct attr_info;
|
||||
struct index_info;
|
||||
|
||||
typedef int op_read_vnode(void *ns, vnode_id vnid, char r, void **node);
|
||||
typedef int op_write_vnode(void *ns, void *node, char r);
|
||||
typedef int op_remove_vnode(void *ns, void *node, char r);
|
||||
typedef int op_secure_vnode(void *ns, void *node);
|
||||
|
||||
typedef int op_walk(void *ns, void *base, const char *file, char **newpath,
|
||||
vnode_id *vnid);
|
||||
|
||||
typedef int op_access(void *ns, void *node, int mode);
|
||||
|
||||
typedef int op_create(void *ns, void *dir, const char *name,
|
||||
int omode, int perms, vnode_id *vnid, void **cookie);
|
||||
typedef int op_mkdir(void *ns, void *dir, const char *name, int perms);
|
||||
typedef int op_symlink(void *ns, void *dir, const char *name,
|
||||
const char *path);
|
||||
typedef int op_link(void *ns, void *dir, const char *name, void *node);
|
||||
|
||||
typedef int op_rename(void *ns, void *olddir, const char *oldname,
|
||||
void *newdir, const char *newname);
|
||||
typedef int op_unlink(void *ns, void *dir, const char *name);
|
||||
typedef int op_rmdir(void *ns, void *dir, const char *name);
|
||||
|
||||
typedef int op_readlink(void *ns, void *node, char *buf, size_t *bufsize);
|
||||
|
||||
typedef int op_opendir(void *ns, void *node, void **cookie);
|
||||
typedef int op_closedir(void *ns, void *node, void *cookie);
|
||||
typedef int op_rewinddir(void *ns, void *node, void *cookie);
|
||||
typedef int op_readdir(void *ns, void *node, void *cookie, long *num,
|
||||
struct dirent *buf, size_t bufsize);
|
||||
|
||||
typedef int op_open(void *ns, void *node, int omode, void **cookie);
|
||||
typedef int op_close(void *ns, void *node, void *cookie);
|
||||
typedef int op_free_cookie(void *ns, void *node, void *cookie);
|
||||
typedef int op_read(void *ns, void *node, void *cookie, off_t pos, void *buf,
|
||||
size_t *len);
|
||||
typedef int op_write(void *ns, void *node, void *cookie, off_t pos,
|
||||
const void *buf, size_t *len);
|
||||
typedef int op_readv(void *ns, void *node, void *cookie, off_t pos, const iovec *vec,
|
||||
size_t count, size_t *len);
|
||||
typedef int op_writev(void *ns, void *node, void *cookie, off_t pos, const iovec *vec,
|
||||
size_t count, size_t *len);
|
||||
typedef int op_ioctl(void *ns, void *node, void *cookie, int cmd, void *buf,
|
||||
size_t len);
|
||||
typedef int op_setflags(void *ns, void *node, void *cookie, int flags);
|
||||
|
||||
typedef int op_rstat(void *ns, void *node, struct stat *);
|
||||
typedef int op_wstat(void *ns, void *node, struct stat *, long mask);
|
||||
typedef int op_fsync(void *ns, void *node);
|
||||
|
||||
typedef int op_select(void *ns, void *node, void *cookie, uint8 event,
|
||||
uint32 ref, selectsync *sync);
|
||||
typedef int op_deselect(void *ns, void *node, void *cookie, uint8 event,
|
||||
selectsync *sync);
|
||||
|
||||
typedef int op_initialize(const char *devname, void *parms, size_t len);
|
||||
typedef int op_mount(nspace_id nsid, const char *devname, ulong flags,
|
||||
void *parms, size_t len, void **data, vnode_id *vnid);
|
||||
typedef int op_unmount(void *ns);
|
||||
typedef int op_sync(void *ns);
|
||||
typedef int op_rfsstat(void *ns, struct fs_info *);
|
||||
typedef int op_wfsstat(void *ns, struct fs_info *, long mask);
|
||||
|
||||
|
||||
typedef int op_open_attrdir(void *ns, void *node, void **cookie);
|
||||
typedef int op_close_attrdir(void *ns, void *node, void *cookie);
|
||||
typedef int op_rewind_attrdir(void *ns, void *node, void *cookie);
|
||||
typedef int op_read_attrdir(void *ns, void *node, void *cookie, long *num,
|
||||
struct dirent *buf, size_t bufsize);
|
||||
typedef int op_remove_attr(void *ns, void *node, const char *name);
|
||||
typedef int op_rename_attr(void *ns, void *node, const char *oldname,
|
||||
const char *newname);
|
||||
typedef int op_stat_attr(void *ns, void *node, const char *name,
|
||||
struct attr_info *buf);
|
||||
|
||||
typedef int op_write_attr(void *ns, void *node, const char *name, int type,
|
||||
const void *buf, size_t *len, off_t pos);
|
||||
typedef int op_read_attr(void *ns, void *node, const char *name, int type,
|
||||
void *buf, size_t *len, off_t pos);
|
||||
|
||||
typedef int op_open_indexdir(void *ns, void **cookie);
|
||||
typedef int op_close_indexdir(void *ns, void *cookie);
|
||||
typedef int op_rewind_indexdir(void *ns, void *cookie);
|
||||
typedef int op_read_indexdir(void *ns, void *cookie, long *num,
|
||||
struct dirent *buf, size_t bufsize);
|
||||
typedef int op_create_index(void *ns, const char *name, int type, int flags);
|
||||
typedef int op_remove_index(void *ns, const char *name);
|
||||
typedef int op_rename_index(void *ns, const char *oldname,
|
||||
const char *newname);
|
||||
typedef int op_stat_index(void *ns, const char *name, struct index_info *buf);
|
||||
|
||||
typedef int op_open_query(void *ns, const char *query, ulong flags,
|
||||
port_id port, long token, void **cookie);
|
||||
typedef int op_close_query(void *ns, void *cookie);
|
||||
typedef int op_read_query(void *ns, void *cookie, long *num,
|
||||
struct dirent *buf, size_t bufsize);
|
||||
|
||||
typedef struct vnode_ops {
|
||||
op_read_vnode (*read_vnode);
|
||||
op_write_vnode (*write_vnode);
|
||||
op_remove_vnode (*remove_vnode);
|
||||
op_secure_vnode (*secure_vnode);
|
||||
op_walk (*walk);
|
||||
op_access (*access);
|
||||
op_create (*create);
|
||||
op_mkdir (*mkdir);
|
||||
op_symlink (*symlink);
|
||||
op_link (*link);
|
||||
op_rename (*rename);
|
||||
op_unlink (*unlink);
|
||||
op_rmdir (*rmdir);
|
||||
op_readlink (*readlink);
|
||||
op_opendir (*opendir);
|
||||
op_closedir (*closedir);
|
||||
op_free_cookie (*free_dircookie);
|
||||
op_rewinddir (*rewinddir);
|
||||
op_readdir (*readdir);
|
||||
op_open (*open);
|
||||
op_close (*close);
|
||||
op_free_cookie (*free_cookie);
|
||||
op_read (*read);
|
||||
op_write (*write);
|
||||
op_readv (*readv);
|
||||
op_writev (*writev);
|
||||
op_ioctl (*ioctl);
|
||||
op_setflags (*setflags);
|
||||
op_rstat (*rstat);
|
||||
op_wstat (*wstat);
|
||||
op_fsync (*fsync);
|
||||
op_initialize (*initialize);
|
||||
op_mount (*mount);
|
||||
op_unmount (*unmount);
|
||||
op_sync (*sync);
|
||||
op_rfsstat (*rfsstat);
|
||||
op_wfsstat (*wfsstat);
|
||||
op_select (*select);
|
||||
op_deselect (*deselect);
|
||||
op_open_indexdir (*open_indexdir);
|
||||
op_close_indexdir (*close_indexdir);
|
||||
op_free_cookie (*free_indexdircookie);
|
||||
op_rewind_indexdir (*rewind_indexdir);
|
||||
op_read_indexdir (*read_indexdir);
|
||||
op_create_index (*create_index);
|
||||
op_remove_index (*remove_index);
|
||||
op_rename_index (*rename_index);
|
||||
op_stat_index (*stat_index);
|
||||
op_open_attrdir (*open_attrdir);
|
||||
op_close_attrdir (*close_attrdir);
|
||||
op_free_cookie (*free_attrdircookie);
|
||||
op_rewind_attrdir (*rewind_attrdir);
|
||||
op_read_attrdir (*read_attrdir);
|
||||
op_write_attr (*write_attr);
|
||||
op_read_attr (*read_attr);
|
||||
op_remove_attr (*remove_attr);
|
||||
op_rename_attr (*rename_attr);
|
||||
op_stat_attr (*stat_attr);
|
||||
op_open_query (*open_query);
|
||||
op_close_query (*close_query);
|
||||
op_free_cookie (*free_querycookie);
|
||||
op_read_query (*read_query);
|
||||
} vnode_ops;
|
||||
|
||||
extern _IMPEXP_KERNEL int new_path(const char *path, char **copy);
|
||||
extern _IMPEXP_KERNEL void free_path(char *p);
|
||||
|
||||
extern _IMPEXP_KERNEL int notify_listener(int op, nspace_id nsid,
|
||||
vnode_id vnida, vnode_id vnidb,
|
||||
vnode_id vnidc, const char *name);
|
||||
extern _IMPEXP_KERNEL int send_notification(port_id port, long token,
|
||||
ulong what, long op, nspace_id nsida,
|
||||
nspace_id nsidb, vnode_id vnida,
|
||||
vnode_id vnidb, vnode_id vnidc,
|
||||
const char *name);
|
||||
extern _IMPEXP_KERNEL int get_vnode(nspace_id nsid, vnode_id vnid, void **data);
|
||||
extern _IMPEXP_KERNEL int put_vnode(nspace_id nsid, vnode_id vnid);
|
||||
extern _IMPEXP_KERNEL int new_vnode(nspace_id nsid, vnode_id vnid, void *data);
|
||||
extern _IMPEXP_KERNEL int remove_vnode(nspace_id nsid, vnode_id vnid);
|
||||
extern _IMPEXP_KERNEL int unremove_vnode(nspace_id nsid, vnode_id vnid);
|
||||
extern _IMPEXP_KERNEL int is_vnode_removed(nspace_id nsid, vnode_id vnid);
|
||||
|
||||
|
||||
extern _EXPORT vnode_ops fs_entry;
|
||||
extern _EXPORT int32 api_version;
|
||||
|
||||
#endif
|
@ -2,11 +2,10 @@
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
#include <KernelExport.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <lock.h>
|
||||
#include <cache.h>
|
||||
#include <fs_cache.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "iter.h"
|
||||
#include "dosfs.h"
|
||||
@ -34,7 +33,7 @@ static int _validate_cs_(nspace *vol, uint32 cluster, uint32 sector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static off_t _csi_to_block_(struct csi *csi)
|
||||
off_t csi_to_block(struct csi *csi)
|
||||
{
|
||||
// presumes the caller has already called _validate_cs_ on the argument
|
||||
ASSERT(_validate_cs_(csi->vol, csi->cluster, csi->sector) == 0);
|
||||
@ -97,37 +96,34 @@ int iter_csi(struct csi *csi, int sectors)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8 *csi_get_block(struct csi *csi)
|
||||
uint8 *csi_get_block(struct csi *csi, int32 tid)
|
||||
{
|
||||
if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
|
||||
return NULL;
|
||||
|
||||
return get_block(csi->vol->fd, _csi_to_block_(csi), csi->vol->bytes_per_sector);
|
||||
return block_cache_get_writable_etc(csi->vol->fBlockCache, csi_to_block(csi),
|
||||
1, csi->vol->bytes_per_sector, tid);
|
||||
}
|
||||
|
||||
status_t csi_release_block(struct csi *csi)
|
||||
{
|
||||
status_t err;
|
||||
|
||||
if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
|
||||
return EINVAL;
|
||||
|
||||
err = release_block(csi->vol->fd, _csi_to_block_(csi));
|
||||
ASSERT(err == B_OK);
|
||||
return err;
|
||||
block_cache_put(csi->vol->fBlockCache, csi_to_block(csi));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t csi_mark_block_dirty(struct csi *csi)
|
||||
status_t csi_mark_block_dirty(struct csi *csi, int32 tid)
|
||||
{
|
||||
status_t err;
|
||||
|
||||
ASSERT(_validate_cs_(csi->vol, csi->cluster, csi->sector) == 0);
|
||||
if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
|
||||
return EINVAL;
|
||||
|
||||
err = mark_blocks_dirty(csi->vol->fd, _csi_to_block_(csi), 1);
|
||||
ASSERT(err == B_OK);
|
||||
return err;
|
||||
// TODO : block_cache doesn't implement this
|
||||
//block_cache_set_dirty(csi->vol->fBlockCache, csi_to_block(csi), true, tid);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/* XXX: not the most efficient implementation, but it gets the job done */
|
||||
@ -137,28 +133,33 @@ status_t csi_read_blocks(struct csi *csi, uint8 *buffer, ssize_t len)
|
||||
uint32 sectors;
|
||||
off_t block;
|
||||
status_t err;
|
||||
|
||||
char *buf = buffer;
|
||||
int32 i;
|
||||
|
||||
ASSERT(len >= csi->vol->bytes_per_sector);
|
||||
|
||||
if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
|
||||
return EINVAL;
|
||||
|
||||
sectors = 1;
|
||||
block = _csi_to_block_(csi);
|
||||
block = csi_to_block(csi);
|
||||
|
||||
while (1) {
|
||||
old_csi = *csi;
|
||||
err = iter_csi(csi, 1);
|
||||
if (len < (sectors + 1) * csi->vol->bytes_per_sector)
|
||||
break;
|
||||
if ((err < B_OK) || (block + sectors != _csi_to_block_(csi)))
|
||||
if ((err < B_OK) || (block + sectors != csi_to_block(csi)))
|
||||
break;
|
||||
sectors++;
|
||||
}
|
||||
|
||||
err = cached_read(csi->vol->fd, block, buffer, sectors, csi->vol->bytes_per_sector);
|
||||
if (err < B_OK)
|
||||
return err;
|
||||
for (i=block; i<block+sectors; i++) {
|
||||
char *blockData = (char *)block_cache_get(csi->vol->fBlockCache, i);
|
||||
memcpy(buf, blockData, csi->vol->bytes_per_sector);
|
||||
buf += csi->vol->bytes_per_sector;
|
||||
block_cache_put(csi->vol->fBlockCache, i);
|
||||
}
|
||||
|
||||
*csi = old_csi;
|
||||
|
||||
@ -171,6 +172,8 @@ status_t csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len)
|
||||
uint32 sectors;
|
||||
off_t block;
|
||||
status_t err;
|
||||
char *buf = buffer;
|
||||
int32 i, tid;
|
||||
|
||||
ASSERT(len >= csi->vol->bytes_per_sector);
|
||||
|
||||
@ -179,21 +182,26 @@ status_t csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len)
|
||||
return EINVAL;
|
||||
|
||||
sectors = 1;
|
||||
block = _csi_to_block_(csi);
|
||||
block = csi_to_block(csi);
|
||||
|
||||
while (1) {
|
||||
old_csi = *csi;
|
||||
err = iter_csi(csi, 1);
|
||||
if (len < (sectors + 1) * csi->vol->bytes_per_sector)
|
||||
break;
|
||||
if ((err < B_OK) || (block + sectors != _csi_to_block_(csi)))
|
||||
if ((err < B_OK) || (block + sectors != csi_to_block(csi)))
|
||||
break;
|
||||
sectors++;
|
||||
}
|
||||
|
||||
err = cached_write(csi->vol->fd, block, buffer, sectors, csi->vol->bytes_per_sector);
|
||||
if (err < B_OK)
|
||||
return err;
|
||||
|
||||
tid = cache_start_transaction(csi->vol->fBlockCache);
|
||||
for(i=block; i<block+sectors; i++) {
|
||||
char *blockData = block_cache_get_writable_etc(csi->vol->fBlockCache, i, 0, 1, tid);
|
||||
memcpy(blockData, buf, csi->vol->bytes_per_sector);
|
||||
buf += csi->vol->bytes_per_sector;
|
||||
block_cache_put(csi->vol->fBlockCache, i);
|
||||
}
|
||||
cache_end_transaction(csi->vol->fBlockCache, tid, NULL, NULL);
|
||||
|
||||
/* return the last state of the iterator because that's what dosfs_write
|
||||
* expects. this lets it meaningfully cache the state even when it's
|
||||
@ -205,11 +213,23 @@ status_t csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len)
|
||||
|
||||
status_t csi_write_block(struct csi *csi, uint8 *buffer)
|
||||
{
|
||||
off_t block;
|
||||
int32 tid;
|
||||
char *blockData;
|
||||
|
||||
block = csi_to_block(csi);
|
||||
|
||||
ASSERT(_validate_cs_(csi->vol, csi->cluster, csi->sector) == 0);
|
||||
if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
|
||||
return EINVAL;
|
||||
|
||||
tid = cache_start_transaction(csi->vol->fBlockCache);
|
||||
blockData = block_cache_get_writable_etc(csi->vol->fBlockCache, block, 0, 1, tid);
|
||||
memcpy(blockData, buffer, csi->vol->bytes_per_sector);
|
||||
block_cache_put(csi->vol->fBlockCache, block);
|
||||
cache_end_transaction(csi->vol->fBlockCache, tid, NULL, NULL);
|
||||
|
||||
return cached_write(csi->vol->fd, _csi_to_block_(csi), buffer, 1, csi->vol->bytes_per_sector);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static void _diri_release_current_block_(struct diri *diri)
|
||||
@ -238,9 +258,11 @@ uint8 *diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri)
|
||||
if (iter_csi(&(diri->csi), diri->current_index / (vol->bytes_per_sector / 0x20)) != 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diri->tid = cache_start_transaction(diri->csi.vol->fBlockCache);
|
||||
|
||||
// get current sector
|
||||
diri->current_block = csi_get_block(&(diri->csi));
|
||||
diri->current_block = csi_get_block(&(diri->csi), diri->tid);
|
||||
|
||||
if (diri->current_block == NULL)
|
||||
return NULL;
|
||||
@ -256,6 +278,8 @@ int diri_free(struct diri *diri)
|
||||
|
||||
if (diri->current_block)
|
||||
_diri_release_current_block_(diri);
|
||||
|
||||
cache_end_transaction(diri->csi.vol->fBlockCache, diri->tid, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -281,7 +305,7 @@ uint8 *diri_next_entry(struct diri *diri)
|
||||
_diri_release_current_block_(diri);
|
||||
if (iter_csi(&(diri->csi), 1) != 0)
|
||||
return NULL;
|
||||
diri->current_block = csi_get_block(&(diri->csi));
|
||||
diri->current_block = csi_get_block(&(diri->csi), diri->tid);
|
||||
if (diri->current_block == NULL)
|
||||
return NULL;
|
||||
}
|
||||
@ -298,7 +322,7 @@ uint8 *diri_rewind(struct diri *diri)
|
||||
_diri_release_current_block_(diri);
|
||||
if (init_csi(diri->csi.vol, diri->starting_cluster, 0, &(diri->csi)) != 0)
|
||||
return NULL;
|
||||
diri->current_block = csi_get_block(&(diri->csi));
|
||||
diri->current_block = csi_get_block(&(diri->csi), diri->tid);
|
||||
}
|
||||
diri->current_index = 0;
|
||||
return diri->current_block;
|
||||
@ -306,5 +330,5 @@ uint8 *diri_rewind(struct diri *diri)
|
||||
|
||||
void diri_mark_dirty(struct diri *diri)
|
||||
{
|
||||
csi_mark_block_dirty(&(diri->csi));
|
||||
csi_mark_block_dirty(&(diri->csi), diri->tid);
|
||||
}
|
||||
|
@ -15,11 +15,12 @@ struct csi
|
||||
uint32 sector;
|
||||
};
|
||||
|
||||
off_t csi_to_block(struct csi *csi);
|
||||
int init_csi(struct _nspace *vol, uint32 cluster, uint32 sector, struct csi *csi);
|
||||
int iter_csi(struct csi *csi, int sectors);
|
||||
uint8 *csi_get_block(struct csi *csi);
|
||||
uint8 *csi_get_block(struct csi *csi, int32 tid);
|
||||
status_t csi_release_block(struct csi *csi);
|
||||
status_t csi_mark_block_dirty(struct csi *csi);
|
||||
status_t csi_mark_block_dirty(struct csi *csi, int32 tid);
|
||||
status_t csi_read_blocks(struct csi *csi, uint8 *buffer, ssize_t len);
|
||||
status_t csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len);
|
||||
status_t csi_write_block(struct csi *csi, uint8 *buffer);
|
||||
@ -33,6 +34,7 @@ struct diri
|
||||
uint32 starting_cluster;
|
||||
uint32 current_index;
|
||||
uint8 *current_block;
|
||||
int32 tid;
|
||||
};
|
||||
|
||||
uint8 *diri_init(struct _nspace *vol, uint32 cluster, uint32 index, struct diri *diri);
|
||||
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef _ALLOC_H
|
||||
#define _ALLOC_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#if KMALLOC_TRACKING
|
||||
extern bool kmalloc_tracking_enabled;
|
||||
#endif
|
||||
|
||||
extern void init_malloc(void);
|
||||
extern void init_smalloc(void);
|
||||
|
||||
extern void * smalloc(unsigned int nbytes);
|
||||
extern void sfree(void *ptr);
|
||||
extern void * scalloc(unsigned int nobj, unsigned int size);
|
||||
extern void * srealloc(void *p, unsigned int newsize);
|
||||
|
||||
#endif
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef _LOCK_H
|
||||
#define _LOCK_H
|
||||
|
||||
#include <BeBuild.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct lock lock;
|
||||
typedef struct mlock mlock;
|
||||
|
||||
struct lock {
|
||||
sem_id s;
|
||||
long c;
|
||||
};
|
||||
|
||||
struct mlock {
|
||||
sem_id s;
|
||||
};
|
||||
|
||||
extern _IMPEXP_KERNEL int new_lock(lock *l, const char *name);
|
||||
extern _IMPEXP_KERNEL int free_lock(lock *l);
|
||||
|
||||
#define LOCK(l) if (atomic_add(&l.c, -1) <= 0) acquire_sem(l.s);
|
||||
#define UNLOCK(l) if (atomic_add(&l.c, 1) < 0) release_sem(l.s);
|
||||
|
||||
extern _IMPEXP_KERNEL int new_mlock(mlock *l, long c, const char *name);
|
||||
extern _IMPEXP_KERNEL int free_mlock(mlock *l);
|
||||
|
||||
#define LOCKM(l,cnt) acquire_sem_etc(l.s, cnt, 0, 0)
|
||||
#define UNLOCKM(l,cnt) release_sem_etc(l.s, cnt, 0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
@ -9,8 +9,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <rtc_info.h>
|
||||
#include "rtc_info.h"
|
||||
|
||||
#include "dosfs.h"
|
||||
#include "fat.h"
|
||||
@ -18,6 +17,8 @@
|
||||
|
||||
static int32 tzoffset = -1; /* in minutes */
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
int _assert_(char *a, int b, char *c)
|
||||
{
|
||||
dprintf("tripped assertion in %s/%d (%s)\n", a, b, c);
|
||||
@ -25,6 +26,8 @@ int _assert_(char *a, int b, char *c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void print_byte(uint8 c)
|
||||
{
|
||||
dprintf("%c", ((c >= ' ') && (c <= '~')) ? c : '.');
|
||||
|
@ -8,13 +8,14 @@
|
||||
#include <ByteOrder.h>
|
||||
|
||||
// debugging functions
|
||||
|
||||
#ifndef ASSERT
|
||||
#ifndef DEBUG
|
||||
#define ASSERT(c) ((void)0)
|
||||
#else
|
||||
int _assert_(char *,int,char *);
|
||||
#define ASSERT(c) (!(c) ? _assert_(__FILE__,__LINE__,#c) : 0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void dump_bytes(uint8 *buffer, uint32 count);
|
||||
void dump_directory(uint8 *buffer);
|
||||
|
@ -50,7 +50,6 @@ purpose.
|
||||
#define UNLOCK_CACHE_W \
|
||||
release_sem_etc(vol->vcache.vc_sem, READERS, 0)
|
||||
|
||||
#include <fsproto.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@ -358,12 +357,12 @@ status_t vcache_set_entry(nspace *vol, vnode_id vnid, vnode_id loc)
|
||||
|
||||
DPRINTF(0, ("vcache_set_entry: %Lx -> %Lx\n", vnid, loc));
|
||||
|
||||
if (is_vnode_removed(vol->id, vnid) > 0) {
|
||||
/*if (is_vnode_removed(vol->id, vnid) > 0) {
|
||||
if (!IS_ARTIFICIAL_VNID(loc))
|
||||
return B_OK;
|
||||
} else {
|
||||
ASSERT(is_vnode_removed(vol->id, vnid) == 0);
|
||||
}
|
||||
}*/
|
||||
|
||||
LOCK_CACHE_W;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user