* Removed the superfluous "magic" stuff - if structures are broken, then please

let it crash!
* Made some headers self-contained.
* Always lock, regardless of "reenter" (we're using a recursive lock, so this
  doesn't matter at all).
* Some cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31913 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-07-29 15:40:28 +00:00
parent d7737cc84f
commit 3f1684d92c
11 changed files with 101 additions and 384 deletions

View File

@ -2,7 +2,8 @@
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
/* attr.c
/*
* handles mime type information for dosfs
* gets/sets mime information in vnode
*/
@ -67,11 +68,6 @@ dosfs_open_attrdir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_open_attrdir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
if ((*_cookie = malloc(sizeof(uint32))) == NULL) {
UNLOCK_VOL(vol);
return ENOMEM;
@ -95,11 +91,6 @@ dosfs_close_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_open_attrdir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
*(int32 *)_cookie = 1;
UNLOCK_VOL(vol);
@ -160,12 +151,6 @@ dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_read_attrdir") ||
check_vnode_magic(node, "dosfs_read_attrdir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
if ((*cookie == 0) && (node->mime)) {
*num = 1;
@ -235,12 +220,6 @@ dosfs_read_attr_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_read_attr_stat") ||
check_vnode_magic(node, "dosfs_read_attr_stat")) {
UNLOCK_VOL(vol);
return EINVAL;
}
if (node->mime == NULL) {
UNLOCK_VOL(vol);
return ENOENT;
@ -268,12 +247,6 @@ dosfs_read_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_read_attr") ||
check_vnode_magic(node, "dosfs_read_attr")) {
UNLOCK_VOL(vol);
return EINVAL;
}
if (node->mime == NULL) {
UNLOCK_VOL(vol);
return ENOENT;

View File

@ -3,20 +3,21 @@
This file may be used under the terms of the Be Sample Code License.
*/
#include <KernelExport.h>
#include "dir.h"
#include <stdlib.h>
#include <dirent.h>
#include <fs_cache.h>
#include <fs_info.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <fs_cache.h>
#include <fs_info.h>
#include <KernelExport.h>
#include "iter.h"
#include "dosfs.h"
#include "attr.h"
#include "dir.h"
#include "dlist.h"
#include "fat.h"
#include "util.h"
@ -31,17 +32,14 @@
const char acceptable[]="!#$%&'()-0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`{}~";
const char illegal[] = "\\/:*?\"<>|";
#define DIRCOOKIE_MAGIC 'AiC '
typedef struct dircookie {
uint32 magic;
uint32 current_index;
} dircookie;
static CHECK_MAGIC(dircookie,struct dircookie, DIRCOOKIE_MAGIC)
static status_t findfile(nspace *vol, vnode *dir, const char *file,
ino_t *vnid, vnode **node, bool check_case,
bool check_dups, bool *dups_exist);
ino_t *vnid, vnode **node, bool check_case, bool check_dups,
bool *dups_exist);
// private structure for returning data from _next_dirent_()
struct _dirent_info_ {
@ -53,7 +51,8 @@ struct _dirent_info_ {
uint32 time;
};
// scans dir for the next entry, using the state stored in a struct diri.
//! Scans dir for the next entry, using the state stored in a struct diri.
static status_t
_next_dirent_(struct diri *iter, struct _dirent_info_ *oinfo, char *filename,
int len)
@ -67,9 +66,6 @@ _next_dirent_(struct diri *iter, struct _dirent_info_ *oinfo, char *filename,
uint32 start_index = 0xffff, filename_len = 0; /* quiet warning */
uint32 lfn_count = 0 /* quiet warning */;
if (check_diri_magic(iter, "_next_dirent_"))
return EINVAL;
if (iter->current_block == NULL)
return ENOENT;
@ -212,9 +208,6 @@ get_next_dirent(nspace *vol, vnode *dir, struct diri *iter, ino_t *vnid,
struct _dirent_info_ info;
status_t result;
if (check_nspace_magic(vol, "get_next_dirent"))
return EINVAL;
do {
result = _next_dirent_(iter, &info, filename, len);
if (result < 0)
@ -281,11 +274,6 @@ check_dir_empty(nspace *vol, vnode *dir)
struct diri iter;
status_t result = B_ERROR; /* quiet warning */
if (check_nspace_magic(vol, "check_dir_empty"))
return EINVAL;
if (check_vnode_magic(dir, "check_dir_empty"))
return EINVAL;
if (diri_init(vol, dir->cluster, 0, &iter) == NULL) {
dprintf("check_dir_empty: error opening directory\n");
return B_ERROR;
@ -372,11 +360,6 @@ findfile(nspace *vol, vnode *dir, const char *file, ino_t *vnid,
// dprintf("findfile: %s in %Lx, case %d dups %d\n", file, dir->vnid, check_case, check_dups);
if (check_nspace_magic(vol, "findfile"))
return EINVAL;
if (check_vnode_magic(dir, "findfile"))
return EINVAL;
DPRINTF(1, ("findfile: %s in %Lx\n", file, dir->vnid));
if (dups_exist != NULL)
@ -676,8 +659,8 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info,
*ne = *ns + required_entries - 1;
for (i = *ns; i <= *ne; i++) {
ASSERT(find_loc_in_vcache(vol, \
GENERATE_DIR_INDEX_VNID(dir->cluster, i)) == ENOENT);
ASSERT(find_loc_in_vcache(vol,
GENERATE_DIR_INDEX_VNID(dir->cluster, i)) == ENOENT);
}
DPRINTF(0, ("directory entry runs from %lx to %lx (dirsize = %Lx) (is%s last entry)\n", *ns, *ne, dir->st_size, last_entry ? "" : "n't"));
@ -934,19 +917,12 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
struct diri iter;
char filename[512]; /* need this for setting mime type */
if (!reenter) {
LOCK_VOL(vol);
}
LOCK_VOL(vol);
_node->private_node = NULL;
_node->ops = &gFATVnodeOps;
_flags = 0;
if (check_nspace_magic(vol, "dosfs_read_vnode")) {
if (!reenter) UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_read_vnode (vnode id %Lx)\n", vnid));
if (vnid == vol->root_vnode.vnid) {
@ -1008,7 +984,6 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
goto bi2;
}
entry->magic = VNODE_MAGIC;
entry->vnid = vnid;
entry->dir_vnid = dir_vnid;
entry->disk_image = 0;
@ -1054,8 +1029,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
bi2:
diri_free(&iter);
bi:
if (!reenter)
UNLOCK_VOL(vol);
UNLOCK_VOL(vol);
if (result != B_OK)
DPRINTF(0, ("dosfs_read_vnode (%s)\n", strerror(result)));
@ -1076,12 +1050,6 @@ dosfs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *_vnid)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_walk") ||
check_vnode_magic(dir, "dosfs_walk")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_walk: find %Lx/%s\n", dir->vnid, file));
result = findfile_case(vol, dir, file, _vnid, &vnode);
@ -1106,23 +1074,17 @@ dosfs_access(fs_volume *_vol, fs_vnode *_node, int mode)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_access")
|| check_vnode_magic(node, "dosfs_access")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_access (vnode id %Lx, mode %x)\n", node->vnid, mode));
if (mode & W_OK) {
if (vol->flags & B_FS_IS_READONLY) {
dprintf("dosfs_access: can't write on read-only volume\n");
DPRINTF(0, ("dosfs_access: can't write on read-only volume\n"));
result = EROFS;
} else if (node->mode & FAT_READ_ONLY) {
dprintf("can't open read-only file for writing\n");
DPRINTF(0, ("can't open read-only file for writing\n"));
result = EPERM;
} else if (node->disk_image != 0) {
dprintf("can't open disk image file for writing\n");
DPRINTF(0, ("can't open disk image file for writing\n"));
result = EPERM;
}
}
@ -1153,19 +1115,8 @@ dosfs_opendir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
dircookie *cookie = NULL;
int result;
if (_cookie == NULL) {
dprintf("dosfs_opendir called with null _cookie\n");
return EINVAL;
}
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_opendir")
|| check_vnode_magic(node, "dosfs_opendir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_opendir (vnode id %Lx)\n", node->vnid));
*_cookie = NULL;
@ -1181,12 +1132,11 @@ dosfs_opendir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
}
if ((cookie = (dircookie *)malloc(sizeof(dircookie))) == NULL) {
dprintf("dosfs_opendir: out of memory error\n");
DPRINTF(0, ("dosfs_opendir: out of memory error\n"));
result = ENOMEM;
goto bi;
}
cookie->magic = DIRCOOKIE_MAGIC;
cookie->current_index = 0;
result = B_NO_ERROR;
@ -1215,13 +1165,6 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_readdir")
|| check_vnode_magic(dir, "dosfs_readdir")
|| check_dircookie_magic(cookie, "dosfs_readdir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_readdir: vnode id %Lx, index %lx\n",
dir->vnid, cookie->current_index));
@ -1295,13 +1238,6 @@ dosfs_rewinddir(fs_volume *_vol, fs_vnode *_node, void* _cookie)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_rewinddir")
|| check_vnode_magic(node, "dosfs_rewinddir")
|| check_dircookie_magic(cookie, "dosfs_rewinddir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_rewinddir (vnode id %Lx)\n", node->vnid));
cookie->current_index = 0;
@ -1332,22 +1268,8 @@ dosfs_free_dircookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_free_dircookie")
|| check_vnode_magic(node, "dosfs_free_dircookie")
|| check_dircookie_magic((dircookie *)cookie, "dosfs_free_dircookie")) {
UNLOCK_VOL(vol);
return EINVAL;
}
if (cookie == NULL) {
dprintf("error: dosfs_free_dircookie called with null cookie\n");
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_free_dircookie (vnode id %Lx)\n", node->vnid));
cookie->magic = ~DIRCOOKIE_MAGIC;
free(cookie);
UNLOCK_VOL(vol);

View File

@ -5,6 +5,10 @@
#ifndef _DOSFS_DIR_H_
#define _DOSFS_DIR_H_
#include "dosfs.h"
bool is_filename_legal(const char *name);
status_t check_dir_empty(nspace *vol, vnode *dir);
status_t findfile_case(nspace *vol, vnode *dir, const char *file,

View File

@ -3,6 +3,9 @@
This file may be used under the terms of the Be Sample Code License.
*/
#include "dosfs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -20,7 +23,6 @@
#include <fs_cache.h>
#include <fs_volume.h>
#include "dosfs.h"
#include "attr.h"
#include "dir.h"
#include "dlist.h"
@ -30,6 +32,7 @@
#include "util.h"
#include "vcache.h"
extern const char *build_time, *build_date;
/* debug levels */
@ -39,11 +42,9 @@ int debug_attr = 0, debug_dir = 0, debug_dlist = 0, debug_dosfs = 0,
#define DPRINTF(a,b) if (debug_dosfs > (a)) dprintf b
CHECK_MAGIC(vnode,struct vnode,VNODE_MAGIC)
CHECK_MAGIC(nspace,struct _nspace, NSPACE_MAGIC)
static status_t get_fsinfo(nspace *vol, uint32 *free_count, uint32 *last_allocated);
#if DEBUG
int32 instances = 0;
@ -58,7 +59,6 @@ debug_fat_nspace(int argc, char **argv)
continue;
kprintf("fat nspace @ %p\n", vol);
kprintf("magic: %lx\n", vol->magic);
kprintf("id: %lx, fd: %x, device: %s, flags %lx\n",
vol->id, vol->fd, vol->device, vol->flags);
kprintf("bytes/sector = %lx, sectors/cluster = %lx, reserved sectors = %lx\n",
@ -82,6 +82,9 @@ debug_fat_nspace(int argc, char **argv)
vol->vcache.by_vnid, vol->vcache.by_loc);
kprintf("dlist entries: %lx/%lx @ %p\n",
vol->dlist.entries, vol->dlist.allocated, vol->dlist.vnid_list);
dump_vcache(vol);
dlist_dump(vol);
}
return B_OK;
}
@ -97,7 +100,7 @@ debug_dvnode(int argc, char **argv)
return B_OK;
}
for (i=1;i<argc;i++) {
for (i = 1; i < argc; i++) {
vnode *n = (vnode *)strtoul(argv[i], NULL, 0);
if (!n) continue;
@ -105,12 +108,11 @@ debug_dvnode(int argc, char **argv)
#if TRACK_FILENAME
kprintf(" (%s)", n->filename);
#endif
kprintf("\nmagic %lx, vnid %Lx, dir vnid %Lx\n",
n->magic, n->vnid, n->dir_vnid);
kprintf("\nvnid %Lx, dir vnid %Lx\n", n->vnid, n->dir_vnid);
kprintf("iteration %lx, si=%lx, ei=%lx, cluster=%lx\n",
n->iteration, n->sindex, n->eindex, n->cluster);
n->iteration, n->sindex, n->eindex, n->cluster);
kprintf("mode %lx, size %Lx, time %lx\n",
n->mode, n->st_size, n->st_time);
n->mode, n->st_size, n->st_time);
kprintf("end cluster = %lx\n", n->end_cluster);
if (n->mime) kprintf("mime type %s\n", n->mime);
}
@ -198,7 +200,6 @@ mount_fat_disk(const char *path, fs_volume *_vol, const int flags,
return B_NO_MEMORY;
}
vol->magic = NSPACE_MAGIC;
vol->flags = B_FS_IS_PERSISTENT | B_FS_HAS_MIME;
vol->fs_flags = fs_flags;
@ -565,9 +566,8 @@ mount_fat_disk(const char *path, fs_volume *_vol, const int flags,
}
// initialize root vnode
vol->root_vnode.magic = VNODE_MAGIC;
vol->root_vnode.vnid = vol->root_vnode.dir_vnid = GENERATE_DIR_CLUSTER_VNID(
vol->root_vnode.cluster, vol->root_vnode.cluster);
vol->root_vnode.cluster, vol->root_vnode.cluster);
vol->root_vnode.sindex = vol->root_vnode.eindex = 0xffffffff;
vol->root_vnode.mode = FAT_SUBDIR;
time(&(vol->root_vnode.st_time));
@ -779,11 +779,9 @@ dosfs_mount(fs_volume *_vol, const char *device, uint32 flags,
// Try and mount volume as a FAT volume
if ((result = mount_fat_disk(device, _vol, flags, &vol, fs_flags,
op_sync_mode)) == B_NO_ERROR) {
op_sync_mode)) == B_NO_ERROR) {
char name[32];
if (check_nspace_magic(vol, "dosfs_mount")) return EINVAL;
*_rootID = vol->root_vnode.vnid;
_vol->private_volume = (void *)vol;
_vol->ops = &gFATVolumeOps;
@ -890,11 +888,6 @@ dosfs_unmount(fs_volume *_vol)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_unmount")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_unmount volume %lx\n", vol->id));
update_fsinfo(vol);
@ -920,7 +913,6 @@ dosfs_unmount(fs_volume *_vol)
lock_removable_device(vol->fd, false);
result = close(vol->fd);
recursive_lock_destroy(&(vol->vlock));
vol->magic = ~VNODE_MAGIC;
free(vol);
#if USE_DMALLOC
@ -940,11 +932,6 @@ dosfs_read_fs_stat(fs_volume *_vol, struct fs_info * fss)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_read_fs_stat")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(1, ("dosfs_read_fs_stat called\n"));
// fss->dev and fss->root filled in by kernel
@ -999,11 +986,6 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_write_fs_stat")) {
UNLOCK_VOL(vol);
return EINVAL;
}
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
@ -1103,12 +1085,6 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, ulong code,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_ioctl") ||
check_vnode_magic(node, "dosfs_ioctl")) {
UNLOCK_VOL(vol);
return EINVAL;
}
switch (code) {
case 10002 : /* return real creation time */
if (buf) *(bigtime_t *)buf = node->st_time;
@ -1117,6 +1093,7 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, ulong code,
if (buf) *(bigtime_t *)buf = node->st_time;
break;
#if 0
/*case 69666 :
result = fragment(vol, buf);
break;
@ -1174,9 +1151,11 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, ulong code,
dprintf("dumping dlist for %lx\n", vol->id);
dlist_dump(vol);
break;
#endif
default :
dprintf("dosfs_ioctl: vol %lx, vnode %Lx code = %ld\n", vol->id, node->vnid, code);
DPRINTF(0, ("dosfs_ioctl: vol %lx, vnode %Lx code = %ld\n",
vol->id, node->vnid, code));
result = EINVAL;
break;
}
@ -1190,9 +1169,6 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, ulong code,
status_t
_dosfs_sync(nspace *vol)
{
if (check_nspace_magic(vol, "dosfs_sync"))
return EINVAL;
update_fsinfo(vol);
block_cache_sync(vol->fBlockCache);
@ -1225,11 +1201,6 @@ dosfs_fsync(fs_volume *_vol, fs_vnode *_node)
LOCK_VOL(vol);
if (check_vnode_magic(node, "dosfs_fsync")) {
UNLOCK_VOL(vol);
return EINVAL;
}
if (node->cache)
err = file_cache_sync(node->cache);

View File

@ -62,10 +62,8 @@
#define VNODE_PARENT_DIR_CLUSTER(vnode) \
CLUSTER_OF_DIR_CLUSTER_VNID((vnode)->dir_vnid)
#define VNODE_MAGIC 'treB'
typedef struct vnode {
uint32 magic;
ino_t vnid; // self id
ino_t dir_vnid; // parent vnode id (directory containing entry)
void *cache;
@ -108,13 +106,10 @@ typedef struct vnode {
#define FAT_SUBDIR 16
#define FAT_ARCHIVE 32
#define NSPACE_MAGIC 'smaI'
struct vcache_entry;
typedef struct _nspace
{
uint32 magic;
typedef struct _nspace {
fs_volume *volume; // fs_volume passed in to fs_mount
dev_t id;
int fd; // File descriptor
@ -179,22 +174,6 @@ typedef struct _nspace
#define UNLOCK_VOL(vol) \
UNLOCK((vol)->vlock)
#define CHECK_MAGIC(name,struc,magick) \
int check_##name##_magic(struc *t, char *funcname) \
{ \
if (t == NULL) { \
dprintf("%s passed null " #name " pointer\n", funcname); \
return EINVAL; \
} else if (t->magic != magick) { \
dprintf(#name " (%x) passed to %s has invalid magic number\n", (int)t, funcname); \
return EINVAL; \
} else \
return 0; \
}
int check_vnode_magic(struct vnode *t, char *funcname);
int check_nspace_magic(struct _nspace *t, char *funcname);
#define TOUCH(x) ((void)(x))
extern fs_vnode_ops gFATVnodeOps;

View File

@ -2,25 +2,29 @@
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 <fs_cache.h>
#include "fat.h"
#include <stdlib.h>
#include <string.h>
#include <fs_cache.h>
#include <ByteOrder.h>
#include <KernelExport.h>
#include "dosfs.h"
#include "fat.h"
#include "util.h"
#include "file.h"
#include "util.h"
#include "vcache.h"
#define END_FAT_ENTRY 0x0fffffff
#define BAD_FAT_ENTRY 0x0ffffff1
#define DPRINTF(a,b) if (debug_fat > (a)) dprintf b
static status_t
mirror_fats(nspace *vol, uint32 sector, uint8 *buffer)
{
@ -104,11 +108,8 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N)
// mark end of chain for allocations
uint32 endOfChainMarker = (action == _IOCTL_SET_ENTRY_) ? N : 0x0fffffff;
ASSERT((action >= _IOCTL_COUNT_FREE_)
&& (action <= _IOCTL_ALLOCATE_N_ENTRIES_));
if (check_nspace_magic(vol, "_fat_ioctl_"))
return B_BAD_VALUE;
ASSERT(action >= _IOCTL_COUNT_FREE_
&& action <= _IOCTL_ALLOCATE_N_ENTRIES_);
DPRINTF(3, ("_fat_ioctl_: action %lx, cluster %ld, N %ld\n", action,
cluster, N));
@ -367,7 +368,7 @@ get_fat_entry(nspace *vol, uint32 cluster)
if (value < 0)
return value;
if ((value == 0) || IS_DATA_CLUSTER(value))
if (value == 0 || IS_DATA_CLUSTER(value))
return value;
if (value > 0x0ffffff7)
@ -388,13 +389,10 @@ set_fat_entry(nspace *vol, uint32 cluster, int32 value)
}
// traverse n fat entries
//! Traverse n fat entries
int32
get_nth_fat_entry(nspace *vol, int32 cluster, uint32 n)
{
if (check_nspace_magic(vol, "get_nth_fat_entry"))
return B_BAD_VALUE;
while (n--) {
cluster = get_fat_entry(vol, cluster);
@ -417,9 +415,6 @@ count_clusters(nspace *vol, int32 cluster)
DPRINTF(2, ("count_clusters %ld\n", cluster));
if (check_nspace_magic(vol, "count_clusters"))
return 0;
// not intended for use on root directory
if (!IS_DATA_CLUSTER(cluster)) {
DPRINTF(0, ("count_clusters called on invalid cluster (%ld)\n",

View File

@ -5,6 +5,10 @@
#ifndef _DOSFS_FAT_H_
#define _DOSFS_FAT_H_
#include "dosfs.h"
#define vIS_DATA_CLUSTER(vol,cluster) (((cluster) >= 2) && ((cluster) < vol->total_clusters + 2))
#define IS_DATA_CLUSTER(cluster) vIS_DATA_CLUSTER(vol,cluster)

View File

@ -29,11 +29,8 @@
#define MAX_FILE_SIZE 0xffffffffLL
#define FILECOOKIE_MAGIC 'looT'
typedef struct filecookie
{
uint32 magic;
typedef struct filecookie {
uint32 mode; // open mode
/* simple cluster cache */
@ -44,8 +41,6 @@ typedef struct filecookie
} ccache;
} filecookie;
static CHECK_MAGIC(filecookie,struct filecookie, FILECOOKIE_MAGIC)
mode_t
make_mode(nspace *volume, vnode *node)
@ -141,11 +136,6 @@ dosfs_release_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
TOUCH(reenter);
if (check_nspace_magic(vol, "dosfs_write_vnode")
|| check_vnode_magic(node, "dosfs_write_vnode")) {
return EINVAL;
}
DPRINTF(0, ("dosfs_write_vnode (ino_t %Lx)\n", node->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
@ -160,7 +150,6 @@ dosfs_release_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
#endif
if (node->vnid != vol->root_vnode.vnid) {
node->magic = ~VNODE_MAGIC; // munge magic number to be safe
file_cache_delete(node->cache);
file_map_delete(node->file_map);
free(node);
@ -179,12 +168,6 @@ dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_rstat")
|| check_vnode_magic(node, "dosfs_rstat")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(1, ("dosfs_rstat (vnode id %Lx)\n", node->vnid));
st->st_dev = vol->id;
@ -216,12 +199,6 @@ dosfs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_wstat")
|| check_vnode_magic(node, "dosfs_wstat")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_wstat (vnode id %Lx)\n", node->vnid));
if (vol->flags & B_FS_IS_READONLY) {
@ -302,12 +279,6 @@ dosfs_open(fs_volume *_vol, fs_vnode *_node, int omode, void **_cookie)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_open")
|| check_vnode_magic(node, "dosfs_open")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_open: vnode id %Lx, omode %x\n", node->vnid, omode));
if (omode & O_CREAT) {
@ -347,7 +318,6 @@ dosfs_open(fs_volume *_vol, fs_vnode *_node, int omode, void **_cookie)
goto error;
}
cookie->magic = FILECOOKIE_MAGIC;
cookie->mode = omode;
cookie->ccache.iteration = node->iteration;
cookie->ccache.index = 0;
@ -379,15 +349,6 @@ dosfs_read(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
LOCK_VOL(vol);
if (check_nspace_magic((nspace *)vol, "dosfs_read")
|| check_vnode_magic(node, "dosfs_read")
|| check_filecookie_magic(cookie, "dosfs_read")) {
*len = 0;
UNLOCK_VOL(vol);
return EINVAL;
}
if (node->mode & FAT_SUBDIR) {
DPRINTF(0, ("dosfs_read called on subdirectory %Lx\n", node->vnid));
*len = 0;
@ -536,14 +497,6 @@ dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
LOCK_VOL(vol);
if (check_nspace_magic((nspace *)vol, "dosfs_write")
|| check_vnode_magic(node, "dosfs_write")
|| check_filecookie_magic(cookie, "dosfs_write")) {
*len = 0;
UNLOCK_VOL(vol);
return EINVAL;
}
if (node->mode & FAT_SUBDIR) {
DPRINTF(0, ("dosfs_write called on subdirectory %Lx\n", node->vnid));
*len = 0;
@ -728,13 +681,6 @@ dosfs_close(fs_volume *_vol, fs_vnode *_node, void *_cookie)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_close")
|| check_vnode_magic(node, "dosfs_close")
|| check_filecookie_magic(_cookie, "dosfs_close")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_close (vnode id %Lx)\n", node->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
@ -756,16 +702,8 @@ dosfs_free_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
filecookie *cookie = _cookie;
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_free_cookie")
|| check_vnode_magic(node, "dosfs_free_cookie")
|| check_filecookie_magic(cookie, "dosfs_free_cookie")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_free_cookie (vnode id %Lx)\n", node->vnid));
cookie->magic = ~FILECOOKIE_MAGIC;
free(cookie);
UNLOCK_VOL(vol);
@ -786,12 +724,6 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_create")
|| check_vnode_magic(dir, "dosfs_create")) {
UNLOCK_VOL(vol);
return EINVAL;
}
ASSERT(name != NULL);
if (name == NULL) {
dprintf("dosfs_create called with null name\n");
@ -863,7 +795,6 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
// the file doesn't already exist in any case
vnode dummy; /* used only to create directory entry */
dummy.magic = VNODE_MAGIC;
dummy.dir_vnid = dir->vnid;
dummy.cluster = 0;
dummy.end_cluster = 0;
@ -873,7 +804,6 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
if ((result = create_dir_entry(vol, dir, &dummy, name, &(dummy.sindex), &(dummy.eindex))) != B_OK) {
dprintf("dosfs_create: error creating directory entry for %s (%s)\n", name, strerror(result));
dummy.magic = ~VNODE_MAGIC;
goto bi;
}
dummy.vnid = GENERATE_DIR_INDEX_VNID(dummy.dir_vnid, dummy.sindex);
@ -888,7 +818,6 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
}
}
*vnid = dummy.vnid;
dummy.magic = ~VNODE_MAGIC;
result = get_vnode(_vol, *vnid, (void **)&file);
if (result < B_OK) {
@ -900,7 +829,6 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
goto bi;
}
cookie->magic = FILECOOKIE_MAGIC;
cookie->mode = omode;
cookie->ccache.iteration = file->iteration;
cookie->ccache.index = 0;
@ -936,12 +864,6 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_mkdir")
|| check_vnode_magic(dir, "dosfs_mkdir")) {
UNLOCK_VOL(vol);
return EINVAL;
}
// TODO : is it needed ? vfs job ?
/*if (is_vnode_removed(vol->id, dir->vnid) > 0) {
dprintf("dosfs_mkdir() called in removed directory. disallowed.\n");
@ -967,7 +889,6 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
}
/* only used to create directory entry */
dummy.magic = VNODE_MAGIC;
dummy.dir_vnid = dir->vnid;
if ((result = allocate_n_fat_entries(vol, 1, (int32 *)&(dummy.cluster))) < 0) {
dprintf("dosfs_mkdir: error allocating space for %s (%s))\n", name, strerror(result));
@ -1062,14 +983,18 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
UNLOCK_VOL(vol);
return result;
bi5:free(buffer);
bi4:dlist_remove(vol, dummy.vnid);
bi3:if (IS_ARTIFICIAL_VNID(dummy.vnid)) remove_from_vcache(vol, dummy.vnid);
bi2:clear_fat_chain(vol, dummy.cluster);
bi5:
free(buffer);
bi4:
dlist_remove(vol, dummy.vnid);
bi3:
if (IS_ARTIFICIAL_VNID(dummy.vnid))
remove_from_vcache(vol, dummy.vnid);
bi2:
clear_fat_chain(vol, dummy.cluster);
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi: dummy.magic = ~VNODE_MAGIC;
bi:
UNLOCK_VOL(vol);
if (result != B_OK) DPRINTF(0, ("dosfs_mkdir (%s)\n", strerror(result)));
return result;
@ -1091,13 +1016,6 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
LOCK_VOL(vol);
if (check_nspace_magic(vol, "dosfs_rename")
|| check_vnode_magic(odir, "dosfs_rename")
|| check_vnode_magic(ndir, "dosfs_rename")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("dosfs_rename called: %Lx/%s->%Lx/%s\n", odir->vnid, oldname, ndir->vnid, newname));
if(!is_filename_legal(newname)) {
@ -1134,11 +1052,6 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
goto bi1;
}
if (check_vnode_magic(file, "dosfs_rename")) {
result = EINVAL;
goto bi1;
}
// don't move a directory into one of its children
if (file->mode & FAT_SUBDIR) {
ino_t vnid = ndir->vnid;
@ -1318,19 +1231,13 @@ dosfs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
if (!reenter) { LOCK_VOL(vol); }
if (check_nspace_magic(vol, "dosfs_remove_vnode")
|| check_vnode_magic(node, "dosfs_remove_vnode")) {
if (!reenter) UNLOCK_VOL(vol);
return EINVAL;
}
LOCK_VOL(vol);
DPRINTF(0, ("dosfs_remove_vnode (%Lx)\n", node->vnid));
if (vol->flags & B_FS_IS_READONLY) {
dprintf("dosfs_remove_vnode: read-only volume\n");
if (!reenter) UNLOCK_VOL(vol);
UNLOCK_VOL(vol);
return EROFS;
}
@ -1349,19 +1256,17 @@ dosfs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
if (node->mode & FAT_SUBDIR)
dlist_remove(vol, node->vnid);
node->magic = ~VNODE_MAGIC; // munge magic number to be safe
free(node);
if (!reenter) {
if (vol->fs_flags & FS_FLAGS_OP_SYNC) {
// sync the entire filesystem,
// but only if we're not reentrant. Presumably the
// function that called this will sync.
_dosfs_sync(vol);
}
UNLOCK_VOL(vol);
if (!reenter && vol->fs_flags & FS_FLAGS_OP_SYNC) {
// sync the entire filesystem,
// but only if we're not reentrant. Presumably the
// function that called this will sync.
_dosfs_sync(vol);
}
UNLOCK_VOL(vol);
return B_OK;
}
@ -1383,12 +1288,6 @@ do_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name, bool is_file)
LOCK_VOL(vol);
if (check_nspace_magic(vol, "do_unlink")
|| check_vnode_magic(dir, "do_unlink")) {
UNLOCK_VOL(vol);
return EINVAL;
}
DPRINTF(0, ("do_unlink %Lx/%s\n", dir->vnid, name));
if (vol->flags & B_FS_IS_READONLY) {
@ -1404,11 +1303,6 @@ do_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name, bool is_file)
goto bi;
}
if (check_vnode_magic(file, "do_unlink")) {
result = EINVAL;
goto bi1;
}
if (file->disk_image) {
DPRINTF(0, ("do_unlink: can't unlink disk image or disk image directory\n"));
result = EPERM;
@ -1516,10 +1410,6 @@ dosfs_read_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
size_t bytesLeft = *_numBytes;
status_t status;
if (check_nspace_magic(vol, "dosfs_read_pages")
|| check_vnode_magic(node, "dosfs_read_pages"))
return EINVAL;
if (node->cache == NULL)
return(B_BAD_VALUE);
@ -1564,10 +1454,6 @@ dosfs_write_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
size_t bytesLeft = *_numBytes;
status_t status;
if (check_nspace_magic(vol, "dosfs_write_pages")
|| check_vnode_magic(node, "dosfs_write_pages"))
return EINVAL;
if (node->cache == NULL)
return B_BAD_VALUE;
@ -1617,12 +1503,6 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t pos, size_t len,
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);

View File

@ -3,20 +3,21 @@
This file may be used under the terms of the Be Sample Code License.
*/
#include <KernelExport.h>
#include "iter.h"
#include <string.h>
#include <fs_cache.h>
#include <fs_info.h>
#include <string.h>
#include <KernelExport.h>
#include "iter.h"
#include "dosfs.h"
#include "fat.h"
#include "util.h"
#define DPRINTF(a,b) if (debug_iter > (a)) dprintf b
CHECK_MAGIC(diri,struct diri,DIRI_MAGIC)
#define DPRINTF(a,b) if (debug_iter > (a)) dprintf b
static int
@ -267,7 +268,6 @@ _diri_release_current_block_(struct diri *diri)
uint8 *
diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri)
{
diri->magic = ~DIRI_MAGIC; // trash magic number
diri->current_block = NULL;
if (cluster >= vol->total_clusters + 2)
@ -290,7 +290,6 @@ diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri)
return NULL;
// now the diri is valid
diri->magic = DIRI_MAGIC;
return diri->current_block
+ (diri->current_index % (diri->csi.vol->bytes_per_sector / 0x20))*0x20;
}
@ -299,10 +298,6 @@ diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri)
int
diri_free(struct diri *diri)
{
if (check_diri_magic(diri, "diri_free")) return EINVAL;
diri->magic = ~DIRI_MAGIC; // trash magic number
if (diri->current_block)
_diri_release_current_block_(diri);
@ -313,8 +308,6 @@ diri_free(struct diri *diri)
uint8 *
diri_current_entry(struct diri *diri)
{
if (check_diri_magic(diri, "diri_current_entry")) return NULL;
if (diri->current_block == NULL)
return NULL;
@ -326,8 +319,6 @@ diri_current_entry(struct diri *diri)
uint8 *
diri_next_entry(struct diri *diri)
{
if (check_diri_magic(diri, "diri_next_entry")) return NULL;
if (diri->current_block == NULL)
return NULL;
@ -348,9 +339,6 @@ diri_next_entry(struct diri *diri)
uint8 *
diri_rewind(struct diri *diri)
{
if (check_diri_magic(diri, "diri_rewind"))
return NULL;
if (diri->current_index > (diri->csi.vol->bytes_per_sector / 0x20 - 1)) {
if (diri->current_block)
_diri_release_current_block_(diri);

View File

@ -5,6 +5,10 @@
#ifndef _DOSFS_ITER_H_
#define _DOSFS_ITER_H_
#include <SupportDefs.h>
struct _nspace;
/* csi keeps track of current cluster and sector info */
@ -25,9 +29,7 @@ status_t csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len);
status_t csi_write_block(struct csi *csi, uint8 *buffer);
/* directory entry iterator */
#define DIRI_MAGIC '!duM'
struct diri {
uint32 magic;
struct csi csi;
uint32 starting_cluster;
uint32 current_index;
@ -41,6 +43,4 @@ uint8 *diri_next_entry(struct diri *diri);
uint8 *diri_rewind(struct diri *diri);
void diri_make_writable(struct diri *diri);
int check_diri_magic(struct diri *t, char *funcname);
#endif

View File

@ -79,12 +79,13 @@ dump_vcache(nspace *vol)
{
uint32 i;
struct vcache_entry *c;
dprintf("vnid cache size %lx, cur vnid = %Lx\n"
"vnid loc\n",
vol->vcache.cache_size, vol->vcache.cur_vnid);
for (i=0;i<vol->vcache.cache_size;i++)
for (c = vol->vcache.by_vnid[i];c;c=c->next_vnid)
dprintf("%16Lx %16Lx\n", c->vnid, c->loc);
kprintf("vnid cache size %lx, cur vnid = %Lx\n"
"vnid loc\n",
vol->vcache.cache_size, vol->vcache.cur_vnid);
for (i = 0; i < vol->vcache.cache_size; i++) {
for (c = vol->vcache.by_vnid[i]; c ; c = c->next_vnid)
kprintf("%16Lx %16Lx\n", c->vnid, c->loc);
}
}
@ -104,14 +105,14 @@ init_vcache(nspace *vol)
vol->vcache.by_vnid = calloc(sizeof(struct vache_entry *),
vol->vcache.cache_size);
if (vol->vcache.by_vnid == NULL) {
dprintf("init_vcache: out of core\n");
dprintf("init_vcache: out of memory\n");
return ENOMEM;
}
vol->vcache.by_loc = calloc(sizeof(struct vache_entry *),
vol->vcache.cache_size);
if (vol->vcache.by_loc == NULL) {
dprintf("init_vcache: out of core\n");
dprintf("init_vcache: out of memory\n");
free(vol->vcache.by_vnid);
vol->vcache.by_vnid = NULL;
return ENOMEM;
@ -431,7 +432,7 @@ debug_dfvnid(int argc, char **argv)
if (vol == NULL)
return B_OK;
for (i=2;i<argc;i++) {
for (i = 2; i < argc; i++) {
ino_t vnid = strtoull(argv[i], NULL, 0);
struct vcache_entry *e;
if ((e = _find_vnid_in_vcache_(vol, vnid)) != NULL) {