* vcache is now using an rw_lock instead of a semaphore.
* Got rid of the lock typedef. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31843 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -5,20 +5,19 @@
|
|||||||
#ifndef _DOSFS_H_
|
#ifndef _DOSFS_H_
|
||||||
#define _DOSFS_H_
|
#define _DOSFS_H_
|
||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <fs_interface.h>
|
#include <fs_interface.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
||||||
|
|
||||||
//#define DEBUG 1
|
//#define DEBUG 1
|
||||||
|
|
||||||
typedef recursive_lock lock;
|
|
||||||
#define LOCK(l) recursive_lock_lock(&l);
|
#define LOCK(l) recursive_lock_lock(&l);
|
||||||
#define UNLOCK(l) recursive_lock_unlock(&l);
|
#define UNLOCK(l) recursive_lock_unlock(&l);
|
||||||
|
|
||||||
|
|
||||||
/* for multiple reader/single writer locks */
|
|
||||||
#define READERS 100000
|
|
||||||
|
|
||||||
/* Unfortunately, ino_t's are defined as signed. This causes problems with
|
/* Unfortunately, ino_t's are defined as signed. This causes problems with
|
||||||
* programs (notably cp) that use the modulo of a ino_t as a
|
* programs (notably cp) that use the modulo of a ino_t as a
|
||||||
* hash function to index an array. This means the high bit of every ino_t
|
* hash function to index an array. This means the high bit of every ino_t
|
||||||
@@ -154,11 +153,11 @@ typedef struct _nspace
|
|||||||
|
|
||||||
int fs_flags; // flags for this mount
|
int fs_flags; // flags for this mount
|
||||||
|
|
||||||
lock vlock; // volume lock
|
recursive_lock vlock; // volume lock
|
||||||
|
|
||||||
// vcache state
|
// vcache state
|
||||||
struct {
|
struct {
|
||||||
sem_id vc_sem;
|
rw_lock lock;
|
||||||
ino_t cur_vnid;
|
ino_t cur_vnid;
|
||||||
uint32 cache_size;
|
uint32 cache_size;
|
||||||
struct vcache_entry **by_vnid, **by_loc;
|
struct vcache_entry **by_vnid, **by_loc;
|
||||||
|
|||||||
@@ -36,31 +36,36 @@ mapping table to translate vnode id's to locations. This file serves this
|
|||||||
purpose.
|
purpose.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DPRINTF(a,b) if (debug_vcache > (a)) dprintf b
|
|
||||||
|
|
||||||
#define LOCK_CACHE_R \
|
#include "vcache.h"
|
||||||
acquire_sem(vol->vcache.vc_sem)
|
|
||||||
|
|
||||||
#define LOCK_CACHE_W \
|
|
||||||
acquire_sem_etc(vol->vcache.vc_sem, READERS, 0, 0)
|
|
||||||
|
|
||||||
#define UNLOCK_CACHE_R \
|
|
||||||
release_sem(vol->vcache.vc_sem)
|
|
||||||
|
|
||||||
#define UNLOCK_CACHE_W \
|
|
||||||
release_sem_etc(vol->vcache.vc_sem, READERS, 0)
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "dosfs.h"
|
#include <KernelExport.h>
|
||||||
#include "vcache.h"
|
|
||||||
|
|
||||||
|
#include "dosfs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DPRINTF(a,b) if (debug_vcache > (a)) dprintf b
|
||||||
|
|
||||||
|
#define LOCK_CACHE_R \
|
||||||
|
rw_lock_read_lock(&vol->vcache.lock)
|
||||||
|
|
||||||
|
#define LOCK_CACHE_W \
|
||||||
|
rw_lock_write_lock(&vol->vcache.lock)
|
||||||
|
|
||||||
|
#define UNLOCK_CACHE_R \
|
||||||
|
rw_lock_read_unlock(&vol->vcache.lock)
|
||||||
|
|
||||||
|
#define UNLOCK_CACHE_W \
|
||||||
|
rw_lock_write_unlock(&vol->vcache.lock)
|
||||||
|
|
||||||
|
#define hash(v) ((v) & (vol->vcache.cache_size-1))
|
||||||
|
|
||||||
|
|
||||||
struct vcache_entry {
|
struct vcache_entry {
|
||||||
ino_t vnid; /* originally reported vnid */
|
ino_t vnid; /* originally reported vnid */
|
||||||
ino_t loc; /* where the file is now */
|
ino_t loc; /* where the file is now */
|
||||||
@@ -68,7 +73,9 @@ struct vcache_entry {
|
|||||||
struct vcache_entry *next_loc; /* next entry in location hash table */
|
struct vcache_entry *next_loc; /* next entry in location hash table */
|
||||||
};
|
};
|
||||||
|
|
||||||
void dump_vcache(nspace *vol)
|
|
||||||
|
void
|
||||||
|
dump_vcache(nspace *vol)
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
struct vcache_entry *c;
|
struct vcache_entry *c;
|
||||||
@@ -80,9 +87,9 @@ void dump_vcache(nspace *vol)
|
|||||||
dprintf("%16Lx %16Lx\n", c->vnid, c->loc);
|
dprintf("%16Lx %16Lx\n", c->vnid, c->loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define hash(v) ((v) & (vol->vcache.cache_size-1))
|
|
||||||
|
|
||||||
status_t init_vcache(nspace *vol)
|
status_t
|
||||||
|
init_vcache(nspace *vol)
|
||||||
{
|
{
|
||||||
char name[16];
|
char name[16];
|
||||||
DPRINTF(0, ("init_vcache called\n"));
|
DPRINTF(0, ("init_vcache called\n"));
|
||||||
@@ -93,12 +100,16 @@ status_t init_vcache(nspace *vol)
|
|||||||
#else
|
#else
|
||||||
vol->vcache.cache_size = 512; /* must be power of 2 */
|
vol->vcache.cache_size = 512; /* must be power of 2 */
|
||||||
#endif
|
#endif
|
||||||
vol->vcache.by_vnid = calloc(sizeof(struct vache_entry *), vol->vcache.cache_size);
|
|
||||||
|
vol->vcache.by_vnid = calloc(sizeof(struct vache_entry *),
|
||||||
|
vol->vcache.cache_size);
|
||||||
if (vol->vcache.by_vnid == NULL) {
|
if (vol->vcache.by_vnid == NULL) {
|
||||||
dprintf("init_vcache: out of core\n");
|
dprintf("init_vcache: out of core\n");
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
vol->vcache.by_loc = calloc(sizeof(struct vache_entry *), vol->vcache.cache_size);
|
|
||||||
|
vol->vcache.by_loc = calloc(sizeof(struct vache_entry *),
|
||||||
|
vol->vcache.cache_size);
|
||||||
if (vol->vcache.by_loc == NULL) {
|
if (vol->vcache.by_loc == NULL) {
|
||||||
dprintf("init_vcache: out of core\n");
|
dprintf("init_vcache: out of core\n");
|
||||||
free(vol->vcache.by_vnid);
|
free(vol->vcache.by_vnid);
|
||||||
@@ -107,13 +118,10 @@ status_t init_vcache(nspace *vol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(name, "fat cache %lx", vol->id);
|
sprintf(name, "fat cache %lx", vol->id);
|
||||||
if ((vol->vcache.vc_sem = create_sem(READERS, name)) < 0) {
|
rw_lock_init(&vol->vcache.lock, "fat cache");
|
||||||
free(vol->vcache.by_vnid); vol->vcache.by_vnid = NULL;
|
|
||||||
free(vol->vcache.by_loc); vol->vcache.by_loc = NULL;
|
|
||||||
return vol->vcache.vc_sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(0, ("init_vcache: initialized vnid cache with %lx entries\n", vol->vcache.cache_size));
|
DPRINTF(0, ("init_vcache: initialized vnid cache with %lx entries\n",
|
||||||
|
vol->vcache.cache_size));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -129,7 +137,7 @@ uninit_vcache(nspace *vol)
|
|||||||
LOCK_CACHE_W;
|
LOCK_CACHE_W;
|
||||||
|
|
||||||
/* free entries */
|
/* free entries */
|
||||||
for (i=0;i<vol->vcache.cache_size;i++) {
|
for (i = 0; i < vol->vcache.cache_size; i++) {
|
||||||
c = vol->vcache.by_vnid[i];
|
c = vol->vcache.by_vnid[i];
|
||||||
while (c) {
|
while (c) {
|
||||||
count++;
|
count++;
|
||||||
@@ -144,9 +152,8 @@ uninit_vcache(nspace *vol)
|
|||||||
free(vol->vcache.by_vnid); vol->vcache.by_vnid = NULL;
|
free(vol->vcache.by_vnid); vol->vcache.by_vnid = NULL;
|
||||||
free(vol->vcache.by_loc); vol->vcache.by_loc = NULL;
|
free(vol->vcache.by_loc); vol->vcache.by_loc = NULL;
|
||||||
|
|
||||||
delete_sem(vol->vcache.vc_sem);
|
rw_lock_destroy(&vol->vcache.lock);
|
||||||
|
return B_OK;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
#ifndef _DOSFS_VCACHE_H_
|
#ifndef _DOSFS_VCACHE_H_
|
||||||
#define _DOSFS_VCACHE_H_
|
#define _DOSFS_VCACHE_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "dosfs.h"
|
||||||
|
|
||||||
|
|
||||||
void dump_vcache(nspace *vol);
|
void dump_vcache(nspace *vol);
|
||||||
|
|
||||||
status_t init_vcache(nspace *vol);
|
status_t init_vcache(nspace *vol);
|
||||||
|
|||||||
Reference in New Issue
Block a user