From dc0ec78d0eb485e20870ed09448eb52d040a39cc Mon Sep 17 00:00:00 2001 From: rob Date: Thu, 28 Jun 2007 22:28:19 +0000 Subject: [PATCH] r26886@plastic: rob | 2007-06-29 07:22:07 +1000 made the device/unit a part of the cache, rather than per-block, to make the calls easier git-svn-id: https://svn.aros.org:8080/svn/aros/trunk/AROS@26320 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- workbench/fs/fat/cache.c | 73 +++++++++++++----------------------------------- workbench/fs/fat/cache.h | 12 ++++---- workbench/fs/fat/fat.c | 6 ++-- workbench/fs/fat/file.c | 4 +-- 4 files changed, 30 insertions(+), 65 deletions(-) diff --git a/workbench/fs/fat/cache.c b/workbench/fs/fat/cache.c index f4b318a8b..8d096f706 100644 --- a/workbench/fs/fat/cache.c +++ b/workbench/fs/fat/cache.c @@ -65,11 +65,10 @@ #define DEBUG 0 #include -/* prototypes for lowlevel block functions */ -static ULONG _cache_get_blocks_ll(struct Device *dev, struct Unit *unit, ULONG num, ULONG nblocks, ULONG block_size, UBYTE *data); -static ULONG _cache_put_blocks_ll(struct Device *dev, struct Unit *unit, ULONG num, ULONG nblocks, ULONG block_size, UBYTE *data); +/* prototype for lowlevel block function */ +static ULONG _cache_do_blocks_ll(struct cache *c, BOOL do_write, ULONG num, ULONG nblocks, ULONG block_size, UBYTE *data); -struct cache *cache_new(ULONG hash_size, ULONG num_blocks, ULONG block_size, ULONG flags) { +struct cache *cache_new(struct Device *device, struct Unit *unit, ULONG hash_size, ULONG num_blocks, ULONG block_size, ULONG flags) { struct cache *c; ULONG i; @@ -91,6 +90,9 @@ struct cache *cache_new(ULONG hash_size, ULONG num_blocks, ULONG block_size, ULO c->blocks = (struct cache_block **) AllocVec(sizeof(struct cache_block *) * num_blocks, MEMF_PUBLIC); + c->device = device; + c->unit = unit; + c->hits = c->misses = 0; for (i = 0; i < num_blocks; i++) { @@ -100,8 +102,6 @@ struct cache *cache_new(ULONG hash_size, ULONG num_blocks, ULONG block_size, ULO b->use_count = 0; b->is_dirty = FALSE; b->num = 0; - b->device = NULL; - b->unit = NULL; b->data = (UBYTE *) b + sizeof(struct cache_block); b->hash_next = b->hash_prev = NULL; @@ -137,7 +137,7 @@ void cache_free(struct cache *c) { FreeVec(c); } -ULONG cache_get_block(struct cache *c, struct Device *dev, struct Unit *unit, ULONG num, ULONG flags, struct cache_block **rb) { +ULONG cache_get_block(struct cache *c, ULONG num, ULONG flags, struct cache_block **rb) { struct cache_block *b; ULONG err; @@ -223,7 +223,7 @@ ULONG cache_get_block(struct cache *c, struct Device *dev, struct Unit *unit, UL if (b->is_dirty) { D(bug("cache_get_block: writing dirty block %d before reusing it\n", b->num)); - if ((err = _cache_put_blocks_ll(dev, unit, num, 1, c->block_size, b->data)) != 0) { + if ((err = _cache_do_blocks_ll(c, TRUE, num, 1, c->block_size, b->data)) != 0) { /* write failed. this is bad. */ /* XXX what is the sane thing to do here? */ *rb = NULL; @@ -232,7 +232,7 @@ ULONG cache_get_block(struct cache *c, struct Device *dev, struct Unit *unit, UL } /* read the block from disk */ - if ((err = _cache_get_blocks_ll(dev, unit, num, 1, c->block_size, b->data)) != 0) { + if ((err = _cache_do_blocks_ll(c, FALSE, num, 1, c->block_size, b->data)) != 0) { /* read failed, put the block back on the free list */ b->free_next = c->free_head; c->free_head = b; @@ -243,8 +243,6 @@ ULONG cache_get_block(struct cache *c, struct Device *dev, struct Unit *unit, UL } /* setup the rest of it */ - b->device = dev; - b->unit = unit; b->num = num; b->is_dirty = FALSE; @@ -301,14 +299,14 @@ ULONG cache_put_block(struct cache *c, struct cache_block *b, ULONG flags) { return 0; } -ULONG cache_get_blocks(struct cache *c, struct Device *dev, struct Unit *unit, ULONG num, ULONG nblocks, ULONG flags, struct cache_block **rb) { +ULONG cache_get_blocks(struct cache *c, ULONG num, ULONG nblocks, ULONG flags, struct cache_block **rb) { ULONG err, i; D(bug("cache_get_blocks: loading %d blocks starting at %d, flags 0x%08x\n", nblocks, num, flags)); /* XXX optimise this to get contiguous blocks in one hit */ for (i = 0; i < nblocks; i++) { - if ((err = cache_get_block(c, dev, unit, num+i, flags, &rb[i])) != 0) { + if ((err = cache_get_block(c, num+i, flags, &rb[i])) != 0) { D(bug("cache_get_blocks: block load failed, freeing everything we got so far\n")); for (; i >= 0; i--) @@ -344,7 +342,7 @@ ULONG cache_mark_block_dirty(struct cache *c, struct cache_block *b) { D(bug("cache_mark_block_dirty: writing dirty block %d\n", b->num)); - if ((err = _cache_put_blocks_ll(b->device, b->unit, b->num, 1, c->block_size, b->data)) != 0) { + if ((err = _cache_do_blocks_ll(c, TRUE, b->num, 1, c->block_size, b->data)) != 0) { D(bug("cache_mark_block_dirty: write failed, leaving block marked dirty\n")); b->is_dirty = 1; return err; @@ -367,7 +365,7 @@ ULONG cache_mark_blocks_dirty(struct cache *c, struct cache_block **b, ULONG nbl /* XXX optimise this to do contiguous blocks in one hit */ for (i = 0; i < nblocks; i++) { D(bug("cache_mark_blocks_dirty: writing dirty block %d\n", b[i]->num)); - if ((err = _cache_put_blocks_ll(b[i]->device, b[i]->unit, b[i]->num, 1, c->block_size, b[i]->data)) != 0) { + if ((err = _cache_do_blocks_ll(c, TRUE, b[i]->num, 1, c->block_size, b[i]->data)) != 0) { D(bug("cache_mark_blocks_dirty: write failed, leaving this and remaining blocks marked dirty\n")); b[i]->is_dirty = 1; for (; i < nblocks; i++) { @@ -413,45 +411,12 @@ void cache_stats(struct cache *c) { /* lowlevel block functions */ -static ULONG _cache_get_blocks_ll(struct Device *dev, struct Unit *unit, ULONG num, ULONG nblocks, ULONG block_size, UBYTE *data) { - struct MsgPort *port; - struct IOExtTD req; - ULONG err; - - D(bug("_cache_get_blocks_ll: request to get %ld blocks starting from %ld (block_size %ld)\n", nblocks, num, block_size)); - - port = CreateMsgPort(); - - req.iotd_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG; - req.iotd_Req.io_Message.mn_ReplyPort = port; - req.iotd_Req.io_Message.mn_Length = sizeof(struct IOExtTD); - - req.iotd_Req.io_Command = CMD_READ; - req.iotd_Req.io_Offset = num * block_size; - req.iotd_Req.io_Length = nblocks * block_size; - req.iotd_Req.io_Data = data; - req.iotd_Req.io_Flags = IOF_QUICK; - - req.iotd_Req.io_Device = dev; - req.iotd_Req.io_Unit = unit; - - DoIO((struct IORequest *) &req); - - err = req.iotd_Req.io_Error; - - DeleteMsgPort(port); - - D(bug("_cache_get_blocks_ll: returning error %ld\n", err)); - - return err; -} - -static ULONG _cache_put_blocks_ll(struct Device *dev, struct Unit *unit, ULONG num, ULONG nblocks, ULONG block_size, UBYTE *data) { +static ULONG _cache_do_blocks_ll(struct cache *c, BOOL do_write, ULONG num, ULONG nblocks, ULONG block_size, UBYTE *data) { struct MsgPort *port; struct IOExtTD req; ULONG err; - D(bug("_cache_put_blocks_ll: request to put %ld blocks starting from %ld (block_size %ld)\n", nblocks, num, block_size)); + D(bug("_cache_do_blocks_ll: request to %s %ld blocks starting from %ld (block_size %ld)\n", do_write ? "write" : "read", nblocks, num, block_size)); port = CreateMsgPort(); @@ -459,14 +424,14 @@ static ULONG _cache_put_blocks_ll(struct Device *dev, struct Unit *unit, ULONG n req.iotd_Req.io_Message.mn_ReplyPort = port; req.iotd_Req.io_Message.mn_Length = sizeof(struct IOExtTD); - req.iotd_Req.io_Command = CMD_WRITE; + req.iotd_Req.io_Command = do_write ? CMD_WRITE : CMD_READ; req.iotd_Req.io_Offset = num * block_size; req.iotd_Req.io_Length = nblocks * block_size; req.iotd_Req.io_Data = data; req.iotd_Req.io_Flags = IOF_QUICK; - req.iotd_Req.io_Device = dev; - req.iotd_Req.io_Unit = unit; + req.iotd_Req.io_Device = c->device; + req.iotd_Req.io_Unit = c->unit; DoIO((struct IORequest *) &req); @@ -474,7 +439,7 @@ static ULONG _cache_put_blocks_ll(struct Device *dev, struct Unit *unit, ULONG n DeleteMsgPort(port); - D(bug("_cache_put_blocks_ll: returning error %ld\n", err)); + D(bug("_cache_do_blocks_ll: returning error %ld\n", err)); return err; } diff --git a/workbench/fs/fat/cache.h b/workbench/fs/fat/cache.h index 8a7884118..48af285f8 100644 --- a/workbench/fs/fat/cache.h +++ b/workbench/fs/fat/cache.h @@ -25,9 +25,6 @@ struct cache_block { ULONG use_count; /* number of users of this block */ BOOL is_dirty; /* does the block need to be written? */ - struct Device *device; /* device this block was loaded from */ - struct Unit *unit; /* unit of aforementioned device */ - ULONG num; /* block number */ UBYTE *data; /* actual block data */ @@ -50,6 +47,9 @@ struct cache { struct cache_block *free_head; /* first block in the free list */ struct cache_block *free_tail; /* last block in the free list */ + struct Device *device; /* device to read/write */ + struct Unit *unit; /* unit on said device */ + ULONG hits; /* number of hits, for stats */ ULONG misses; /* number of misses */ }; @@ -58,13 +58,13 @@ struct cache { #define CACHE_WRITETHROUGH (1<<0) #define CACHE_WRITEBACK (1<<1) -struct cache *cache_new(ULONG hash_size, ULONG num_blocks, ULONG block_size, ULONG flags); +struct cache *cache_new(struct Device *device, struct Unit *unit, ULONG hash_size, ULONG num_blocks, ULONG block_size, ULONG flags); void cache_free(struct cache *c); -ULONG cache_get_block(struct cache *c, struct Device *dev, struct Unit *unit, ULONG num, ULONG flags, struct cache_block **rb); +ULONG cache_get_block(struct cache *c, ULONG num, ULONG flags, struct cache_block **rb); ULONG cache_put_block(struct cache *c, struct cache_block *b, ULONG flags); -ULONG cache_get_blocks(struct cache *c, struct Device *dev, struct Unit *unit, ULONG num, ULONG nblocks, ULONG flags, struct cache_block **rb); +ULONG cache_get_blocks(struct cache *c, ULONG num, ULONG nblocks, ULONG flags, struct cache_block **rb); ULONG cache_put_blocks(struct cache *c, struct cache_block **b, ULONG nblocks, ULONG flags); ULONG cache_mark_block_dirty(struct cache *c, struct cache_block *b); diff --git a/workbench/fs/fat/fat.c b/workbench/fs/fat/fat.c index ad3e15435..ca3318350 100644 --- a/workbench/fs/fat/fat.c +++ b/workbench/fs/fat/fat.c @@ -45,8 +45,6 @@ static UBYTE *GetFatEntryPtr(struct FSSuper *sb, ULONG offset, struct cache_bloc /* load some more */ cache_get_blocks(sb->cache, - glob->diskioreq->iotd_Req.io_Device, - glob->diskioreq->iotd_Req.io_Unit, sb->first_device_sector + sb->first_fat_sector + (entry_cache_block << (sb->fat_cachesize_bits - sb->sectorsize_bits)), sb->fat_blocks_count, @@ -299,7 +297,9 @@ LONG ReadFATSuper(struct FSSuper *sb ) { return ERROR_NOT_A_DOS_DISK; } - sb->cache = cache_new(64, 256, sb->sectorsize, CACHE_WRITETHROUGH); + sb->cache = cache_new(glob->diskioreq->iotd_Req.io_Device, + glob->diskioreq->iotd_Req.io_Unit, + 64, 256, sb->sectorsize, CACHE_WRITETHROUGH); if (sb->clusters_count < 4085) { D(bug("\tFAT12 filesystem detected\n")); diff --git a/workbench/fs/fat/file.c b/workbench/fs/fat/file.c index c851e3be8..2fb2d4aca 100644 --- a/workbench/fs/fat/file.c +++ b/workbench/fs/fat/file.c @@ -161,7 +161,7 @@ LONG ReadFileChunk(struct IOHandle *ioh, ULONG file_pos, ULONG nwant, UBYTE *dat D(bug("[fat] requesting sector %ld from cache\n", ioh->cur_sector)); - err = cache_get_block(ioh->sb->cache, glob->diskioreq->iotd_Req.io_Device, glob->diskioreq->iotd_Req.io_Unit, ioh->sb->first_device_sector + ioh->cur_sector, 0, &b); + err = cache_get_block(ioh->sb->cache, ioh->sb->first_device_sector + ioh->cur_sector, 0, &b); if (err > 0) { RESET_HANDLE(ioh); @@ -327,7 +327,7 @@ LONG WriteFileChunk(struct IOHandle *ioh, ULONG file_pos, ULONG nwant, UBYTE *da D(bug("[fat] requesting sector %ld from cache\n", ioh->cur_sector)); - err = cache_get_block(ioh->sb->cache, glob->diskioreq->iotd_Req.io_Device, glob->diskioreq->iotd_Req.io_Unit, ioh->sb->first_device_sector + ioh->cur_sector, 0, &b); + err = cache_get_block(ioh->sb->cache, ioh->sb->first_device_sector + ioh->cur_sector, 0, &b); if (err > 0) { RESET_HANDLE(ioh); -- 2.11.4.GIT