mfs: use macros to mark blocks and inodes dirty

. No functional change
	. Only serves to get hooks to do checks in
	. e.g. should things be marked dirty when we are
	  mounted readonly

Signed-off-by: Ben Gras <ben@minix3.org>
This commit is contained in:
Ben Gras 2011-12-22 01:29:27 +01:00
parent 34a8901eb8
commit 9b7d357ca1
16 changed files with 63 additions and 43 deletions

View File

@ -1,6 +1,8 @@
#ifndef __MFS_BUF_H__ #ifndef __MFS_BUF_H__
#define __MFS_BUF_H__ #define __MFS_BUF_H__
#include "clean.h"
/* Buffer (block) cache. To acquire a block, a routine calls get_block(), /* Buffer (block) cache. To acquire a block, a routine calls get_block(),
* telling which block it wants. The block is then regarded as "in use" * telling which block it wants. The block is then regarded as "in use"
* and has its 'b_count' field incremented. All the blocks that are not * and has its 'b_count' field incremented. All the blocks that are not

View File

@ -136,7 +136,7 @@ PUBLIC struct buf *get_block(
* Avoid hysteresis by flushing all other dirty blocks for the same device. * Avoid hysteresis by flushing all other dirty blocks for the same device.
*/ */
if (bp->b_dev != NO_DEV) { if (bp->b_dev != NO_DEV) {
if (bp->b_dirt == DIRTY) flushall(bp->b_dev); if (ISDIRTY(bp)) flushall(bp->b_dev);
/* Are we throwing out a block that contained something? /* Are we throwing out a block that contained something?
* Give it to VM for the second-layer cache. * Give it to VM for the second-layer cache.
@ -360,8 +360,7 @@ int rw_flag; /* READING or WRITING */
} }
} }
bp->b_dirt = CLEAN; MARKCLEAN(bp);
} }
/*===========================================================================* /*===========================================================================*
@ -406,7 +405,7 @@ PUBLIC void flushall(
} }
for (bp = &buf[0], ndirty = 0; bp < &buf[nr_bufs]; bp++) for (bp = &buf[0], ndirty = 0; bp < &buf[nr_bufs]; bp++)
if (bp->b_dirt == DIRTY && bp->b_dev == dev) dirty[ndirty++] = bp; if (ISDIRTY(bp) && bp->b_dev == dev) dirty[ndirty++] = bp;
rw_scattered(dev, dirty, ndirty, WRITING); rw_scattered(dev, dirty, ndirty, WRITING);
} }
@ -487,7 +486,7 @@ PUBLIC void rw_scattered(
bp->b_dev = dev; /* validate block */ bp->b_dev = dev; /* validate block */
put_block(bp, PARTIAL_DATA_BLOCK); put_block(bp, PARTIAL_DATA_BLOCK);
} else { } else {
bp->b_dirt = CLEAN; MARKCLEAN(bp);
} }
r -= fs_block_size; r -= fs_block_size;
} }

11
servers/mfs/clean.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef _MFS_CLEAN_H
#define _MFS_CLEAN_H 1
#define MARKDIRTY(b) ((b)->b_dirt = BP_DIRTY)
#define MARKCLEAN(b) ((b)->b_dirt = BP_CLEAN)
#define ISDIRTY(b) ((b)->b_dirt == BP_DIRTY)
#define ISCLEAN(b) ((b)->b_dirt == BP_CLEAN)
#endif

View File

@ -57,8 +57,10 @@
#define IGN_PERM 0 #define IGN_PERM 0
#define CHK_PERM 1 #define CHK_PERM 1
#define CLEAN 0 /* disk and memory copies identical */ #define BP_CLEAN 0 /* on-disk block and memory copies identical */
#define DIRTY 1 /* disk and memory copies differ */ #define BP_DIRTY 1 /* on-disk block and memory copies differ */
#define IN_CLEAN 0 /* in-block inode and memory copies identical */
#define IN_DIRTY 1 /* in-block inode and memory copies differ */
#define ATIME 002 /* set if atime field needs updating */ #define ATIME 002 /* set if atime field needs updating */
#define CTIME 004 /* set if ctime field needs updating */ #define CTIME 004 /* set if ctime field needs updating */
#define MTIME 010 /* set if mtime field needs updating */ #define MTIME 010 /* set if mtime field needs updating */

View File

@ -233,12 +233,12 @@ register struct inode *rip; /* pointer to inode to be released */
*/ */
(void) truncate_inode(rip, (off_t) 0); (void) truncate_inode(rip, (off_t) 0);
rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */ rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
free_inode(rip->i_dev, rip->i_num); free_inode(rip->i_dev, rip->i_num);
} }
rip->i_mountpoint = FALSE; rip->i_mountpoint = FALSE;
if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING); if (IN_ISDIRTY(rip)) rw_inode(rip, WRITING);
if (rip->i_nlinks == NO_LINK) { if (rip->i_nlinks == NO_LINK) {
/* free, put at the front of the LRU list */ /* free, put at the front of the LRU list */
@ -325,7 +325,7 @@ register struct inode *rip; /* the inode to be erased */
rip->i_size = 0; rip->i_size = 0;
rip->i_update = ATIME | CTIME | MTIME; /* update all times later */ rip->i_update = ATIME | CTIME | MTIME; /* update all times later */
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE; for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE;
} }
@ -405,7 +405,7 @@ int rw_flag; /* READING or WRITING */
/* Do the read or write. */ /* Do the read or write. */
if (rw_flag == WRITING) { if (rw_flag == WRITING) {
if (rip->i_update) update_times(rip); /* times need updating */ if (rip->i_update) update_times(rip); /* times need updating */
if (sp->s_rd_only == FALSE) bp->b_dirt = DIRTY; if (sp->s_rd_only == FALSE) MARKDIRTY(bp);
} }
/* Copy the inode from the disk block to the in-core table or vice versa. /* Copy the inode from the disk block to the in-core table or vice versa.
@ -417,7 +417,7 @@ int rw_flag; /* READING or WRITING */
new_icopy(rip, dip2, rw_flag, sp->s_native); new_icopy(rip, dip2, rw_flag, sp->s_native);
put_block(bp, INODE_BLOCK); put_block(bp, INODE_BLOCK);
rip->i_dirt = CLEAN; IN_MARKCLEAN(rip);
} }

View File

@ -62,4 +62,10 @@ EXTERN unsigned int inode_cache_miss;
#define NO_SEEK 0 /* i_seek = NO_SEEK if last op was not SEEK */ #define NO_SEEK 0 /* i_seek = NO_SEEK if last op was not SEEK */
#define ISEEK 1 /* i_seek = ISEEK if last op was SEEK */ #define ISEEK 1 /* i_seek = ISEEK if last op was SEEK */
#define IN_MARKCLEAN(i) i->i_dirt = IN_CLEAN
#define IN_MARKDIRTY(i) i->i_dirt = IN_DIRTY
#define IN_ISCLEAN(i) i->i_dirt == IN_CLEAN
#define IN_ISDIRTY(i) i->i_dirt == IN_DIRTY
#endif #endif

View File

@ -97,7 +97,7 @@ PUBLIC int fs_link()
if(r == OK) { if(r == OK) {
rip->i_nlinks++; rip->i_nlinks++;
rip->i_update |= CTIME; rip->i_update |= CTIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
} }
/* Done. Release both inodes. */ /* Done. Release both inodes. */
@ -271,7 +271,7 @@ char file_name[MFS_NAME_MAX]; /* name of file to be removed */
if (r == OK) { if (r == OK) {
rip->i_nlinks--; /* entry deleted from parent's dir */ rip->i_nlinks--; /* entry deleted from parent's dir */
rip->i_update |= CTIME; rip->i_update |= CTIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
} }
put_inode(rip); put_inode(rip);
@ -471,7 +471,7 @@ PUBLIC int fs_rename()
if(search_dir(old_ip, dot2, &numb, ENTER, IGN_PERM) == OK) { if(search_dir(old_ip, dot2, &numb, ENTER, IGN_PERM) == OK) {
/* New link created. */ /* New link created. */
new_dirp->i_nlinks++; new_dirp->i_nlinks++;
new_dirp->i_dirt = DIRTY; IN_MARKDIRTY(new_dirp);
} }
} }
@ -546,7 +546,7 @@ off_t newsize; /* inode must become this size */
/* Next correct the inode size. */ /* Next correct the inode size. */
rip->i_size = newsize; rip->i_size = newsize;
rip->i_update |= CTIME | MTIME; rip->i_update |= CTIME | MTIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
return(OK); return(OK);
} }
@ -610,7 +610,7 @@ off_t start, end; /* range of bytes to free (end uninclusive) */
} }
rip->i_update |= CTIME | MTIME; rip->i_update |= CTIME | MTIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
return(OK); return(OK);
} }
@ -693,7 +693,7 @@ off_t len;
if (bytes > (size_t) len) if (bytes > (size_t) len)
bytes = len; bytes = len;
memset(bp->b_data + offset, 0, bytes); memset(bp->b_data + offset, 0, bytes);
bp->b_dirt = DIRTY; MARKDIRTY(bp);
put_block(bp, FULL_DATA_BLOCK); put_block(bp, FULL_DATA_BLOCK);
pos += bytes; pos += bytes;

View File

@ -3,7 +3,7 @@
#include <minix/vfsif.h> #include <minix/vfsif.h>
#include <minix/bdev.h> #include <minix/bdev.h>
#include "inode.h" #include "inode.h"
#include "clean.h"
/*===========================================================================* /*===========================================================================*
* fs_sync * * fs_sync *
@ -23,11 +23,11 @@ PUBLIC int fs_sync()
/* Write all the dirty inodes to the disk. */ /* Write all the dirty inodes to the disk. */
for(rip = &inode[0]; rip < &inode[NR_INODES]; rip++) for(rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
if(rip->i_count > 0 && rip->i_dirt == DIRTY) rw_inode(rip, WRITING); if(rip->i_count > 0 && IN_ISDIRTY(rip)) rw_inode(rip, WRITING);
/* Write all the dirty blocks to the disk, one drive at a time. */ /* Write all the dirty blocks to the disk, one drive at a time. */
for(bp = &buf[0]; bp < &buf[nr_bufs]; bp++) for(bp = &buf[0]; bp < &buf[nr_bufs]; bp++)
if(bp->b_dev != NO_DEV && bp->b_dirt == DIRTY) if(bp->b_dev != NO_DEV && ISDIRTY(bp))
flushall(bp->b_dev); flushall(bp->b_dev);
return(OK); /* sync() can't fail */ return(OK); /* sync() can't fail */

View File

@ -150,7 +150,7 @@ PUBLIC int fs_mkdir()
/* Normal case. It was possible to enter . and .. in the new dir. */ /* Normal case. It was possible to enter . and .. in the new dir. */
rip->i_nlinks++; /* this accounts for . */ rip->i_nlinks++; /* this accounts for . */
ldirp->i_nlinks++; /* this accounts for .. */ ldirp->i_nlinks++; /* this accounts for .. */
ldirp->i_dirt = DIRTY; /* mark parent's inode as dirty */ IN_MARKDIRTY(ldirp); /* mark parent's inode as dirty */
} else { } else {
/* It was not possible to enter . or .. probably disk was full - /* It was not possible to enter . or .. probably disk was full -
* links counts haven't been touched. */ * links counts haven't been touched. */
@ -158,7 +158,7 @@ PUBLIC int fs_mkdir()
panic("Dir disappeared: %ul", rip->i_num); panic("Dir disappeared: %ul", rip->i_num);
rip->i_nlinks--; /* undo the increment done in new_node() */ rip->i_nlinks--; /* undo the increment done in new_node() */
} }
rip->i_dirt = DIRTY; /* either way, i_nlinks has changed */ IN_MARKDIRTY(rip); /* either way, i_nlinks has changed */
put_inode(ldirp); /* return the inode of the parent dir */ put_inode(ldirp); /* return the inode of the parent dir */
put_inode(rip); /* return the inode of the newly made dir */ put_inode(rip); /* return the inode of the newly made dir */
@ -293,7 +293,7 @@ PRIVATE struct inode *new_node(struct inode *ldirp,
/* New inode acquired. Try to make directory entry. */ /* New inode acquired. Try to make directory entry. */
if((r=search_dir(ldirp, string, &rip->i_num, ENTER, IGN_PERM)) != OK) { if((r=search_dir(ldirp, string, &rip->i_num, ENTER, IGN_PERM)) != OK) {
rip->i_nlinks--; /* pity, have to free disk inode */ rip->i_nlinks--; /* pity, have to free disk inode */
rip->i_dirt = DIRTY; /* dirty inodes are written out */ IN_MARKDIRTY(rip); /* dirty inodes are written out */
put_inode(rip); /* this call frees the inode */ put_inode(rip); /* this call frees the inode */
err_code = r; err_code = r;
return(NULL); return(NULL);

View File

@ -561,9 +561,9 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
t = MFS_NAME_MAX - sizeof(ino_t); t = MFS_NAME_MAX - sizeof(ino_t);
*((ino_t *) &dp->mfs_d_name[t]) = dp->mfs_d_ino; *((ino_t *) &dp->mfs_d_name[t]) = dp->mfs_d_ino;
dp->mfs_d_ino = NO_ENTRY; /* erase entry */ dp->mfs_d_ino = NO_ENTRY; /* erase entry */
bp->b_dirt = DIRTY; MARKDIRTY(bp);
ldir_ptr->i_update |= CTIME | MTIME; ldir_ptr->i_update |= CTIME | MTIME;
ldir_ptr->i_dirt = DIRTY; IN_MARKDIRTY(ldir_ptr);
if (pos < ldir_ptr->i_last_dpos) if (pos < ldir_ptr->i_last_dpos)
ldir_ptr->i_last_dpos = pos; ldir_ptr->i_last_dpos = pos;
} else { } else {
@ -614,10 +614,10 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
for (i = 0; i < MFS_NAME_MAX && string[i]; i++) dp->mfs_d_name[i] = string[i]; for (i = 0; i < MFS_NAME_MAX && string[i]; i++) dp->mfs_d_name[i] = string[i];
sp = ldir_ptr->i_sp; sp = ldir_ptr->i_sp;
dp->mfs_d_ino = conv4(sp->s_native, (int) *numb); dp->mfs_d_ino = conv4(sp->s_native, (int) *numb);
bp->b_dirt = DIRTY; MARKDIRTY(bp);
put_block(bp, DIRECTORY_BLOCK); put_block(bp, DIRECTORY_BLOCK);
ldir_ptr->i_update |= CTIME | MTIME; /* mark mtime for update later */ ldir_ptr->i_update |= CTIME | MTIME; /* mark mtime for update later */
ldir_ptr->i_dirt = DIRTY; IN_MARKDIRTY(ldir_ptr);
if (new_slots > old_slots) { if (new_slots > old_slots) {
ldir_ptr->i_size = (off_t) new_slots * DIR_ENTRY_SIZE; ldir_ptr->i_size = (off_t) new_slots * DIR_ENTRY_SIZE;
/* Send the change to disk if the directory is extended. */ /* Send the change to disk if the directory is extended. */

View File

@ -25,7 +25,7 @@ PUBLIC int fs_chmod()
/* Now make the change. Clear setgid bit if file is not in caller's grp */ /* Now make the change. Clear setgid bit if file is not in caller's grp */
rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES); rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
rip->i_update |= CTIME; rip->i_update |= CTIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
/* Return full new mode to caller. */ /* Return full new mode to caller. */
fs_m_out.RES_MODE = rip->i_mode; fs_m_out.RES_MODE = rip->i_mode;
@ -54,7 +54,7 @@ PUBLIC int fs_chown()
rip->i_gid = (gid_t) fs_m_in.REQ_GID; rip->i_gid = (gid_t) fs_m_in.REQ_GID;
rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT); rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
rip->i_update |= CTIME; rip->i_update |= CTIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
} }
/* Update caller on current mode, as it may have changed. */ /* Update caller on current mode, as it may have changed. */

View File

@ -117,7 +117,7 @@ PUBLIC int fs_readwrite(void)
if (r == OK) { if (r == OK) {
if (rw_flag == READING) rip->i_update |= ATIME; if (rw_flag == READING) rip->i_update |= ATIME;
if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
rip->i_dirt = DIRTY; /* inode is thus now dirty */ IN_MARKDIRTY(rip); /* inode is thus now dirty */
} }
fs_m_out.RES_NBYTES = cum_io; fs_m_out.RES_NBYTES = cum_io;
@ -267,7 +267,7 @@ int *completed; /* number of bytes copied */
/* Copy a chunk from user space to the block buffer. */ /* Copy a chunk from user space to the block buffer. */
r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off, r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off,
(vir_bytes) (bp->b_data+off), (size_t) chunk, D); (vir_bytes) (bp->b_data+off), (size_t) chunk, D);
bp->b_dirt = DIRTY; MARKDIRTY(bp);
} }
n = (off + chunk == block_size ? FULL_DATA_BLOCK : PARTIAL_DATA_BLOCK); n = (off + chunk == block_size ? FULL_DATA_BLOCK : PARTIAL_DATA_BLOCK);
@ -643,7 +643,7 @@ PUBLIC int fs_getdents(void)
fs_m_out.RES_NBYTES = userbuf_off; fs_m_out.RES_NBYTES = userbuf_off;
fs_m_out.RES_SEEK_POS_LO = new_pos; fs_m_out.RES_SEEK_POS_LO = new_pos;
rip->i_update |= ATIME; rip->i_update |= ATIME;
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
r = OK; r = OK;
} }

View File

@ -88,7 +88,7 @@ bit_t origin; /* number of bit to start searching at */
/* Allocate and return bit number. */ /* Allocate and return bit number. */
k |= 1 << i; k |= 1 << i;
*wptr = (bitchunk_t) conv4(sp->s_native, (int) k); *wptr = (bitchunk_t) conv4(sp->s_native, (int) k);
bp->b_dirt = DIRTY; MARKDIRTY(bp);
put_block(bp, MAP_BLOCK); put_block(bp, MAP_BLOCK);
return(b); return(b);
} }
@ -140,7 +140,7 @@ bit_t bit_returned; /* number of bit to insert into the map */
k &= ~mask; k &= ~mask;
bp->b_bitmap[word] = (bitchunk_t) conv4(sp->s_native, (int) k); bp->b_bitmap[word] = (bitchunk_t) conv4(sp->s_native, (int) k);
bp->b_dirt = DIRTY; MARKDIRTY(bp);
put_block(bp, MAP_BLOCK); put_block(bp, MAP_BLOCK);
} }

View File

@ -22,7 +22,7 @@ PUBLIC int fs_utime()
rip->i_atime = fs_m_in.REQ_ACTIME; rip->i_atime = fs_m_in.REQ_ACTIME;
rip->i_mtime = fs_m_in.REQ_MODTIME; rip->i_mtime = fs_m_in.REQ_MODTIME;
rip->i_update = CTIME; /* discard any stale ATIME and MTIME flags */ rip->i_update = CTIME; /* discard any stale ATIME and MTIME flags */
rip->i_dirt = DIRTY; IN_MARKDIRTY(rip);
} }
put_inode(rip); put_inode(rip);

View File

@ -35,7 +35,7 @@ struct buf {
struct buf *b_hash; /* used to link bufs on hash chains */ struct buf *b_hash; /* used to link bufs on hash chains */
block_t b_blocknr; /* block number of its (minor) device */ block_t b_blocknr; /* block number of its (minor) device */
dev_t b_dev; /* major | minor device where block resides */ dev_t b_dev; /* major | minor device where block resides */
char b_dirt; /* CLEAN or DIRTY */ char b_dirt; /* BP_CLEAN or BP_DIRTY */
char b_count; /* number of users of this buffer */ char b_count; /* number of users of this buffer */
unsigned int b_bytes; /* Number of bytes allocated in bp */ unsigned int b_bytes; /* Number of bytes allocated in bp */
}; };

View File

@ -44,7 +44,7 @@ int op; /* special actions */
long excess, zone; long excess, zone;
struct buf *bp_dindir = NULL, *bp = NULL; struct buf *bp_dindir = NULL, *bp = NULL;
rip->i_dirt = DIRTY; /* inode will be changed */ IN_MARKDIRTY(rip);
scale = rip->i_sp->s_log_zone_size; /* for zone-block conversion */ scale = rip->i_sp->s_log_zone_size; /* for zone-block conversion */
/* relative zone # to insert */ /* relative zone # to insert */
zone = (position/rip->i_sp->s_block_size) >> scale; zone = (position/rip->i_sp->s_block_size) >> scale;
@ -119,7 +119,7 @@ int op; /* special actions */
new_ind = TRUE; new_ind = TRUE;
/* If double ind, it is dirty. */ /* If double ind, it is dirty. */
if (bp_dindir != NULL) bp_dindir->b_dirt = DIRTY; if (bp_dindir != NULL) MARKDIRTY(bp_dindir);
if (z1 == NO_ZONE) { if (z1 == NO_ZONE) {
/* Release dbl indirect blk. */ /* Release dbl indirect blk. */
put_block(bp_dindir, INDIRECT_BLOCK); put_block(bp_dindir, INDIRECT_BLOCK);
@ -155,14 +155,14 @@ int op; /* special actions */
rip->i_zone[zones] = z1; rip->i_zone[zones] = z1;
} else { } else {
wr_indir(bp_dindir, ind_ex, z1); wr_indir(bp_dindir, ind_ex, z1);
bp_dindir->b_dirt = DIRTY; MARKDIRTY(bp_dindir);
} }
} }
} else { } else {
wr_indir(bp, ex, new_zone); wr_indir(bp, ex, new_zone);
} }
/* z1 equals NO_ZONE only when we are freeing up the indirect block. */ /* z1 equals NO_ZONE only when we are freeing up the indirect block. */
bp->b_dirt = (z1 == NO_ZONE) ? CLEAN : DIRTY; if(z1 == NO_ZONE) { MARKCLEAN(bp); } else { MARKDIRTY(bp); }
put_block(bp, INDIRECT_BLOCK); put_block(bp, INDIRECT_BLOCK);
} }
@ -172,7 +172,7 @@ int op; /* special actions */
*/ */
if(z1 == NO_ZONE && !single && z2 != NO_ZONE && if(z1 == NO_ZONE && !single && z2 != NO_ZONE &&
empty_indir(bp_dindir, rip->i_sp)) { empty_indir(bp_dindir, rip->i_sp)) {
bp_dindir->b_dirt = CLEAN; MARKCLEAN(bp_dindir);
free_zone(rip->i_dev, z2); free_zone(rip->i_dev, z2);
rip->i_zone[zones+1] = NO_ZONE; rip->i_zone[zones+1] = NO_ZONE;
} }
@ -332,6 +332,6 @@ register struct buf *bp; /* pointer to buffer to zero */
ASSERT(bp->b_bytes > 0); ASSERT(bp->b_bytes > 0);
ASSERT(bp->bp); ASSERT(bp->bp);
memset(bp->b_data, 0, (size_t) bp->b_bytes); memset(bp->b_data, 0, (size_t) bp->b_bytes);
bp->b_dirt = DIRTY; MARKDIRTY(bp);
} }