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.
This commit is contained in:
parent
2d43bf5807
commit
a89ec8bc3b
3 changed files with 49 additions and 47 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue