MFS: annotate cache blocks with inode metadata
. use lmfs_* cache functions that provide the cache with inode metadata whenever applicable, i.e. tell the cache code which inode number and in-inode offset a particular cache block corresponds to. . needed for mmap implementation Change-Id: Ic7d3c0c49029880f86a31368278722e907bc2896
This commit is contained in:
parent
49eb1f4806
commit
6fa5ce74ce
|
@ -6,6 +6,7 @@
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include <minix/vfsif.h>
|
#include <minix/vfsif.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
#define SAME 1000
|
#define SAME 1000
|
||||||
|
|
||||||
|
@ -172,7 +173,6 @@ int fs_unlink()
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
int fs_rdlink()
|
int fs_rdlink()
|
||||||
{
|
{
|
||||||
block_t b; /* block containing link text */
|
|
||||||
struct buf *bp; /* buffer containing link text */
|
struct buf *bp; /* buffer containing link text */
|
||||||
register struct inode *rip; /* target inode */
|
register struct inode *rip; /* target inode */
|
||||||
register int r; /* return value */
|
register int r; /* return value */
|
||||||
|
@ -186,14 +186,13 @@ int fs_rdlink()
|
||||||
|
|
||||||
if(!S_ISLNK(rip->i_mode))
|
if(!S_ISLNK(rip->i_mode))
|
||||||
r = EACCES;
|
r = EACCES;
|
||||||
else if ((b = read_map(rip, (off_t) 0)) == NO_BLOCK)
|
|
||||||
r = EIO;
|
|
||||||
else {
|
else {
|
||||||
|
if(!(bp = get_block_map(rip, 0)))
|
||||||
|
return EIO;
|
||||||
/* Passed all checks */
|
/* Passed all checks */
|
||||||
/* We can safely cast to unsigned, because copylen is guaranteed to be
|
/* We can safely cast to unsigned, because copylen is guaranteed to be
|
||||||
below max file size */
|
below max file size */
|
||||||
copylen = min( copylen, (unsigned) rip->i_size);
|
copylen = min( copylen, (unsigned) rip->i_size);
|
||||||
bp = get_block(rip->i_dev, b, NORMAL);
|
|
||||||
r = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
|
r = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
|
||||||
(vir_bytes) 0, (vir_bytes) b_data(bp),
|
(vir_bytes) 0, (vir_bytes) b_data(bp),
|
||||||
(size_t) copylen);
|
(size_t) copylen);
|
||||||
|
@ -677,7 +676,6 @@ off_t len;
|
||||||
{
|
{
|
||||||
/* Zero an arbitrary byte range in a zone, possibly spanning multiple blocks.
|
/* Zero an arbitrary byte range in a zone, possibly spanning multiple blocks.
|
||||||
*/
|
*/
|
||||||
block_t b;
|
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
unsigned short block_size;
|
unsigned short block_size;
|
||||||
|
@ -686,10 +684,10 @@ off_t len;
|
||||||
block_size = rip->i_sp->s_block_size;
|
block_size = rip->i_sp->s_block_size;
|
||||||
|
|
||||||
if(!len) return; /* no zeroing to be done. */
|
if(!len) return; /* no zeroing to be done. */
|
||||||
if( (b = read_map(rip, pos)) == NO_BLOCK) return;
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if( (bp = get_block(rip->i_dev, b, NORMAL)) == NULL)
|
if( (bp = get_block_map(rip, rounddown(pos, block_size))) == NULL)
|
||||||
panic("zerozone_range: no block");
|
return;
|
||||||
offset = pos % block_size;
|
offset = pos % block_size;
|
||||||
bytes = block_size - offset;
|
bytes = block_size - offset;
|
||||||
if (bytes > (size_t) len)
|
if (bytes > (size_t) len)
|
||||||
|
@ -700,7 +698,6 @@ off_t len;
|
||||||
|
|
||||||
pos += bytes;
|
pos += bytes;
|
||||||
len -= bytes;
|
len -= bytes;
|
||||||
b++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -287,16 +287,13 @@ char *suffix; /* current remaining path. Has to point in the
|
||||||
* new pathname.
|
* new pathname.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
block_t blink; /* block containing link text */
|
|
||||||
size_t llen; /* length of link */
|
size_t llen; /* length of link */
|
||||||
size_t slen; /* length of suffix */
|
size_t slen; /* length of suffix */
|
||||||
struct buf *bp; /* buffer containing link text */
|
struct buf *bp; /* buffer containing link text */
|
||||||
char *sp; /* start of link text */
|
char *sp; /* start of link text */
|
||||||
|
|
||||||
if ((blink = read_map(rip, (off_t) 0)) == NO_BLOCK)
|
if(!(bp = get_block_map(rip, 0)))
|
||||||
return(EIO);
|
return(EIO);
|
||||||
|
|
||||||
bp = get_block(rip->i_dev, blink, NORMAL);
|
|
||||||
llen = (size_t) rip->i_size;
|
llen = (size_t) rip->i_size;
|
||||||
sp = b_data(bp);
|
sp = b_data(bp);
|
||||||
slen = strlen(suffix);
|
slen = strlen(suffix);
|
||||||
|
@ -485,7 +482,6 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||||
mode_t bits;
|
mode_t bits;
|
||||||
off_t pos;
|
off_t pos;
|
||||||
unsigned new_slots, old_slots;
|
unsigned new_slots, old_slots;
|
||||||
block_t b;
|
|
||||||
struct super_block *sp;
|
struct super_block *sp;
|
||||||
int extended = 0;
|
int extended = 0;
|
||||||
|
|
||||||
|
@ -524,12 +520,14 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; pos < ldir_ptr->i_size; pos += ldir_ptr->i_sp->s_block_size) {
|
for (; pos < ldir_ptr->i_size; pos += ldir_ptr->i_sp->s_block_size) {
|
||||||
b = read_map(ldir_ptr, pos); /* get block number */
|
assert(ldir_ptr->i_dev != NO_DEV);
|
||||||
|
|
||||||
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
|
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
|
||||||
bp = get_block(ldir_ptr->i_dev, b, NORMAL); /* get a dir block */
|
bp = get_block_map(ldir_ptr, pos);
|
||||||
|
|
||||||
|
assert(ldir_ptr->i_dev != NO_DEV);
|
||||||
assert(bp != NULL);
|
assert(bp != NULL);
|
||||||
|
assert(lmfs_dev(bp) != NO_DEV);
|
||||||
|
|
||||||
/* Search a directory block. */
|
/* Search a directory block. */
|
||||||
for (dp = &b_dir(bp)[0];
|
for (dp = &b_dir(bp)[0];
|
||||||
|
@ -573,6 +571,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||||
*numb = (ino_t) conv4(sp->s_native,
|
*numb = (ino_t) conv4(sp->s_native,
|
||||||
(int) dp->mfs_d_ino);
|
(int) dp->mfs_d_ino);
|
||||||
}
|
}
|
||||||
|
assert(lmfs_dev(bp) != NO_DEV);
|
||||||
put_block(bp, DIRECTORY_BLOCK);
|
put_block(bp, DIRECTORY_BLOCK);
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
@ -586,6 +585,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||||
|
|
||||||
/* The whole block has been searched or ENTER has a free slot. */
|
/* The whole block has been searched or ENTER has a free slot. */
|
||||||
if (e_hit) break; /* e_hit set if ENTER can be performed now */
|
if (e_hit) break; /* e_hit set if ENTER can be performed now */
|
||||||
|
assert(lmfs_dev(bp) != NO_DEV);
|
||||||
put_block(bp, DIRECTORY_BLOCK); /* otherwise, continue searching dir */
|
put_block(bp, DIRECTORY_BLOCK); /* otherwise, continue searching dir */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,8 @@ int read_only(struct inode *ip);
|
||||||
int fs_breadwrite(void);
|
int fs_breadwrite(void);
|
||||||
int fs_readwrite(void);
|
int fs_readwrite(void);
|
||||||
void read_ahead(void);
|
void read_ahead(void);
|
||||||
block_t read_map(struct inode *rip, off_t pos);
|
block_t read_map(struct inode *rip, off_t pos, int opportunistic);
|
||||||
|
struct buf *get_block_map(register struct inode *rip, u64_t position);
|
||||||
zone_t rd_indir(struct buf *bp, int index);
|
zone_t rd_indir(struct buf *bp, int index);
|
||||||
|
|
||||||
/* stadir.c */
|
/* stadir.c */
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
#include <minix/vfsif.h>
|
#include <minix/vfsif.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,6 +234,8 @@ int *completed; /* number of bytes copied */
|
||||||
int n, block_spec;
|
int n, block_spec;
|
||||||
block_t b;
|
block_t b;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
|
ino_t ino = VMC_NO_INODE;
|
||||||
|
u64_t ino_off = rounddown(position, block_size);
|
||||||
|
|
||||||
/* rw_flag:
|
/* rw_flag:
|
||||||
* READING: read from FS, copy to user
|
* READING: read from FS, copy to user
|
||||||
|
@ -250,8 +253,10 @@ int *completed; /* number of bytes copied */
|
||||||
} else {
|
} else {
|
||||||
if (ex64hi(position) != 0)
|
if (ex64hi(position) != 0)
|
||||||
panic("rw_chunk: position too high");
|
panic("rw_chunk: position too high");
|
||||||
b = read_map(rip, (off_t) ex64lo(position));
|
b = read_map(rip, (off_t) ex64lo(position), 0);
|
||||||
dev = rip->i_dev;
|
dev = rip->i_dev;
|
||||||
|
ino = rip->i_num;
|
||||||
|
assert(ino != VMC_NO_INODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!block_spec && b == NO_BLOCK) {
|
if (!block_spec && b == NO_BLOCK) {
|
||||||
|
@ -281,7 +286,14 @@ int *completed; /* number of bytes copied */
|
||||||
n = (chunk == block_size ? NO_READ : NORMAL);
|
n = (chunk == block_size ? NO_READ : NORMAL);
|
||||||
if (!block_spec && off == 0 && (off_t) ex64lo(position) >= rip->i_size)
|
if (!block_spec && off == 0 && (off_t) ex64lo(position) >= rip->i_size)
|
||||||
n = NO_READ;
|
n = NO_READ;
|
||||||
|
if(block_spec) {
|
||||||
|
assert(ino == VMC_NO_INODE);
|
||||||
bp = get_block(dev, b, n);
|
bp = get_block(dev, b, n);
|
||||||
|
} else {
|
||||||
|
assert(ino != VMC_NO_INODE);
|
||||||
|
assert(!(ino_off % block_size));
|
||||||
|
bp = lmfs_get_block_ino(dev, b, n, ino, ino_off);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In all cases, bp now points to a valid buffer. */
|
/* In all cases, bp now points to a valid buffer. */
|
||||||
|
@ -313,9 +325,10 @@ int *completed; /* number of bytes copied */
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* read_map *
|
* read_map *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
block_t read_map(rip, position)
|
block_t read_map(rip, position, opportunistic)
|
||||||
register struct inode *rip; /* ptr to inode to map from */
|
register struct inode *rip; /* ptr to inode to map from */
|
||||||
off_t position; /* position in file whose blk wanted */
|
off_t position; /* position in file whose blk wanted */
|
||||||
|
int opportunistic; /* if nonzero, only use cache for metadata */
|
||||||
{
|
{
|
||||||
/* Given an inode and a position within the corresponding file, locate the
|
/* Given an inode and a position within the corresponding file, locate the
|
||||||
* block (not zone) number in which that position is to be found and return it.
|
* block (not zone) number in which that position is to be found and return it.
|
||||||
|
@ -327,6 +340,9 @@ off_t position; /* position in file whose blk wanted */
|
||||||
unsigned int dzones, nr_indirects;
|
unsigned int dzones, nr_indirects;
|
||||||
block_t b;
|
block_t b;
|
||||||
unsigned long excess, zone, block_pos;
|
unsigned long excess, zone, block_pos;
|
||||||
|
int iomode = NORMAL;
|
||||||
|
|
||||||
|
if(opportunistic) iomode = PREFETCH;
|
||||||
|
|
||||||
scale = rip->i_sp->s_log_zone_size; /* for block-zone conversion */
|
scale = rip->i_sp->s_log_zone_size; /* for block-zone conversion */
|
||||||
block_pos = position/rip->i_sp->s_block_size; /* relative blk # in file */
|
block_pos = position/rip->i_sp->s_block_size; /* relative blk # in file */
|
||||||
|
@ -359,7 +375,11 @@ off_t position; /* position in file whose blk wanted */
|
||||||
index = (int) (excess/nr_indirects);
|
index = (int) (excess/nr_indirects);
|
||||||
if ((unsigned int) index > rip->i_nindirs)
|
if ((unsigned int) index > rip->i_nindirs)
|
||||||
return(NO_BLOCK); /* Can't go beyond double indirects */
|
return(NO_BLOCK); /* Can't go beyond double indirects */
|
||||||
bp = get_block(rip->i_dev, b, NORMAL); /* get double indirect block */
|
bp = get_block(rip->i_dev, b, iomode); /* get double indirect block */
|
||||||
|
if(opportunistic && lmfs_dev(bp) == NO_DEV) {
|
||||||
|
put_block(bp, INDIRECT_BLOCK);
|
||||||
|
return NO_BLOCK;
|
||||||
|
}
|
||||||
ASSERT(lmfs_dev(bp) != NO_DEV);
|
ASSERT(lmfs_dev(bp) != NO_DEV);
|
||||||
ASSERT(lmfs_dev(bp) == rip->i_dev);
|
ASSERT(lmfs_dev(bp) == rip->i_dev);
|
||||||
z = rd_indir(bp, index); /* z= zone for single*/
|
z = rd_indir(bp, index); /* z= zone for single*/
|
||||||
|
@ -370,7 +390,11 @@ off_t position; /* position in file whose blk wanted */
|
||||||
/* 'z' is zone num for single indirect block; 'excess' is index into it. */
|
/* 'z' is zone num for single indirect block; 'excess' is index into it. */
|
||||||
if (z == NO_ZONE) return(NO_BLOCK);
|
if (z == NO_ZONE) return(NO_BLOCK);
|
||||||
b = (block_t) z << scale; /* b is blk # for single ind */
|
b = (block_t) z << scale; /* b is blk # for single ind */
|
||||||
bp = get_block(rip->i_dev, b, NORMAL); /* get single indirect block */
|
bp = get_block(rip->i_dev, b, iomode); /* get single indirect block */
|
||||||
|
if(opportunistic && lmfs_dev(bp) == NO_DEV) {
|
||||||
|
put_block(bp, INDIRECT_BLOCK);
|
||||||
|
return NO_BLOCK;
|
||||||
|
}
|
||||||
z = rd_indir(bp, (int) excess); /* get block pointed to */
|
z = rd_indir(bp, (int) excess); /* get block pointed to */
|
||||||
put_block(bp, INDIRECT_BLOCK); /* release single indir blk */
|
put_block(bp, INDIRECT_BLOCK); /* release single indir blk */
|
||||||
if (z == NO_ZONE) return(NO_BLOCK);
|
if (z == NO_ZONE) return(NO_BLOCK);
|
||||||
|
@ -378,6 +402,16 @@ off_t position; /* position in file whose blk wanted */
|
||||||
return(b);
|
return(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct buf *get_block_map(register struct inode *rip, u64_t position)
|
||||||
|
{
|
||||||
|
block_t b = read_map(rip, position, 0); /* get block number */
|
||||||
|
int block_size = get_block_size(rip->i_dev);
|
||||||
|
if(b == NO_BLOCK)
|
||||||
|
return NULL;
|
||||||
|
position = rounddown(position, block_size);
|
||||||
|
assert(rip->i_num != VMC_NO_INODE);
|
||||||
|
return lmfs_get_block_ino(rip->i_dev, b, NORMAL, rip->i_num, position);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* rd_indir *
|
* rd_indir *
|
||||||
|
@ -442,6 +476,7 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
static unsigned int readqsize = 0;
|
static unsigned int readqsize = 0;
|
||||||
static struct buf **read_q;
|
static struct buf **read_q;
|
||||||
|
u64_t position_running;
|
||||||
|
|
||||||
if(readqsize != nr_bufs) {
|
if(readqsize != nr_bufs) {
|
||||||
if(readqsize > 0) {
|
if(readqsize > 0) {
|
||||||
|
@ -459,10 +494,23 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
||||||
else
|
else
|
||||||
dev = rip->i_dev;
|
dev = rip->i_dev;
|
||||||
|
|
||||||
|
assert(dev != NO_DEV);
|
||||||
|
|
||||||
block_size = get_block_size(dev);
|
block_size = get_block_size(dev);
|
||||||
|
|
||||||
block = baseblock;
|
block = baseblock;
|
||||||
|
|
||||||
|
fragment = position % block_size;
|
||||||
|
position -= fragment;
|
||||||
|
position_running = position;
|
||||||
|
bytes_ahead += fragment;
|
||||||
|
blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
|
||||||
|
|
||||||
|
if(block_spec)
|
||||||
bp = get_block(dev, block, PREFETCH);
|
bp = get_block(dev, block, PREFETCH);
|
||||||
|
else
|
||||||
|
bp = lmfs_get_block_ino(dev, block, PREFETCH, rip->i_num, position);
|
||||||
|
|
||||||
assert(bp != NULL);
|
assert(bp != NULL);
|
||||||
if (lmfs_dev(bp) != NO_DEV) return(bp);
|
if (lmfs_dev(bp) != NO_DEV) return(bp);
|
||||||
|
|
||||||
|
@ -486,12 +534,6 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
||||||
* indirect blocks (but don't call read_map!).
|
* indirect blocks (but don't call read_map!).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fragment = rem64u(position, block_size);
|
|
||||||
position = sub64u(position, fragment);
|
|
||||||
bytes_ahead += fragment;
|
|
||||||
|
|
||||||
blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
|
|
||||||
|
|
||||||
if (block_spec && rip->i_size == 0) {
|
if (block_spec && rip->i_size == 0) {
|
||||||
blocks_left = (block_t) NR_IOREQS;
|
blocks_left = (block_t) NR_IOREQS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -524,6 +566,7 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
||||||
|
|
||||||
/* Acquire block buffers. */
|
/* Acquire block buffers. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
block_t thisblock;
|
||||||
read_q[read_q_size++] = bp;
|
read_q[read_q_size++] = bp;
|
||||||
|
|
||||||
if (--blocks_ahead == 0) break;
|
if (--blocks_ahead == 0) break;
|
||||||
|
@ -532,8 +575,14 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
||||||
if (lmfs_bufs_in_use() >= nr_bufs - 4) break;
|
if (lmfs_bufs_in_use() >= nr_bufs - 4) break;
|
||||||
|
|
||||||
block++;
|
block++;
|
||||||
|
position_running += block_size;
|
||||||
|
|
||||||
|
if(!block_spec &&
|
||||||
|
(thisblock = read_map(rip, (off_t) ex64lo(position_running), 1)) != NO_BLOCK) {
|
||||||
|
bp = lmfs_get_block_ino(dev, thisblock, PREFETCH, rip->i_num, position_running);
|
||||||
|
} else {
|
||||||
bp = get_block(dev, block, PREFETCH);
|
bp = get_block(dev, block, PREFETCH);
|
||||||
|
}
|
||||||
if (lmfs_dev(bp) != NO_DEV) {
|
if (lmfs_dev(bp) != NO_DEV) {
|
||||||
/* Oops, block already in the cache, get out. */
|
/* Oops, block already in the cache, get out. */
|
||||||
put_block(bp, FULL_DATA_BLOCK);
|
put_block(bp, FULL_DATA_BLOCK);
|
||||||
|
@ -541,7 +590,10 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lmfs_rw_scattered(dev, read_q, read_q_size, READING);
|
lmfs_rw_scattered(dev, read_q, read_q_size, READING);
|
||||||
return(get_block(dev, baseblock, NORMAL));
|
|
||||||
|
if(block_spec)
|
||||||
|
return get_block(dev, baseblock, NORMAL);
|
||||||
|
return(lmfs_get_block_ino(dev, baseblock, NORMAL, rip->i_num, position));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -557,7 +609,6 @@ int fs_getdents(void)
|
||||||
int o, r, done;
|
int o, r, done;
|
||||||
unsigned int block_size, len, reclen;
|
unsigned int block_size, len, reclen;
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
block_t b;
|
|
||||||
cp_grant_id_t gid;
|
cp_grant_id_t gid;
|
||||||
size_t size, tmpbuf_off, userbuf_off;
|
size_t size, tmpbuf_off, userbuf_off;
|
||||||
off_t pos, off, block_pos, new_pos, ent_pos;
|
off_t pos, off, block_pos, new_pos, ent_pos;
|
||||||
|
@ -592,11 +643,8 @@ int fs_getdents(void)
|
||||||
new_pos = rip->i_size;
|
new_pos = rip->i_size;
|
||||||
|
|
||||||
for(; block_pos < rip->i_size; block_pos += block_size) {
|
for(; block_pos < rip->i_size; block_pos += block_size) {
|
||||||
b = read_map(rip, block_pos); /* get block number */
|
/* Since directories don't have holes, 'bp' cannot be NULL. */
|
||||||
|
bp = get_block_map(rip, block_pos); /* get a dir block */
|
||||||
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
|
|
||||||
bp = get_block(rip->i_dev, b, NORMAL); /* get a dir block */
|
|
||||||
|
|
||||||
assert(bp != NULL);
|
assert(bp != NULL);
|
||||||
|
|
||||||
/* Search a directory block. */
|
/* Search a directory block. */
|
||||||
|
|
|
@ -44,6 +44,6 @@ int (*fs_call_vec[])(void) = {
|
||||||
fs_rdlink, /* 30 */
|
fs_rdlink, /* 30 */
|
||||||
fs_getdents, /* 31 */
|
fs_getdents, /* 31 */
|
||||||
fs_statvfs, /* 32 */
|
fs_statvfs, /* 32 */
|
||||||
no_sys, /* 33 */ /* peek not supported */
|
fs_readwrite, /* 33 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
|
@ -99,7 +101,8 @@ int op; /* special actions */
|
||||||
z1 = NO_ZONE;
|
z1 = NO_ZONE;
|
||||||
} else {
|
} else {
|
||||||
b = (block_t) z << scale;
|
b = (block_t) z << scale;
|
||||||
bp_dindir = get_block(rip->i_dev, b, (new_dbl?NO_READ:NORMAL));
|
bp_dindir = get_block(rip->i_dev, b,
|
||||||
|
(new_dbl?NO_READ:NORMAL));
|
||||||
if (new_dbl) zero_block(bp_dindir);
|
if (new_dbl) zero_block(bp_dindir);
|
||||||
z1 = rd_indir(bp_dindir, ind_ex);
|
z1 = rd_indir(bp_dindir, ind_ex);
|
||||||
}
|
}
|
||||||
|
@ -239,31 +242,12 @@ int flag; /* 1 if called by new_block, 0 otherwise */
|
||||||
* a byte in the first block to be zeroed. Clearzone() is called from
|
* a byte in the first block to be zeroed. Clearzone() is called from
|
||||||
* fs_readwrite(), truncate_inode(), and new_block().
|
* fs_readwrite(), truncate_inode(), and new_block().
|
||||||
*/
|
*/
|
||||||
|
int scale;
|
||||||
struct buf *bp;
|
|
||||||
block_t b, blo, bhi;
|
|
||||||
off_t next;
|
|
||||||
int scale, zone_size;
|
|
||||||
|
|
||||||
/* If the block size and zone size are the same, clear_zone() not needed. */
|
/* If the block size and zone size are the same, clear_zone() not needed. */
|
||||||
scale = rip->i_sp->s_log_zone_size;
|
scale = rip->i_sp->s_log_zone_size;
|
||||||
if (scale == 0) return;
|
assert(scale == 0);
|
||||||
|
return;
|
||||||
zone_size = rip->i_sp->s_block_size << scale;
|
|
||||||
if (flag == 1) pos = (off_t) ((pos/zone_size) * zone_size);
|
|
||||||
next = pos + rip->i_sp->s_block_size - 1;
|
|
||||||
|
|
||||||
/* If 'pos' is in the last block of a zone, do not clear the zone. */
|
|
||||||
if (next/zone_size != pos/zone_size) return;
|
|
||||||
if ( (blo = read_map(rip, next)) == NO_BLOCK) return;
|
|
||||||
bhi = (block_t) ( ((blo>>scale)+1) << scale) - 1;
|
|
||||||
|
|
||||||
/* Clear all the blocks between 'blo' and 'bhi'. */
|
|
||||||
for (b = blo; b <= bhi; b++) {
|
|
||||||
bp = get_block(rip->i_dev, b, NO_READ);
|
|
||||||
zero_block(bp);
|
|
||||||
put_block(bp, FULL_DATA_BLOCK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,7 +270,7 @@ off_t position; /* file pointer */
|
||||||
int scale, r;
|
int scale, r;
|
||||||
|
|
||||||
/* Is another block available in the current zone? */
|
/* Is another block available in the current zone? */
|
||||||
if ( (b = read_map(rip, position)) == NO_BLOCK) {
|
if ( (b = read_map(rip, position, 0)) == NO_BLOCK) {
|
||||||
if (rip->i_zsearch == NO_ZONE) {
|
if (rip->i_zsearch == NO_ZONE) {
|
||||||
/* First search for this file. Start looking from
|
/* First search for this file. Start looking from
|
||||||
* the file's first data zone to prevent fragmentation
|
* the file's first data zone to prevent fragmentation
|
||||||
|
@ -316,7 +300,8 @@ off_t position; /* file pointer */
|
||||||
b = base_block + (block_t)((position % zone_size)/rip->i_sp->s_block_size);
|
b = base_block + (block_t)((position % zone_size)/rip->i_sp->s_block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bp = get_block(rip->i_dev, b, NO_READ);
|
bp = lmfs_get_block_ino(rip->i_dev, b, NO_READ, rip->i_num,
|
||||||
|
rounddown(position, rip->i_sp->s_block_size));
|
||||||
zero_block(bp);
|
zero_block(bp);
|
||||||
return(bp);
|
return(bp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue