Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2951 → Rev 2950

/trunk/uspace/srv/fs/fat/fat_idx.c
74,7 → 74,15
/** List of unused structures. */
static LIST_INITIALIZE(unused_head);
 
/** Futex protecting the up_hash and ui_hash. */
/** Futex protecting the up_hash and ui_hash.
*
* The locking strategy assumes that there will be at most one fibril for each
* dev_handle. Therefore it will be sufficient to hold the futex for shorter
* times (i.e. only during hash table operations as opposed to holding it the
* whole time between an unsuccessful find and the following insert). Should the
* assumption break, the locking strategy for this futex will have to be
* reconsidered.
*/
static futex_t used_futex = FUTEX_INITIALIZER;
 
/**
344,17 → 352,16
 
futex_down(&used_futex);
l = hash_table_find(&up_hash, pkey);
futex_up(&used_futex);
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
} else {
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
if (!fidx) {
futex_up(&used_futex);
return NULL;
}
if (!fat_idx_alloc(dev_handle, &fidx->index)) {
free(fidx);
futex_up(&used_futex);
return NULL;
}
365,17 → 372,16
link_initialize(&fidx->uph_link);
link_initialize(&fidx->uih_link);
futex_initialize(&fidx->lock, 1);
fidx->dev_handle = dev_handle;
fidx->pfc = pfc;
fidx->pdi = pdi;
fidx->nodep = NULL;
 
futex_down(&used_futex);
hash_table_insert(&up_hash, pkey, &fidx->uph_link);
hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
futex_up(&used_futex);
}
futex_down(&fidx->lock);
futex_up(&used_futex);
 
return fidx;
}
392,11 → 398,10
 
futex_down(&used_futex);
l = hash_table_find(&ui_hash, ikey);
futex_up(&used_futex);
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uih_link);
futex_down(&fidx->lock);
}
futex_up(&used_futex);
 
return fidx;
}
/trunk/uspace/srv/fs/fat/fat_ops.c
50,12 → 50,9
 
#define BS_BLOCK 0
 
/** Futex protecting the list of cached free FAT nodes. */
static futex_t ffn_futex = FUTEX_INITIALIZER;
/** List of free FAT nodes that still contain valid data. */
LIST_INITIALIZE(ffn_head);
 
/** List of cached free FAT nodes. */
static LIST_INITIALIZE(ffn_head);
 
#define FAT_NAME_LEN 8
#define FAT_EXT_LEN 3
 
182,7 → 179,6
 
static void fat_node_initialize(fat_node_t *node)
{
futex_initialize(&node->lock, 1);
node->idx = NULL;
node->type = 0;
link_initialize(&node->ffn_link);
240,12 → 236,10
/* TODO */
}
 
/** Internal version of fat_node_get().
*
* @param idxp Locked index structure.
*/
static void *fat_node_get_core(fat_idx_t *idxp)
/** Instantiate a FAT in-core node. */
static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
{
fat_idx_t *idx;
block_t *b;
fat_dentry_t *d;
fat_node_t *nodep;
252,16 → 246,18
unsigned bps;
unsigned dps;
 
if (idxp->nodep) {
idx = fat_idx_get_by_index(dev_handle, index);
if (!idx)
return NULL;
 
if (idx->nodep) {
/*
* We are lucky.
* The node is already instantiated in memory.
*/
futex_down(&idxp->nodep->lock);
if (!idxp->nodep->refcnt++)
if (!idx->nodep->refcnt++)
list_remove(&nodep->ffn_link);
futex_up(&idxp->nodep->lock);
return idxp->nodep;
return idx->nodep;
}
 
/*
268,31 → 264,17
* We must instantiate the node from the file system.
*/
assert(idxp->pfc);
assert(idx->pfc);
 
futex_down(&ffn_futex);
if (!list_empty(&ffn_head)) {
/* Try to use a cached free node structure. */
fat_idx_t *idxp_tmp;
/* Try to use a cached unused node structure. */
nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
if (futex_trydown(&nodep->lock) == ESYNCH_WOULD_BLOCK)
goto skip_cache;
idxp_tmp = nodep->idx;
if (futex_trydown(&idxp_tmp->lock) == ESYNCH_WOULD_BLOCK) {
futex_up(&nodep->lock);
goto skip_cache;
}
list_remove(&nodep->ffn_link);
futex_up(&ffn_futex);
if (nodep->dirty)
fat_node_sync(nodep);
idxp_tmp->nodep = NULL;
futex_up(&nodep->lock);
futex_up(&idxp_tmp->lock);
list_remove(&nodep->ffn_link);
nodep->idx->nodep = NULL;
} else {
skip_cache:
/* Try to allocate a new node structure. */
futex_up(&ffn_futex);
nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!nodep)
return NULL;
299,15 → 281,15
}
fat_node_initialize(nodep);
 
bps = fat_bps_get(idxp->dev_handle);
bps = fat_bps_get(dev_handle);
dps = bps / sizeof(fat_dentry_t);
 
/* Read the block that contains the dentry of interest. */
b = _fat_block_get(idxp->dev_handle, idxp->pfc,
(idxp->pdi * sizeof(fat_dentry_t)) / bps);
b = _fat_block_get(dev_handle, idx->pfc,
(idx->pdi * sizeof(fat_dentry_t)) / bps);
assert(b);
 
d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);
d = ((fat_dentry_t *)b->data) + (idx->pdi % dps);
if (d->attr & FAT_ATTR_SUBDIR) {
/*
* The only directory which does not have this bit set is the
326,38 → 308,19
block_put(b);
 
/* Link the idx structure with the node structure. */
nodep->idx = idxp;
idxp->nodep = nodep;
nodep->idx = idx;
idx->nodep = nodep;
 
return nodep;
}
 
/** Instantiate a FAT in-core node. */
static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
{
void *node;
fat_idx_t *idxp;
 
idxp = fat_idx_get_by_index(dev_handle, index);
if (!idxp)
return NULL;
/* idxp->lock held */
node = fat_node_get_core(idxp);
futex_up(&idxp->lock);
return node;
}
 
static void fat_node_put(void *node)
{
fat_node_t *nodep = (fat_node_t *)node;
 
futex_down(&nodep->lock);
if (!--nodep->refcnt) {
futex_down(&ffn_futex);
list_append(&nodep->ffn_link, &ffn_head);
futex_up(&ffn_futex);
}
futex_up(&nodep->lock);
}
 
static void *fat_create(int flags)
416,7 → 379,6
}
if (strcmp(name, component) == 0) {
/* hit */
void *node;
fat_idx_t *idx = fat_idx_get_by_pos(
parentp->idx->dev_handle, parentp->firstc,
i * dps + j);
428,8 → 390,8
block_put(b);
return NULL;
}
node = fat_node_get_core(idx);
futex_up(&idx->lock);
void *node = fat_node_get(idx->dev_handle,
idx->index);
block_put(b);
return node;
}
470,7 → 432,6
if (nodep->type != FAT_DIRECTORY)
return false;
 
futex_down(&nodep->idx->lock);
bps = fat_bps_get(nodep->idx->dev_handle);
dps = bps / sizeof(fat_dentry_t);
 
491,22 → 452,18
continue;
case FAT_DENTRY_LAST:
block_put(b);
futex_up(&nodep->idx->lock);
return false;
default:
case FAT_DENTRY_VALID:
block_put(b);
futex_up(&nodep->idx->lock);
return true;
}
block_put(b);
futex_up(&nodep->idx->lock);
return true;
}
block_put(b);
}
 
futex_up(&nodep->idx->lock);
return false;
}
 
/trunk/uspace/srv/fs/fat/fat.h
180,7 → 180,6
/** Used indices (index) hash table link. */
link_t uih_link;
 
futex_t lock;
dev_handle_t dev_handle;
fs_index_t index;
/**
198,7 → 197,6
 
/** FAT in-core node. */
typedef struct fat_node {
futex_t lock;
fat_node_type_t type;
fat_idx_t *idx;
/**