int32_t bread(int fd, char *buf, daddr_t blk, long size) { char *cp; int i, errs; offset_t offset = ldbtob(blk); offset_t addr; if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); else if (read(fd, buf, (int)size) == size) return (0); rwerror(gettext("READ"), blk); if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); errs = 0; bzero(buf, (int)size); pwarn(gettext("THE FOLLOWING SECTORS COULD NOT BE READ:")); for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) { addr = ldbtob(blk + i); if (llseek(fd, addr, SEEK_CUR) < 0 || read(fd, cp, (int)secsize) < 0) { (void) printf(" %ld", blk + i); errs++; } } (void) printf("\n"); return (errs); }
void bwrite(int fd, char *buf, daddr_t blk, long size) { int i, n; char *cp; offset_t offset = ldbtob(blk); offset_t addr; if (fd < 0) return; if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); else if (write(fd, buf, (int)size) == size) { fsmodified = 1; return; } rwerror(gettext("WRITE"), blk); if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); pwarn(gettext("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:")); for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) { n = 0; addr = ldbtob(blk + i); if (llseek(fd, addr, SEEK_CUR) < 0 || (n = write(fd, cp, DEV_BSIZE)) < 0) { (void) printf(" %ld", blk + i); } else if (n > 0) { fsmodified = 1; } } (void) printf("\n"); }
static int diskuse (const char *device, struct usage *use_by_uid) { ino_t inode; daddr32_t inode_blk; int i; int fd; int num_inodes; struct dinode inode_tab [MAXBSIZE / sizeof (struct dinode)]; union sb_union sbu; if ((fd = open (device, O_RDONLY)) == -1) { err_ret ("diskuse: %s", device); return (-1); } sync (); if (pread (fd, &sb, SBSIZE, ldbtob (SBLOCK)) == -1) { close (fd); return (-1); } num_inodes = sb.fs_ipg * sb.fs_ncg; for (inode = 0; inode < num_inodes;) { inode_blk = fsbtodb (&sb, itod (&sb, inode)); if (pread (fd, inode_tab, sb.fs_bsize, ldbtob (inode_blk)) == -1) { close (fd); return (-1); } for (i = 0; i < INOPB (&sb) && inode < num_inodes; i++, inode++) { if (inode < UFSROOTINO) continue; if ((inode_tab [i].di_mode & IFMT) == 0) continue; use_by_uid [inode_tab [i].di_uid].blocks += inode_tab [i].di_blocks; use_by_uid [inode_tab [i].di_uid].inodes++; } } return (0); }
/* * Called from roll thread; * buffer set for reading master * Returns * 0 - success, can continue with next buffer * 1 - failure due to logmap deltas being in use */ int top_read_roll(rollbuf_t *rbp, ml_unit_t *ul) { buf_t *bp = &rbp->rb_bh; offset_t mof = ldbtob(bp->b_blkno); /* * get a list of deltas */ if (logmap_list_get_roll(ul->un_logmap, mof, rbp)) { /* logmap deltas are in use */ return (1); } /* * no deltas were found, nothing to roll */ if (rbp->rb_age == NULL) { bp->b_flags |= B_INVAL; return (0); } /* * If there is one cached roll buffer that cover all the deltas then * we can use that instead of copying to a separate roll buffer. */ if (rbp->rb_crb) { rbp->rb_bh.b_blkno = lbtodb(rbp->rb_crb->c_mof); return (0); } /* * Set up the read. * If no read is needed logmap_setup_read() returns 0. */ if (logmap_setup_read(rbp->rb_age, rbp)) { /* * async read the data from master */ logstats.ls_rreads.value.ui64++; bp->b_bcount = MAPBLOCKSIZE; (void) bdev_strategy(bp); lwp_stat_update(LWP_STAT_INBLK, 1); } else { sema_v(&bp->b_io); /* mark read as complete */ } return (0); }
static void vdev_file_io_strategy(void *arg) { buf_t *bp = arg; vnode_t *vp = bp->b_private; ssize_t resid; int error; error = vn_rdwr((bp->b_flags & B_READ) ? UIO_READ : UIO_WRITE, vp, bp->b_un.b_addr, bp->b_bcount, ldbtob(bp->b_lblkno), UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid); if (error == 0) { bp->b_resid = resid; biodone(bp); } else { bioerror(bp, error); biodone(bp); } }
int zvol_strategy(buf_t *bp) { zvol_state_t *zv = ddi_get_soft_state(zvol_state, getminor(bp->b_edev)); uint64_t off, volsize; size_t size, resid; char *addr; objset_t *os; int error = 0; int sync; int reading; int txg_sync_needed = B_FALSE; if (zv == NULL) { bioerror(bp, ENXIO); biodone(bp); return (0); } if (getminor(bp->b_edev) == 0) { bioerror(bp, EINVAL); biodone(bp); return (0); } if (zv->zv_readonly && !(bp->b_flags & B_READ)) { bioerror(bp, EROFS); biodone(bp); return (0); } off = ldbtob(bp->b_blkno); volsize = zv->zv_volsize; os = zv->zv_objset; ASSERT(os != NULL); sync = !(bp->b_flags & B_ASYNC) && !(zil_disable); bp_mapin(bp); addr = bp->b_un.b_addr; resid = bp->b_bcount; /* * There must be no buffer changes when doing a dmu_sync() because * we can't change the data whilst calculating the checksum. * A better approach than a per zvol rwlock would be to lock ranges. */ reading = bp->b_flags & B_READ; if (reading || resid <= zvol_immediate_write_sz) rw_enter(&zv->zv_dslock, RW_READER); else rw_enter(&zv->zv_dslock, RW_WRITER); while (resid != 0 && off < volsize) { size = MIN(resid, 1UL << 20); /* cap at 1MB per tx */ if (size > volsize - off) /* don't write past the end */ size = volsize - off; if (reading) { error = dmu_read(os, ZVOL_OBJ, off, size, addr); } else { dmu_tx_t *tx = dmu_tx_create(os); dmu_tx_hold_write(tx, ZVOL_OBJ, off, size); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { dmu_tx_abort(tx); } else { dmu_write(os, ZVOL_OBJ, off, size, addr, tx); if (sync) { /* use the ZIL to commit this write */ if (zvol_log_write(zv, tx, off, size, addr) != 0) { txg_sync_needed = B_TRUE; } } dmu_tx_commit(tx); } } if (error) break; off += size; addr += size; resid -= size; } rw_exit(&zv->zv_dslock); if ((bp->b_resid = resid) == bp->b_bcount) bioerror(bp, off > volsize ? EINVAL : error); biodone(bp); if (sync) { if (txg_sync_needed) txg_wait_synced(dmu_objset_pool(os), 0); else zil_commit(zv->zv_zilog, UINT64_MAX, 0); } return (0); }
void lqfs_write_strategy(ml_unit_t *ul, buf_t *bp) { offset_t mof = ldbtob(bp->b_blkno); off_t nb = bp->b_bcount; char *va; mapentry_t *me; uchar_t ord; qfsvfs_t *qfsvfsp = ul->un_qfsvfs; #ifdef LUFS #else caddr_t buf; va = bp_mapin_common(bp, VM_SLEEP); buf = bp->b_un.b_addr; #endif /* LUFS */ ASSERT((nb & DEV_BMASK) == 0); ul->un_logmap->mtm_ref = 1; /* * if there are deltas, move into log */ ord = lqfs_find_ord(qfsvfsp, bp); #ifdef LUFS me = deltamap_remove(ul->un_deltamap, mof, ord, nb); if (me) { va = bp_mapin_common(bp, VM_SLEEP); ASSERT(((ul->un_debug & MT_WRITE_CHECK) == 0) || (ul->un_matamap == NULL)|| matamap_within(ul->un_matamap, mof, ord, nb)); /* * move to logmap */ if (qfs_crb_enable) { logmap_add_buf(ul, va, mof, ord, me, bp->b_un.b_addr, nb); } else { logmap_add(ul, va, mof, ord, me); } if (ul->un_flags & LDL_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; } biodone(bp); return; } #else if (buf && qfs_crb_enable) { uint32_t bufsz; offset_t vamof; offset_t hmof; uchar_t vaord; uchar_t hord; uint32_t hnb, nb1; bufsz = bp->b_bcount; ASSERT((bufsz & DEV_BMASK) == 0); vamof = mof; vaord = ord; /* * Move any deltas to the logmap. Split requests that * straddle MAPBLOCKSIZE hash boundaries (i.e. summary info). */ for (hmof = vamof - (va - buf), nb1 = nb; bufsz; bufsz -= hnb, hmof += hnb, buf += hnb, nb1 -= hnb) { hnb = MAPBLOCKSIZE - (hmof & MAPBLOCKOFF); if (hnb > bufsz) { hnb = bufsz; } LQFS_MSG(CE_WARN, "lqfs_write_strategy(): Removing " "deltamap deltas within mof 0x%llx ord %d nb %d\n", MAX(hmof, vamof), vaord, MIN(hnb, nb1)); me = deltamap_remove(ul->un_deltamap, MAX(hmof, vamof), vaord, MIN(hnb, nb1)); hord = vaord; if (me) { logmap_add_buf(ul, va, hmof, hord, me, buf, hnb); if (ul->un_flags & LDL_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; } biodone(bp); return; } } } else { /* * if there are deltas */ LQFS_MSG(CE_WARN, "lqfs_write_strategy(): Removing " "deltamap deltas within mof 0x%x ord %d nb %d\n", mof, ord, nb); me = deltamap_remove(ul->un_deltamap, mof, ord, nb); if (me) { ASSERT(((ul->un_debug & MT_WRITE_CHECK) == 0) || (ul->un_matamap == NULL)|| matamap_within(ul->un_matamap, mof, ord, nb)); /* * move to logmap */ logmap_add(ul, va, mof, ord, me); if (ul->un_flags & LDL_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; } biodone(bp); return; } } #endif /* LUFS */ if (ul->un_flags & LDL_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; biodone(bp); return; } /* * Check that we are not updating metadata, or if so then via B_PHYS. */ ASSERT((ul->un_matamap == NULL) || !(matamap_overlap(ul->un_matamap, mof, ord, nb) && ((bp->b_flags & B_PHYS) == 0))); LQFS_SET_IOTSTAMP(ul->un_qfsvfs, ddi_get_lbolt()); logstats.ls_lwrites.value.ui64++; #ifdef LQFS_TODO_SNAPSHOT /* If snapshots are enabled, write through the snapshot driver */ if (ul->un_qfsvfs->vfs_snapshot) { fssnap_strategy(&ul->un_qfsvfs->vfs_snapshot, bp); } else { #endif /* LQFS_TODO_SNAPSHOT */ if ((bp->b_flags & B_READ) == 0) { LQFS_MSG(CE_WARN, "lqfs_write_strategy(): " "bdev_strategy writing mof 0x%x edev %ld " "nb %d\n", bp->b_blkno * 512, bp->b_edev, bp->b_bcount); } else { LQFS_MSG(CE_WARN, "lqfs_write_strategy(): " "bdev_strategy reading mof 0x%x edev %ld " "nb %d\n", bp->b_blkno * 512, bp->b_edev, bp->b_bcount); } (void) bdev_strategy(bp); #ifdef LQFS_TODO_SNAPSHOT } #endif /* LQFS_TODO_SNAPSHOT */ #ifdef LQFS_TODO_STATS lwp_stat_update(LWP_STAT_OUBLK, 1); #endif /* LQFS_TODO_STATS */ }
void lqfs_read_strategy(ml_unit_t *ul, buf_t *bp) { mt_map_t *logmap = ul->un_logmap; offset_t mof = ldbtob(bp->b_blkno); off_t nb = bp->b_bcount; mapentry_t *age; char *va; int (*saviodone)(); int entire_range; uchar_t ord; qfsvfs_t *qfsvfsp = ul->un_qfsvfs; /* * get a linked list of overlapping deltas * returns with &mtm->mtm_rwlock held */ ord = lqfs_find_ord(qfsvfsp, bp); entire_range = logmap_list_get(logmap, mof, ord, nb, &age); /* * no overlapping deltas were found; read master */ if (age == NULL) { rw_exit(&logmap->mtm_rwlock); if (ul->un_flags & LDL_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; biodone(bp); } else { LQFS_SET_IOTSTAMP(ul->un_qfsvfs, ddi_get_lbolt()); logstats.ls_lreads.value.ui64++; if ((bp->b_flags & B_READ) == 0) { LQFS_MSG(CE_WARN, "lqfs_read_strategy(): " "bdev_strategy writing mof 0x%x " "edev %ld nb %d\n", bp->b_blkno * 512, bp->b_edev, bp->b_bcount); } else { LQFS_MSG(CE_WARN, "lqfs_read_strategy(): " "bdev_strategy reading mof 0x%x " "edev %ld nb %d\n", bp->b_blkno * 512, bp->b_edev, bp->b_bcount); } (void) bdev_strategy(bp); #ifdef LQFS_TODO_STATS lwp_stat_update(LWP_STAT_INBLK, 1); #endif /* LQFS_TODO_STATS */ } return; } va = bp_mapin_common(bp, VM_SLEEP); /* * if necessary, sync read the data from master * errors are returned in bp */ if (!entire_range) { saviodone = bp->b_iodone; bp->b_iodone = trans_not_done; logstats.ls_mreads.value.ui64++; if ((bp->b_flags & B_READ) == 0) { LQFS_MSG(CE_WARN, "lqfs_read_strategy(): " "bdev_strategy writing mof 0x%x edev %ld " "nb %d\n", bp->b_blkno * 512, bp->b_edev, bp->b_bcount); } else { LQFS_MSG(CE_WARN, "lqfs_read_strategy(): " "bdev_strategy reading mof 0x%x edev %ld " "nb %d\n", bp->b_blkno * 512, bp->b_edev, bp->b_bcount); } (void) bdev_strategy(bp); #ifdef LQFS_TODO_STATS lwp_stat_update(LWP_STAT_INBLK, 1); #endif /* LQFS_TODO_STATS */ if (trans_not_wait(bp)) { ldl_seterror(ul, "Error reading master"); } bp->b_iodone = saviodone; } /* * sync read the data from the log * errors are returned inline */ if (ldl_read(ul, va, mof, ord, nb, age)) { bp->b_flags |= B_ERROR; bp->b_error = EIO; } /* * unlist the deltas */ logmap_list_put(logmap, age); /* * all done */ if (ul->un_flags & LDL_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; } biodone(bp); }
/* * Set various fields of the dqblk according to the command. * Q_SETQUOTA - assign an entire dqblk structure. * Q_SETQLIM - assign a dqblk structure except for the usage. */ static int setquota(int cmd, uid_t uid, struct ufsvfs *ufsvfsp, caddr_t addr, struct cred *cr) { struct dquot *dqp; struct inode *qip; struct dquot *xdqp; struct dqblk newlim; int error; int scan_type = SQD_TYPE_NONE; daddr_t bn; int contig; if (secpolicy_fs_quota(cr, ufsvfsp->vfs_vfs) != 0) return (EPERM); rw_enter(&ufsvfsp->vfs_dqrwlock, RW_WRITER); /* * Quotas are not enabled on this file system so there is * nothing more to do. */ if ((ufsvfsp->vfs_qflags & MQ_ENABLED) == 0) { rw_exit(&ufsvfsp->vfs_dqrwlock); return (ESRCH); } /* * At this point, the quota subsystem is quiescent on this file * system so we can do all the work necessary to modify the quota * information for this user. */ if (copyin(addr, (caddr_t)&newlim, sizeof (struct dqblk)) != 0) { rw_exit(&ufsvfsp->vfs_dqrwlock); return (EFAULT); } error = getdiskquota(uid, ufsvfsp, 0, &xdqp); if (error) { rw_exit(&ufsvfsp->vfs_dqrwlock); return (error); } dqp = xdqp; /* * Don't change disk usage on Q_SETQLIM */ mutex_enter(&dqp->dq_lock); if (cmd == Q_SETQLIM) { newlim.dqb_curblocks = dqp->dq_curblocks; newlim.dqb_curfiles = dqp->dq_curfiles; } if (uid == 0) { /* * Timelimits for uid 0 set the relative time * the other users can be over quota for this file system. * If it is zero a default is used (see quota.h). */ ufsvfsp->vfs_btimelimit = newlim.dqb_btimelimit? newlim.dqb_btimelimit: DQ_BTIMELIMIT; ufsvfsp->vfs_ftimelimit = newlim.dqb_ftimelimit? newlim.dqb_ftimelimit: DQ_FTIMELIMIT; } else { if (newlim.dqb_bsoftlimit && newlim.dqb_curblocks >= newlim.dqb_bsoftlimit) { if (dqp->dq_bsoftlimit == 0 || dqp->dq_curblocks < dqp->dq_bsoftlimit) { /* If we're suddenly over the limit(s), */ /* start the timer(s) */ newlim.dqb_btimelimit = (uint32_t)gethrestime_sec() + ufsvfsp->vfs_btimelimit; dqp->dq_flags &= ~DQ_BLKS; } else { /* If we're currently over the soft */ /* limit and were previously over the */ /* soft limit then preserve the old */ /* time limit but make sure the DQ_BLKS */ /* flag is set since we must have been */ /* previously warned. */ newlim.dqb_btimelimit = dqp->dq_btimelimit; dqp->dq_flags |= DQ_BLKS; } } else { /* Either no quota or under quota, clear time limit */ newlim.dqb_btimelimit = 0; dqp->dq_flags &= ~DQ_BLKS; } if (newlim.dqb_fsoftlimit && newlim.dqb_curfiles >= newlim.dqb_fsoftlimit) { if (dqp->dq_fsoftlimit == 0 || dqp->dq_curfiles < dqp->dq_fsoftlimit) { /* If we're suddenly over the limit(s), */ /* start the timer(s) */ newlim.dqb_ftimelimit = (uint32_t)gethrestime_sec() + ufsvfsp->vfs_ftimelimit; dqp->dq_flags &= ~DQ_FILES; } else { /* If we're currently over the soft */ /* limit and were previously over the */ /* soft limit then preserve the old */ /* time limit but make sure the */ /* DQ_FILES flag is set since we must */ /* have been previously warned. */ newlim.dqb_ftimelimit = dqp->dq_ftimelimit; dqp->dq_flags |= DQ_FILES; } } else { /* Either no quota or under quota, clear time limit */ newlim.dqb_ftimelimit = 0; dqp->dq_flags &= ~DQ_FILES; } } /* * If there was previously no limit and there is now at least * one limit, then any inodes in the cache have NULL d_iquot * fields (getinoquota() returns NULL when there are no limits). */ if ((dqp->dq_fhardlimit == 0 && dqp->dq_fsoftlimit == 0 && dqp->dq_bhardlimit == 0 && dqp->dq_bsoftlimit == 0) && (newlim.dqb_fhardlimit || newlim.dqb_fsoftlimit || newlim.dqb_bhardlimit || newlim.dqb_bsoftlimit)) { scan_type = SQD_TYPE_LIMIT; } /* * If there was previously at least one limit and there is now * no limit, then any inodes in the cache have non-NULL d_iquot * fields need to be reset to NULL. */ else if ((dqp->dq_fhardlimit || dqp->dq_fsoftlimit || dqp->dq_bhardlimit || dqp->dq_bsoftlimit) && (newlim.dqb_fhardlimit == 0 && newlim.dqb_fsoftlimit == 0 && newlim.dqb_bhardlimit == 0 && newlim.dqb_bsoftlimit == 0)) { scan_type = SQD_TYPE_NO_LIMIT; } dqp->dq_dqb = newlim; dqp->dq_flags |= DQ_MOD; /* * push the new quota to disk now. If this is a trans device * then force the page out with ufs_putpage so it will be deltaed * by ufs_startio. */ qip = ufsvfsp->vfs_qinod; rw_enter(&qip->i_contents, RW_WRITER); (void) ufs_rdwri(UIO_WRITE, FWRITE | FSYNC, qip, (caddr_t)&dqp->dq_dqb, sizeof (struct dqblk), dqoff(uid), UIO_SYSSPACE, (int *)NULL, kcred); rw_exit(&qip->i_contents); (void) VOP_PUTPAGE(ITOV(qip), dqoff(dqp->dq_uid) & ~qip->i_fs->fs_bmask, qip->i_fs->fs_bsize, B_INVAL, kcred, NULL); /* * We must set the dq_mof even if not we are not logging in case * we are later remount to logging. */ contig = 0; rw_enter(&qip->i_contents, RW_WRITER); error = bmap_read(qip, dqoff(dqp->dq_uid), &bn, &contig); rw_exit(&qip->i_contents); if (error || (bn == UFS_HOLE)) { dqp->dq_mof = UFS_HOLE; } else { dqp->dq_mof = ldbtob(bn) + (offset_t)((dqoff(dqp->dq_uid)) & (DEV_BSIZE - 1)); } dqp->dq_flags &= ~DQ_MOD; dqput(dqp); mutex_exit(&dqp->dq_lock); if (scan_type) { struct setquota_data sqd; sqd.sqd_type = scan_type; sqd.sqd_ufsvfsp = ufsvfsp; sqd.sqd_uid = uid; (void) ufs_scan_inodes(0, setquota_scan_inode, &sqd, ufsvfsp); } rw_exit(&ufsvfsp->vfs_dqrwlock); return (0); }
static int md_mapbuf( ms_unit_t *un, diskaddr_t blkno, u_longlong_t bcount, buf_t *bp, /* if bp==NULL, skip bp updates */ ms_comp_t **mdc) /* if bp==NULL, skip mdc update */ { struct ms_row *mdr; struct ms_comp *mdcomp; diskaddr_t stripe_blk; diskaddr_t fragment, blk_in_row, endblk; offset_t interlace; size_t dev_index; int row_index, more; extern unsigned md_maxphys; /* Work var's when bp==NULL */ u_longlong_t wb_bcount; diskaddr_t wb_blkno; md_dev64_t wb_edev; ms_comp_t *wmdc; /* * Do a real calculation to derive the minor device of the * Virtual Disk, which in turn will let us derive the * device/minor of the underlying real device. */ for (row_index = 0; row_index < un->un_nrows; row_index++) { mdr = &un->un_row[row_index]; if (blkno < mdr->un_cum_blocks) break; } ASSERT(row_index != un->un_nrows); mdcomp = (struct ms_comp *)((void *)&((char *)un)[un->un_ocomp]); blk_in_row = blkno - mdr->un_cum_blocks + mdr->un_blocks; endblk = (diskaddr_t)(blkno + howmany(bcount, DEV_BSIZE)); if (mdr->un_ncomp == 1) { /* No striping */ if (endblk > mdr->un_cum_blocks) { wb_bcount = ldbtob(mdr->un_cum_blocks - blkno); if ((row_index + 1) == un->un_nrows) more = 0; else more = 1; } else { wb_bcount = bcount; more = 0; } wmdc = &mdcomp[mdr->un_icomp]; wb_blkno = blk_in_row; } else { /* Have striping */ interlace = mdr->un_interlace; fragment = blk_in_row % interlace; if (bcount > ldbtob(interlace - fragment)) { more = 1; wb_bcount = ldbtob(interlace - fragment); } else { more = 0; wb_bcount = bcount; } stripe_blk = blk_in_row / interlace; dev_index = (size_t)(stripe_blk % mdr->un_ncomp); wmdc = &mdcomp[mdr->un_icomp + dev_index]; wb_blkno = (diskaddr_t)(((stripe_blk / mdr->un_ncomp) * interlace) + fragment); } wb_blkno += wmdc->un_start_block; wb_edev = wmdc->un_dev; /* only break up the I/O if we're not built on another metadevice */ if ((md_getmajor(wb_edev) != md_major) && (wb_bcount > md_maxphys)) { wb_bcount = md_maxphys; more = 1; } if (bp != (buf_t *)NULL) { /* * wb_bcount is limited by md_maxphys which is 'int' */ bp->b_bcount = (size_t)wb_bcount; bp->b_lblkno = wb_blkno; bp->b_edev = md_dev64_to_dev(wb_edev); *mdc = wmdc; } return (more); }