/branches/dynload/uspace/lib/libblock/libblock.c |
---|
296,10 → 296,13 |
* |
* @param dev_handle Device handle of the block device. |
* @param boff Block offset. |
* @param flags If BLOCK_FLAGS_NOREAD is specified, block_get() |
* will not read the contents of the block from the |
* device. |
* |
* @return Block structure. |
*/ |
block_t *block_get(dev_handle_t dev_handle, bn_t boff) |
block_t *block_get(dev_handle_t dev_handle, bn_t boff, int flags) |
{ |
devcon_t *devcon; |
cache_t *cache; |
385,13 → 388,15 |
*/ |
abort(); /* TODO: block_write() */ |
} |
if (!(flags & BLOCK_FLAGS_NOREAD)) { |
/* |
* The block contains old or no data. We need to read the new |
* contents from the device. |
* The block contains old or no data. We need to read |
* the new contents from the device. |
*/ |
rc = block_read(dev_handle, &bufpos, &buflen, &pos, b->data, |
cache->block_size, cache->block_size); |
rc = block_read(dev_handle, &bufpos, &buflen, &pos, |
b->data, cache->block_size, cache->block_size); |
assert(rc == EOK); |
} |
futex_up(&b->lock); |
} |
/branches/dynload/uspace/lib/libblock/libblock.h |
---|
44,6 → 44,22 |
#include <libadt/hash_table.h> |
#include <libadt/list.h> |
/* |
* Flags that can be used with block_get(). |
*/ |
/** |
* This macro is a symbolic value for situations where no special flags are |
* needed. |
*/ |
#define BLOCK_FLAGS_NONE 0 |
/** |
* When the client of block_get() intends to overwrite the current contents of |
* the block, this flag is used to avoid the unnecessary read. |
*/ |
#define BLOCK_FLAGS_NOREAD 1 |
typedef unsigned bn_t; /**< Block number type. */ |
typedef struct block { |
77,7 → 93,7 |
extern int block_cache_init(dev_handle_t, size_t, unsigned); |
extern block_t *block_get(dev_handle_t, bn_t); |
extern block_t *block_get(dev_handle_t, bn_t, int flags); |
extern void block_put(block_t *); |
extern int block_read(int, off_t *, size_t *, off_t *, void *, size_t, size_t); |
/branches/dynload/uspace/srv/fs/fat/fat_fat.c |
---|
94,7 → 94,7 |
fsec = (clst * sizeof(fat_cluster_t)) / bps; |
fidx = clst % (bps / sizeof(fat_cluster_t)); |
/* read FAT1 */ |
b = block_get(dev_handle, rscnt + fsec); |
b = block_get(dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE); |
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); |
assert(clst != FAT_CLST_BAD); |
block_put(b); |
114,12 → 114,13 |
* @param firstc First cluster used by the file. Can be zero if the file |
* is empty. |
* @param bn Block number. |
* @param flags Flags passed to libblock. |
* |
* @return Block structure holding the requested block. |
*/ |
block_t * |
_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, |
bn_t bn) |
bn_t bn, int flags) |
{ |
block_t *b; |
unsigned bps; |
143,7 → 144,7 |
if (firstc == FAT_CLST_ROOT) { |
/* root directory special case */ |
assert(bn < rds); |
b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn); |
b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn, flags); |
return b; |
} |
153,7 → 154,7 |
assert(clusters == max_clusters); |
b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc + |
bn % bs->spc); |
bn % bs->spc, flags); |
return b; |
} |
183,7 → 184,9 |
/* zero out already allocated space */ |
for (o = nodep->size - 1; o < pos && o < boundary; |
o = ALIGN_DOWN(o + bps, bps)) { |
b = fat_block_get(bs, nodep, o / bps); |
int flags = (o % bps == 0) ? |
BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE; |
b = fat_block_get(bs, nodep, o / bps, flags); |
memset(b->data + o % bps, 0, bps - o % bps); |
b->dirty = true; /* need to sync node */ |
block_put(b); |
195,7 → 198,7 |
/* zero out the initial part of the new cluster chain */ |
for (o = boundary; o < pos; o += bps) { |
b = _fat_block_get(bs, nodep->idx->dev_handle, mcl, |
(o - boundary) / bps); |
(o - boundary) / bps, BLOCK_FLAGS_NOREAD); |
memset(b->data, 0, min(bps, pos - o)); |
b->dirty = true; /* need to sync node */ |
block_put(b); |
221,7 → 224,8 |
bps = uint16_t_le2host(bs->bps); |
rscnt = uint16_t_le2host(bs->rscnt); |
b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps); |
b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps, |
BLOCK_FLAGS_NONE); |
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); |
value = uint16_t_le2host(*cp); |
block_put(b); |
253,7 → 257,7 |
assert(fatno < bs->fatcnt); |
b = block_get(dev_handle, rscnt + sf * fatno + |
(clst * sizeof(fat_cluster_t)) / bps); |
(clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); |
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); |
*cp = host2uint16_t_le(value); |
b->dirty = true; /* need to sync block */ |
323,7 → 327,7 |
*/ |
futex_down(&fat_alloc_lock); |
for (b = 0, cl = 0; b < sf; blk++) { |
blk = block_get(dev_handle, rscnt + b); |
blk = block_get(dev_handle, rscnt + b, BLOCK_FLAGS_NOREAD); |
for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) { |
fat_cluster_t *clst = (fat_cluster_t *)blk->data + c; |
if (uint16_t_le2host(*clst) == FAT_CLST_RES0) { |
/branches/dynload/uspace/srv/fs/fat/fat_fat.h |
---|
63,11 → 63,11 |
extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t, |
fat_cluster_t *, uint16_t); |
#define fat_block_get(bs, np, bn) \ |
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn)) |
#define fat_block_get(bs, np, bn, flags) \ |
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags)) |
extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t, |
fat_cluster_t, bn_t); |
fat_cluster_t, bn_t, int); |
extern void fat_append_clusters(struct fat_bs *, struct fat_node *, |
fat_cluster_t); |
/branches/dynload/uspace/srv/fs/fat/fat_ops.c |
---|
89,7 → 89,7 |
/* Read the block that contains the dentry of interest. */ |
b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc, |
(node->idx->pdi * sizeof(fat_dentry_t)) / bps); |
(node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); |
d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps); |
181,7 → 181,7 |
/* Read the block that contains the dentry of interest. */ |
b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc, |
(idxp->pdi * sizeof(fat_dentry_t)) / bps); |
(idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); |
assert(b); |
d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps); |
282,7 → 282,7 |
dps = bps / sizeof(fat_dentry_t); |
blocks = parentp->size / bps; |
for (i = 0; i < blocks; i++) { |
b = fat_block_get(bs, parentp, i); |
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); |
for (j = 0; j < dps; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
372,7 → 372,7 |
for (i = 0; i < blocks; i++) { |
fat_dentry_t *d; |
b = fat_block_get(bs, nodep, i); |
b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE); |
for (j = 0; j < dps; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
574,7 → 574,8 |
} else { |
bytes = min(len, bps - pos % bps); |
bytes = min(bytes, nodep->size - pos); |
b = fat_block_get(bs, nodep, pos / bps); |
b = fat_block_get(bs, nodep, pos / bps, |
BLOCK_FLAGS_NONE); |
(void) ipc_data_read_finalize(callid, b->data + pos % bps, |
bytes); |
block_put(b); |
599,7 → 600,7 |
while (bnum < nodep->size / bps) { |
off_t o; |
b = fat_block_get(bs, nodep, bnum); |
b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE); |
for (o = pos % (bps / sizeof(fat_dentry_t)); |
o < bps / sizeof(fat_dentry_t); |
o++, pos++) { |
647,6 → 648,7 |
unsigned spc; |
unsigned bpc; /* bytes per cluster */ |
off_t boundary; |
int flags = BLOCK_FLAGS_NONE; |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
675,6 → 677,8 |
* value signalizing a smaller number of bytes written. |
*/ |
bytes = min(len, bps - pos % bps); |
if (bytes == bps) |
flags |= BLOCK_FLAGS_NOREAD; |
boundary = ROUND_UP(nodep->size, bpc); |
if (pos < boundary) { |
685,7 → 689,7 |
* next block size boundary. |
*/ |
fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); |
b = fat_block_get(bs, nodep, pos / bps); |
b = fat_block_get(bs, nodep, pos / bps, flags); |
(void) ipc_data_write_finalize(callid, b->data + pos % bps, |
bytes); |
b->dirty = true; /* need to sync block */ |
718,7 → 722,8 |
} |
/* zero fill any gaps */ |
fat_fill_gap(bs, nodep, mcl, pos); |
b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc); |
b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc, |
flags); |
(void) ipc_data_write_finalize(callid, b->data + pos % bps, |
bytes); |
b->dirty = true; /* need to sync block */ |