version 1.102.4.3, 2011/02/17 10:37:55 |
version 1.102.4.4, 2011/02/17 12:00:52 |
Line 115 static int snapblkaddr(struct vnode *, d |
|
Line 115 static int snapblkaddr(struct vnode *, d |
|
static int rwfsblk(struct vnode *, int, void *, daddr_t); |
static int rwfsblk(struct vnode *, int, void *, daddr_t); |
static int syncsnap(struct vnode *); |
static int syncsnap(struct vnode *); |
static int wrsnapblk(struct vnode *, void *, daddr_t); |
static int wrsnapblk(struct vnode *, void *, daddr_t); |
|
static int blocks_in_journal(struct fs *); |
|
|
static inline bool is_active_snapshot(struct snap_info *, struct inode *); |
static inline bool is_active_snapshot(struct snap_info *, struct inode *); |
static inline daddr_t db_get(struct inode *, int); |
static inline daddr_t db_get(struct inode *, int); |
|
|
static int |
static int |
snapshot_setup(struct mount *mp, struct vnode *vp) |
snapshot_setup(struct mount *mp, struct vnode *vp) |
{ |
{ |
int error, i, len, loc; |
int error, n, len, loc; |
daddr_t blkno, numblks; |
daddr_t blkno, numblks; |
struct buf *ibp, *nbp; |
struct buf *ibp, *nbp; |
struct fs *fs = VFSTOUFS(mp)->um_fs; |
struct fs *fs = VFSTOUFS(mp)->um_fs; |
struct lwp *l = curlwp; |
struct lwp *l = curlwp; |
|
const int wbreak = blocks_in_journal(fs)/8; |
|
|
/* |
/* |
* Check mount, exclusive reference and owner. |
* Check mount, exclusive reference and owner. |
Line 460 snapshot_setup(struct mount *mp, struct |
|
Line 462 snapshot_setup(struct mount *mp, struct |
|
error = UFS_WAPBL_BEGIN(mp); |
error = UFS_WAPBL_BEGIN(mp); |
if (error) |
if (error) |
return error; |
return error; |
for (blkno = NDADDR, i = 0; blkno < numblks; blkno += NINDIR(fs)) { |
for (blkno = NDADDR, n = 0; blkno < numblks; blkno += NINDIR(fs)) { |
error = ffs_balloc(vp, lblktosize(fs, (off_t)blkno), |
error = ffs_balloc(vp, lblktosize(fs, (off_t)blkno), |
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); |
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); |
if (error) |
if (error) |
goto out; |
goto out; |
brelse(ibp, 0); |
brelse(ibp, 0); |
if ((++i % 16) == 0) { |
if (wbreak > 0 && (++n % wbreak) == 0) { |
UFS_WAPBL_END(mp); |
UFS_WAPBL_END(mp); |
error = UFS_WAPBL_BEGIN(mp); |
error = UFS_WAPBL_BEGIN(mp); |
if (error) |
if (error) |
|
|
snapshot_expunge(struct mount *mp, struct vnode *vp, struct fs *copy_fs, |
snapshot_expunge(struct mount *mp, struct vnode *vp, struct fs *copy_fs, |
daddr_t *snaplistsize, daddr_t **snaplist) |
daddr_t *snaplistsize, daddr_t **snaplist) |
{ |
{ |
bool has_wapbl = false; |
|
int cg, error, len, loc; |
int cg, error, len, loc; |
daddr_t blkno, *blkp; |
daddr_t blkno, *blkp; |
struct fs *fs = VFSTOUFS(mp)->um_fs; |
struct fs *fs = VFSTOUFS(mp)->um_fs; |
Line 601 snapshot_expunge(struct mount *mp, struc |
|
Line 602 snapshot_expunge(struct mount *mp, struc |
|
*/ |
*/ |
*snaplistsize = fs->fs_ncg + howmany(fs->fs_cssize, fs->fs_bsize) + |
*snaplistsize = fs->fs_ncg + howmany(fs->fs_cssize, fs->fs_bsize) + |
FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */; |
FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */; |
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
goto out; |
|
has_wapbl = true; |
|
mutex_enter(&mntvnode_lock); |
mutex_enter(&mntvnode_lock); |
/* |
/* |
* NOTE: not using the TAILQ_FOREACH here since in this loop vgone() |
* NOTE: not using the TAILQ_FOREACH here since in this loop vgone() |
Line 656 snapshot_expunge(struct mount *mp, struc |
|
Line 653 snapshot_expunge(struct mount *mp, struc |
|
if (loc < NDADDR) { |
if (loc < NDADDR) { |
len = fragroundup(fs, blkoff(fs, xp->i_size)); |
len = fragroundup(fs, blkoff(fs, xp->i_size)); |
if (len > 0 && len < fs->fs_bsize) { |
if (len > 0 && len < fs->fs_bsize) { |
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) { |
|
(void)vunmark(mvp); |
|
goto out; |
|
} |
ffs_blkfree_snap(copy_fs, vp, db_get(xp, loc), |
ffs_blkfree_snap(copy_fs, vp, db_get(xp, loc), |
len, xp->i_number); |
len, xp->i_number); |
blkno = db_get(xp, loc); |
blkno = db_get(xp, loc); |
db_assign(xp, loc, 0); |
db_assign(xp, loc, 0); |
|
UFS_WAPBL_END(mp); |
} |
} |
} |
} |
*snaplistsize += 1; |
*snaplistsize += 1; |
error = expunge(vp, xp, copy_fs, fullacct, BLK_NOCOPY); |
error = expunge(vp, xp, copy_fs, fullacct, BLK_NOCOPY); |
if (blkno) |
if (blkno) |
db_assign(xp, loc, blkno); |
db_assign(xp, loc, blkno); |
if (!error) |
if (!error) { |
error = ffs_freefile_snap(copy_fs, vp, xp->i_number, |
error = UFS_WAPBL_BEGIN(mp); |
xp->i_mode); |
if (!error) { |
|
error = ffs_freefile_snap(copy_fs, vp, |
|
xp->i_number, xp->i_mode); |
|
UFS_WAPBL_END(mp); |
|
} |
|
} |
if (error) { |
if (error) { |
(void)vunmark(mvp); |
(void)vunmark(mvp); |
goto out; |
goto out; |
Line 696 snapshot_expunge(struct mount *mp, struc |
|
Line 704 snapshot_expunge(struct mount *mp, struc |
|
(*snaplist)[0] = blkp - &(*snaplist)[0]; |
(*snaplist)[0] = blkp - &(*snaplist)[0]; |
|
|
out: |
out: |
if (has_wapbl) |
|
UFS_WAPBL_END(mp); |
|
if (mvp != NULL) |
if (mvp != NULL) |
vnfree(mvp); |
vnfree(mvp); |
if (logvp != NULL) |
if (logvp != NULL) |
|
|
snapshot_expunge_snap(struct mount *mp, struct vnode *vp, |
snapshot_expunge_snap(struct mount *mp, struct vnode *vp, |
struct fs *copy_fs, daddr_t snaplistsize) |
struct fs *copy_fs, daddr_t snaplistsize) |
{ |
{ |
int error, i; |
int error = 0, i; |
daddr_t numblks, *snaplist = NULL; |
daddr_t numblks, *snaplist = NULL; |
struct fs *fs = VFSTOUFS(mp)->um_fs; |
struct fs *fs = VFSTOUFS(mp)->um_fs; |
struct inode *ip = VTOI(vp), *xp; |
struct inode *ip = VTOI(vp), *xp; |
struct lwp *l = curlwp; |
struct lwp *l = curlwp; |
struct snap_info *si = VFSTOUFS(mp)->um_snapinfo; |
struct snap_info *si = VFSTOUFS(mp)->um_snapinfo; |
|
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
return error; |
|
TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap) { |
TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap) { |
if (xp == ip) |
if (xp == ip) |
break; |
break; |
Line 737 snapshot_expunge_snap(struct mount *mp, |
|
Line 740 snapshot_expunge_snap(struct mount *mp, |
|
break; |
break; |
if (xp->i_nlink != 0) |
if (xp->i_nlink != 0) |
continue; |
continue; |
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
break; |
error = ffs_freefile_snap(copy_fs, vp, xp->i_number, xp->i_mode); |
error = ffs_freefile_snap(copy_fs, vp, xp->i_number, xp->i_mode); |
|
UFS_WAPBL_END(mp); |
if (error) |
if (error) |
break; |
break; |
} |
} |
Line 769 snapshot_expunge_snap(struct mount *mp, |
|
Line 776 snapshot_expunge_snap(struct mount *mp, |
|
snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs)); |
snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs)); |
error = vn_rdwr(UIO_WRITE, vp, (void *)snaplist, |
error = vn_rdwr(UIO_WRITE, vp, (void *)snaplist, |
snaplistsize * sizeof(daddr_t), lblktosize(fs, (off_t)numblks), |
snaplistsize * sizeof(daddr_t), lblktosize(fs, (off_t)numblks), |
UIO_SYSSPACE, IO_NODELOCKED | IO_JOURNALLOCKED | IO_UNIT, |
UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, l->l_cred, NULL, NULL); |
l->l_cred, NULL, NULL); |
|
for (i = 0; i < snaplistsize; i++) |
for (i = 0; i < snaplistsize; i++) |
snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs)); |
snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs)); |
out: |
out: |
UFS_WAPBL_END(mp); |
|
if (error && snaplist != NULL) { |
if (error && snaplist != NULL) { |
free(snaplist, M_UFSMNT); |
free(snaplist, M_UFSMNT); |
ip->i_snapblklist = NULL; |
ip->i_snapblklist = NULL; |
|
|
static int |
static int |
cgaccount(struct vnode *vp, int passno, int *redo) |
cgaccount(struct vnode *vp, int passno, int *redo) |
{ |
{ |
int cg, error; |
int cg, error = 0; |
struct buf *nbp; |
struct buf *nbp; |
struct fs *fs = VTOI(vp)->i_fs; |
struct fs *fs = VTOI(vp)->i_fs; |
|
|
error = UFS_WAPBL_BEGIN(vp->v_mount); |
|
if (error) |
|
return error; |
|
if (redo != NULL) |
if (redo != NULL) |
*redo = 0; |
*redo = 0; |
if (passno == 1) |
if (passno == 1) |
Line 882 cgaccount(struct vnode *vp, int passno, |
|
Line 884 cgaccount(struct vnode *vp, int passno, |
|
for (cg = 0; cg < fs->fs_ncg; cg++) { |
for (cg = 0; cg < fs->fs_ncg; cg++) { |
if (passno == 2 && ACTIVECG_ISSET(fs, cg)) |
if (passno == 2 && ACTIVECG_ISSET(fs, cg)) |
continue; |
continue; |
|
|
if (redo != NULL) |
if (redo != NULL) |
*redo += 1; |
*redo += 1; |
|
error = UFS_WAPBL_BEGIN(vp->v_mount); |
|
if (error) |
|
return error; |
error = ffs_balloc(vp, lfragtosize(fs, cgtod(fs, cg)), |
error = ffs_balloc(vp, lfragtosize(fs, cgtod(fs, cg)), |
fs->fs_bsize, curlwp->l_cred, 0, &nbp); |
fs->fs_bsize, curlwp->l_cred, 0, &nbp); |
if (error) |
if (error) { |
|
UFS_WAPBL_END(vp->v_mount); |
break; |
break; |
|
} |
error = cgaccount1(cg, vp, nbp->b_data, passno); |
error = cgaccount1(cg, vp, nbp->b_data, passno); |
bawrite(nbp); |
bawrite(nbp); |
|
UFS_WAPBL_END(vp->v_mount); |
if (error) |
if (error) |
break; |
break; |
} |
} |
UFS_WAPBL_END(vp->v_mount); |
|
return error; |
return error; |
} |
} |
|
|
Line 1000 expunge(struct vnode *snapvp, struct ino |
|
Line 1008 expunge(struct vnode *snapvp, struct ino |
|
struct lwp *l = curlwp; |
struct lwp *l = curlwp; |
void *bap; |
void *bap; |
struct buf *bp; |
struct buf *bp; |
|
struct mount *mp; |
|
|
ns = UFS_FSNEEDSWAP(fs); |
ns = UFS_FSNEEDSWAP(fs); |
|
mp = snapvp->v_mount; |
|
|
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
return error; |
/* |
/* |
* Prepare to expunge the inode. If its inode block has not |
* Prepare to expunge the inode. If its inode block has not |
* yet been copied, then allocate and fill the copy. |
* yet been copied, then allocate and fill the copy. |
Line 1019 expunge(struct vnode *snapvp, struct ino |
|
Line 1033 expunge(struct vnode *snapvp, struct ino |
|
if (! error) |
if (! error) |
error = rwfsblk(snapvp, B_READ, bp->b_data, lbn); |
error = rwfsblk(snapvp, B_READ, bp->b_data, lbn); |
} |
} |
if (error) |
if (error) { |
|
UFS_WAPBL_END(mp); |
return error; |
return error; |
|
} |
/* |
/* |
* Set a snapshot inode to be a zero length file, regular files |
* Set a snapshot inode to be a zero length file, regular files |
* or unlinked snapshots to be completely unallocated. |
* or unlinked snapshots to be completely unallocated. |
Line 1048 expunge(struct vnode *snapvp, struct ino |
|
Line 1064 expunge(struct vnode *snapvp, struct ino |
|
memset(&dip2->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int64_t)); |
memset(&dip2->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int64_t)); |
} |
} |
bdwrite(bp); |
bdwrite(bp); |
|
UFS_WAPBL_END(mp); |
/* |
/* |
* Now go through and expunge all the blocks in the file |
* Now go through and expunge all the blocks in the file |
* using the function requested. |
* using the function requested. |
Line 1057 expunge(struct vnode *snapvp, struct ino |
|
Line 1074 expunge(struct vnode *snapvp, struct ino |
|
bap = &cancelip->i_ffs1_db[0]; |
bap = &cancelip->i_ffs1_db[0]; |
else |
else |
bap = &cancelip->i_ffs2_db[0]; |
bap = &cancelip->i_ffs2_db[0]; |
if ((error = (*acctfunc)(snapvp, bap, 0, NDADDR, fs, 0, expungetype))) |
error = (*acctfunc)(snapvp, bap, 0, NDADDR, fs, 0, expungetype); |
|
if (error) |
return (error); |
return (error); |
if (fs->fs_magic == FS_UFS1_MAGIC) |
if (fs->fs_magic == FS_UFS1_MAGIC) |
bap = &cancelip->i_ffs1_ib[0]; |
bap = &cancelip->i_ffs1_ib[0]; |
else |
else |
bap = &cancelip->i_ffs2_ib[0]; |
bap = &cancelip->i_ffs2_ib[0]; |
if ((error = (*acctfunc)(snapvp, bap, 0, NIADDR, fs, -1, expungetype))) |
error = (*acctfunc)(snapvp, bap, 0, NIADDR, fs, -1, expungetype); |
|
if (error) |
return (error); |
return (error); |
blksperindir = 1; |
blksperindir = 1; |
lbn = -NDADDR; |
lbn = -NDADDR; |
Line 1179 snapacct(struct vnode *vp, void *bap, in |
|
Line 1198 snapacct(struct vnode *vp, void *bap, in |
|
{ |
{ |
struct inode *ip = VTOI(vp); |
struct inode *ip = VTOI(vp); |
struct lwp *l = curlwp; |
struct lwp *l = curlwp; |
|
struct mount *mp = vp->v_mount; |
daddr_t blkno; |
daddr_t blkno; |
daddr_t lbn; |
daddr_t lbn; |
struct buf *ibp; |
struct buf *ibp; |
int error; |
int error, n; |
|
const int wbreak = blocks_in_journal(VFSTOUFS(mp)->um_fs)/8; |
|
|
for ( ; oldblkp < lastblkp; oldblkp++) { |
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
return error; |
|
for ( n = 0; oldblkp < lastblkp; oldblkp++) { |
blkno = idb_get(ip, bap, oldblkp); |
blkno = idb_get(ip, bap, oldblkp); |
if (blkno == 0 || blkno == BLK_NOCOPY || blkno == BLK_SNAP) |
if (blkno == 0 || blkno == BLK_NOCOPY || blkno == BLK_SNAP) |
continue; |
continue; |
Line 1196 snapacct(struct vnode *vp, void *bap, in |
|
Line 1220 snapacct(struct vnode *vp, void *bap, in |
|
error = ffs_balloc(vp, lblktosize(fs, (off_t)lbn), |
error = ffs_balloc(vp, lblktosize(fs, (off_t)lbn), |
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); |
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); |
if (error) |
if (error) |
return (error); |
break; |
blkno = idb_get(ip, ibp->b_data, |
blkno = idb_get(ip, ibp->b_data, |
(lbn - NDADDR) % NINDIR(fs)); |
(lbn - NDADDR) % NINDIR(fs)); |
} |
} |
Line 1220 snapacct(struct vnode *vp, void *bap, in |
|
Line 1244 snapacct(struct vnode *vp, void *bap, in |
|
bdwrite(ibp); |
bdwrite(ibp); |
} |
} |
} |
} |
|
if (wbreak > 0 && (++n % wbreak) == 0) { |
|
UFS_WAPBL_END(mp); |
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
return error; |
|
} |
} |
} |
return (0); |
UFS_WAPBL_END(mp); |
|
return error; |
} |
} |
|
|
/* |
/* |
Line 1233 mapacct(struct vnode *vp, void *bap, int |
|
Line 1264 mapacct(struct vnode *vp, void *bap, int |
|
{ |
{ |
daddr_t blkno; |
daddr_t blkno; |
struct inode *ip; |
struct inode *ip; |
|
struct mount *mp = vp->v_mount; |
ino_t inum; |
ino_t inum; |
int acctit; |
int acctit, error, n; |
|
const int wbreak = blocks_in_journal(VFSTOUFS(mp)->um_fs)/8; |
|
|
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
return error; |
ip = VTOI(vp); |
ip = VTOI(vp); |
inum = ip->i_number; |
inum = ip->i_number; |
if (lblkno == -1) |
if (lblkno == -1) |
acctit = 0; |
acctit = 0; |
else |
else |
acctit = 1; |
acctit = 1; |
for ( ; oldblkp < lastblkp; oldblkp++, lblkno++) { |
for ( n = 0; oldblkp < lastblkp; oldblkp++, lblkno++) { |
blkno = idb_get(ip, bap, oldblkp); |
blkno = idb_get(ip, bap, oldblkp); |
if (blkno == 0 || blkno == BLK_NOCOPY) |
if (blkno == 0 || blkno == BLK_NOCOPY) |
continue; |
continue; |
Line 1251 mapacct(struct vnode *vp, void *bap, int |
|
Line 1287 mapacct(struct vnode *vp, void *bap, int |
|
if (blkno == BLK_SNAP) |
if (blkno == BLK_SNAP) |
blkno = blkstofrags(fs, lblkno); |
blkno = blkstofrags(fs, lblkno); |
ffs_blkfree_snap(fs, vp, blkno, fs->fs_bsize, inum); |
ffs_blkfree_snap(fs, vp, blkno, fs->fs_bsize, inum); |
|
if (wbreak > 0 && (++n % wbreak) == 0) { |
|
UFS_WAPBL_END(mp); |
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
return error; |
|
} |
} |
} |
|
UFS_WAPBL_END(mp); |
return (0); |
return (0); |
} |
} |
#endif /* defined(FFS_NO_SNAPSHOT) */ |
#endif /* defined(FFS_NO_SNAPSHOT) */ |
Line 1318 ffs_snapremove(struct vnode *vp) |
|
Line 1361 ffs_snapremove(struct vnode *vp) |
|
struct snap_info *si; |
struct snap_info *si; |
struct lwp *l = curlwp; |
struct lwp *l = curlwp; |
daddr_t numblks, blkno, dblk; |
daddr_t numblks, blkno, dblk; |
int error, loc, last; |
int error, loc, last, n; |
|
const int wbreak = blocks_in_journal(fs)/8; |
|
|
si = VFSTOUFS(mp)->um_snapinfo; |
si = VFSTOUFS(mp)->um_snapinfo; |
/* |
/* |
Line 1366 ffs_snapremove(struct vnode *vp) |
|
Line 1410 ffs_snapremove(struct vnode *vp) |
|
} |
} |
} |
} |
numblks = howmany(ip->i_size, fs->fs_bsize); |
numblks = howmany(ip->i_size, fs->fs_bsize); |
for (blkno = NDADDR; blkno < numblks; blkno += NINDIR(fs)) { |
for (blkno = NDADDR, n = 0; blkno < numblks; blkno += NINDIR(fs)) { |
error = ffs_balloc(vp, lblktosize(fs, (off_t)blkno), |
error = ffs_balloc(vp, lblktosize(fs, (off_t)blkno), |
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); |
fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); |
if (error) |
if (error) |
Line 1376 ffs_snapremove(struct vnode *vp) |
|
Line 1420 ffs_snapremove(struct vnode *vp) |
|
else |
else |
last = fs->fs_size - blkno; |
last = fs->fs_size - blkno; |
for (loc = 0; loc < last; loc++) { |
for (loc = 0; loc < last; loc++) { |
|
if (wbreak > 0 && (++n % wbreak) == 0) { |
|
UFS_WAPBL_END(mp); |
|
error = UFS_WAPBL_BEGIN(mp); |
|
if (error) |
|
panic("UFS_WAPBL_BEGIN failed"); |
|
} |
dblk = idb_get(ip, ibp->b_data, loc); |
dblk = idb_get(ip, ibp->b_data, loc); |
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP) |
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP) |
idb_assign(ip, ibp->b_data, loc, 0); |
idb_assign(ip, ibp->b_data, loc, 0); |
Line 2154 is_active_snapshot(struct snap_info *si, |
|
Line 2204 is_active_snapshot(struct snap_info *si, |
|
} |
} |
|
|
/* |
/* |
|
* Number of blocks that fit into the journal or zero if not logging. |
|
*/ |
|
static int |
|
blocks_in_journal(struct fs *fs) |
|
{ |
|
off_t bpj; |
|
|
|
if ((fs->fs_flags & FS_DOWAPBL) == 0) |
|
return 0; |
|
bpj = 1; |
|
if (fs->fs_journal_version == UFS_WAPBL_VERSION) { |
|
switch (fs->fs_journal_location) { |
|
case UFS_WAPBL_JOURNALLOC_END_PARTITION: |
|
bpj = (off_t)fs->fs_journallocs[UFS_WAPBL_EPART_BLKSZ]* |
|
fs->fs_journallocs[UFS_WAPBL_EPART_COUNT]; |
|
break; |
|
case UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM: |
|
bpj = (off_t)fs->fs_journallocs[UFS_WAPBL_INFS_BLKSZ]* |
|
fs->fs_journallocs[UFS_WAPBL_INFS_COUNT]; |
|
break; |
|
} |
|
} |
|
bpj /= fs->fs_bsize; |
|
return (bpj > 0 ? bpj : 1); |
|
} |
|
|
|
/* |
* Get/Put direct block from inode or buffer containing disk addresses. Take |
* Get/Put direct block from inode or buffer containing disk addresses. Take |
* care for fs type (UFS1/UFS2) and byte swapping. These functions should go |
* care for fs type (UFS1/UFS2) and byte swapping. These functions should go |
* into a global include. |
* into a global include. |