From a89ec8bc3b47cf320832464f38564ea072a4a466 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Mon, 12 Nov 2012 19:15:10 +0100 Subject: [PATCH] can't get_block(NO_DEV) any more . 'anonymous' cache blocks (retrieved with NO_DEV as dev parameter) were used to implement read()s from holes in inodes that should return zeroes . this is an awkward special case in the cache code though and there's a more direct way to implement the same functionality: instead of copying from a new, anonymous, zero block, to the user target buffer, simply sys_safememset the user target buffer directly. as this was the only use of this feature, this is all that's needed to simplify the cache code a little. --- lib/libminixfs/cache.c | 80 +++++++++++++++++++----------------------- servers/ext2/read.c | 8 +++-- servers/mfs/read.c | 8 +++-- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/lib/libminixfs/cache.c b/lib/libminixfs/cache.c index 1f3132c59..2772db091 100644 --- a/lib/libminixfs/cache.c +++ b/lib/libminixfs/cache.c @@ -156,29 +156,29 @@ struct buf *lmfs_get_block( ASSERT(fs_block_size > 0); + assert(dev != NO_DEV); + /* Search the hash chain for (dev, block). Do_read() can use * lmfs_get_block(NO_DEV ...) to get an unnamed block to fill with zeros when * someone wants to read from a hole in a file, in which case this search * is skipped */ - if (dev != NO_DEV) { - b = BUFHASH(block); - bp = buf_hash[b]; - while (bp != NULL) { - if (bp->lmfs_blocknr == block && bp->lmfs_dev == dev) { - /* Block needed has been found. */ - if (bp->lmfs_count == 0) rm_lru(bp); - bp->lmfs_count++; /* record that block is in use */ - ASSERT(bp->lmfs_bytes == fs_block_size); - ASSERT(bp->lmfs_dev == dev); - ASSERT(bp->lmfs_dev != NO_DEV); - ASSERT(bp->data); - return(bp); - } else { - /* This block is not the one sought. */ - bp = bp->lmfs_hash; /* move to next block on hash chain */ - } - } + b = BUFHASH(block); + bp = buf_hash[b]; + while (bp != NULL) { + if (bp->lmfs_blocknr == block && bp->lmfs_dev == dev) { + /* Block needed has been found. */ + if (bp->lmfs_count == 0) rm_lru(bp); + bp->lmfs_count++; /* record that block is in use */ + ASSERT(bp->lmfs_bytes == fs_block_size); + ASSERT(bp->lmfs_dev == dev); + ASSERT(bp->lmfs_dev != NO_DEV); + ASSERT(bp->data); + return(bp); + } else { + /* This block is not the one sought. */ + bp = bp->lmfs_hash; /* move to next block on hash chain */ + } } /* Desired block is not on available chain. Take oldest block ('front'). */ @@ -247,13 +247,7 @@ struct buf *lmfs_get_block( buf_hash[b] = bp; /* add to hash list */ - if(dev == NO_DEV) { - if(vmcache && cmp64(yieldid, VM_BLOCKID_NONE) != 0) { - vm_yield_block_get_block(yieldid, VM_BLOCKID_NONE, - bp->data, fs_block_size); - } - return(bp); /* If the caller wanted a NO_DEV block, work is done. */ - } + assert(dev != NO_DEV); /* Go get the requested block unless searching or prefetching. */ if(only_search == PREFETCH || only_search == NORMAL) { @@ -354,29 +348,29 @@ register struct buf *bp; /* buffer pointer */ */ int r, op_failed; u64_t pos; - dev_t dev; + dev_t dev = bp->lmfs_dev; op_failed = 0; - if ( (dev = bp->lmfs_dev) != NO_DEV) { - pos = mul64u(bp->lmfs_blocknr, fs_block_size); - r = bdev_read(dev, pos, bp->data, fs_block_size, - BDEV_NOFLAGS); - if (r < 0) { - printf("fs cache: I/O error on device %d/%d, block %u\n", - major(dev), minor(dev), bp->lmfs_blocknr); - op_failed = 1; - } else if (r != (ssize_t) fs_block_size) { - r = END_OF_FILE; - op_failed = 1; - } + assert(dev != NO_DEV); - if (op_failed) { - bp->lmfs_dev = NO_DEV; /* invalidate block */ + pos = mul64u(bp->lmfs_blocknr, fs_block_size); + r = bdev_read(dev, pos, bp->data, fs_block_size, + BDEV_NOFLAGS); + if (r < 0) { + printf("fs cache: I/O error on device %d/%d, block %u\n", + major(dev), minor(dev), bp->lmfs_blocknr); + op_failed = 1; + } else if (r != (ssize_t) fs_block_size) { + r = END_OF_FILE; + op_failed = 1; + } - /* Report read errors to interested parties. */ - rdwt_err = r; - } + if (op_failed) { + bp->lmfs_dev = NO_DEV; /* invalidate block */ + + /* Report read errors to interested parties. */ + rdwt_err = r; } } diff --git a/servers/ext2/read.c b/servers/ext2/read.c index 8d0c39c95..3597acf26 100644 --- a/servers/ext2/read.c +++ b/servers/ext2/read.c @@ -237,8 +237,12 @@ int *completed; /* number of bytes copied */ if (!block_spec && b == NO_BLOCK) { if (rw_flag == READING) { /* Reading from a nonexistent block. Must read as all zeros.*/ - bp = get_block(NO_DEV, NO_BLOCK, NORMAL); /* get a buffer */ - zero_block(bp); + r = sys_safememset(VFS_PROC_NR, gid, (vir_bytes) buf_off, + 0, (size_t) chunk); + if(r != OK) { + printf("ext2fs: sys_safememset failed\n"); + } + return r; } else { /* Writing to a nonexistent block. Create and enter in inode.*/ if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL) diff --git a/servers/mfs/read.c b/servers/mfs/read.c index 5d98956ed..408359ad3 100644 --- a/servers/mfs/read.c +++ b/servers/mfs/read.c @@ -246,8 +246,12 @@ int *completed; /* number of bytes copied */ if (!block_spec && b == NO_BLOCK) { if (rw_flag == READING) { /* Reading from a nonexistent block. Must read as all zeros.*/ - bp = get_block(NO_DEV, NO_BLOCK, NORMAL); /* get a buffer */ - zero_block(bp); + r = sys_safememset(VFS_PROC_NR, gid, (vir_bytes) buf_off, + 0, (size_t) chunk); + if(r != OK) { + printf("MFS: sys_safememset failed\n"); + } + return r; } else { /* Writing to a nonexistent block. Create and enter in inode.*/ if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)