version 1.129, 2011/09/20 14:01:32 |
version 1.129.2.4, 2014/05/22 11:41:18 |
Line 81 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 81 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/buf.h> |
#include <sys/buf.h> |
|
#include <sys/cprng.h> |
#include <sys/fstrans.h> |
#include <sys/fstrans.h> |
#include <sys/kauth.h> |
#include <sys/kauth.h> |
#include <sys/kernel.h> |
#include <sys/kernel.h> |
|
|
ffs_check_bad_allocation(const char *func, struct fs *fs, daddr_t bno, |
ffs_check_bad_allocation(const char *func, struct fs *fs, daddr_t bno, |
long size, dev_t dev, ino_t inum) |
long size, dev_t dev, ino_t inum) |
{ |
{ |
if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0 || |
if ((u_int)size > fs->fs_bsize || ffs_fragoff(fs, size) != 0 || |
fragnum(fs, bno) + numfrags(fs, size) > fs->fs_frag) { |
ffs_fragnum(fs, bno) + ffs_numfrags(fs, size) > fs->fs_frag) { |
printf("dev = 0x%llx, bno = %" PRId64 " bsize = %d, " |
printf("dev = 0x%llx, bno = %" PRId64 " bsize = %d, " |
"size = %ld, fs = %s\n", |
"size = %ld, fs = %s\n", |
(long long)dev, bno, fs->fs_bsize, size, fs->fs_fsmnt); |
(long long)dev, bno, fs->fs_bsize, size, fs->fs_fsmnt); |
Line 204 ffs_alloc(struct inode *ip, daddr_t lbn, |
|
Line 205 ffs_alloc(struct inode *ip, daddr_t lbn, |
|
*/ |
*/ |
|
|
if (ITOV(ip)->v_type == VREG && |
if (ITOV(ip)->v_type == VREG && |
lblktosize(fs, (voff_t)lbn) < round_page(ITOV(ip)->v_size)) { |
ffs_lblktosize(fs, (voff_t)lbn) < round_page(ITOV(ip)->v_size)) { |
struct vm_page *pg; |
struct vm_page *pg; |
struct vnode *vp = ITOV(ip); |
struct vnode *vp = ITOV(ip); |
struct uvm_object *uobj = &vp->v_uobj; |
struct uvm_object *uobj = &vp->v_uobj; |
voff_t off = trunc_page(lblktosize(fs, lbn)); |
voff_t off = trunc_page(ffs_lblktosize(fs, lbn)); |
voff_t endoff = round_page(lblktosize(fs, lbn) + size); |
voff_t endoff = round_page(ffs_lblktosize(fs, lbn) + size); |
|
|
mutex_enter(uobj->vmobjlock); |
mutex_enter(uobj->vmobjlock); |
while (off < endoff) { |
while (off < endoff) { |
pg = uvm_pagelookup(uobj, off); |
pg = uvm_pagelookup(uobj, off); |
KASSERT((pg == NULL && (vp->v_vflag & VV_MAPPED) == 0 && |
KASSERT((pg == NULL && (vp->v_vflag & VV_MAPPED) == 0 && |
(size & PAGE_MASK) == 0 && |
(size & PAGE_MASK) == 0 && |
blkoff(fs, size) == 0) || |
ffs_blkoff(fs, size) == 0) || |
(pg != NULL && pg->owner == curproc->p_pid && |
(pg != NULL && pg->owner == curproc->p_pid && |
pg->lowner == curlwp->l_lid)); |
pg->lowner == curlwp->l_lid)); |
off += PAGE_SIZE; |
off += PAGE_SIZE; |
Line 227 ffs_alloc(struct inode *ip, daddr_t lbn, |
|
Line 228 ffs_alloc(struct inode *ip, daddr_t lbn, |
|
|
|
*bnp = 0; |
*bnp = 0; |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) { |
if ((u_int)size > fs->fs_bsize || ffs_fragoff(fs, size) != 0) { |
printf("dev = 0x%llx, bsize = %d, size = %d, fs = %s\n", |
printf("dev = 0x%llx, bsize = %d, size = %d, fs = %s\n", |
(unsigned long long)ip->i_dev, fs->fs_bsize, size, |
(unsigned long long)ip->i_dev, fs->fs_bsize, size, |
fs->fs_fsmnt); |
fs->fs_fsmnt); |
Line 331 ffs_realloccg(struct inode *ip, daddr_t |
|
Line 332 ffs_realloccg(struct inode *ip, daddr_t |
|
if (ITOV(ip)->v_type == VREG) { |
if (ITOV(ip)->v_type == VREG) { |
struct vm_page *pg; |
struct vm_page *pg; |
struct uvm_object *uobj = &ITOV(ip)->v_uobj; |
struct uvm_object *uobj = &ITOV(ip)->v_uobj; |
voff_t off = trunc_page(lblktosize(fs, lbprev)); |
voff_t off = trunc_page(ffs_lblktosize(fs, lbprev)); |
voff_t endoff = round_page(lblktosize(fs, lbprev) + osize); |
voff_t endoff = round_page(ffs_lblktosize(fs, lbprev) + osize); |
|
|
mutex_enter(uobj->vmobjlock); |
mutex_enter(uobj->vmobjlock); |
while (off < endoff) { |
while (off < endoff) { |
Line 346 ffs_realloccg(struct inode *ip, daddr_t |
|
Line 347 ffs_realloccg(struct inode *ip, daddr_t |
|
#endif |
#endif |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if ((u_int)osize > fs->fs_bsize || fragoff(fs, osize) != 0 || |
if ((u_int)osize > fs->fs_bsize || ffs_fragoff(fs, osize) != 0 || |
(u_int)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) { |
(u_int)nsize > fs->fs_bsize || ffs_fragoff(fs, nsize) != 0) { |
printf( |
printf( |
"dev = 0x%llx, bsize = %d, osize = %d, nsize = %d, fs = %s\n", |
"dev = 0x%llx, bsize = %d, osize = %d, nsize = %d, fs = %s\n", |
(unsigned long long)ip->i_dev, fs->fs_bsize, osize, nsize, |
(unsigned long long)ip->i_dev, fs->fs_bsize, osize, nsize, |
Line 381 ffs_realloccg(struct inode *ip, daddr_t |
|
Line 382 ffs_realloccg(struct inode *ip, daddr_t |
|
*/ |
*/ |
if (bpp != NULL && |
if (bpp != NULL && |
(error = bread(ITOV(ip), lbprev, osize, NOCRED, 0, &bp)) != 0) { |
(error = bread(ITOV(ip), lbprev, osize, NOCRED, 0, &bp)) != 0) { |
brelse(bp, 0); |
|
return (error); |
return (error); |
} |
} |
#if defined(QUOTA) || defined(QUOTA2) |
#if defined(QUOTA) || defined(QUOTA2) |
Line 402 ffs_realloccg(struct inode *ip, daddr_t |
|
Line 402 ffs_realloccg(struct inode *ip, daddr_t |
|
ip->i_flag |= IN_CHANGE | IN_UPDATE; |
ip->i_flag |= IN_CHANGE | IN_UPDATE; |
|
|
if (bpp != NULL) { |
if (bpp != NULL) { |
if (bp->b_blkno != fsbtodb(fs, bno)) |
if (bp->b_blkno != FFS_FSBTODB(fs, bno)) |
panic("bad blockno"); |
panic("bad blockno"); |
allocbuf(bp, nsize, 1); |
allocbuf(bp, nsize, 1); |
memset((char *)bp->b_data + osize, 0, nsize - osize); |
memset((char *)bp->b_data + osize, 0, nsize - osize); |
Line 480 ffs_realloccg(struct inode *ip, daddr_t |
|
Line 480 ffs_realloccg(struct inode *ip, daddr_t |
|
if ((ip->i_ump->um_mountp->mnt_wapbl) && |
if ((ip->i_ump->um_mountp->mnt_wapbl) && |
(ITOV(ip)->v_type != VREG)) { |
(ITOV(ip)->v_type != VREG)) { |
UFS_WAPBL_REGISTER_DEALLOCATION( |
UFS_WAPBL_REGISTER_DEALLOCATION( |
ip->i_ump->um_mountp, fsbtodb(fs, bprev), |
ip->i_ump->um_mountp, FFS_FSBTODB(fs, bprev), |
osize); |
osize); |
} else { |
} else { |
ffs_blkfree(fs, ip->i_devvp, bprev, (long)osize, |
ffs_blkfree(fs, ip->i_devvp, bprev, (long)osize, |
Line 491 ffs_realloccg(struct inode *ip, daddr_t |
|
Line 491 ffs_realloccg(struct inode *ip, daddr_t |
|
(ITOV(ip)->v_type != VREG)) { |
(ITOV(ip)->v_type != VREG)) { |
UFS_WAPBL_REGISTER_DEALLOCATION( |
UFS_WAPBL_REGISTER_DEALLOCATION( |
ip->i_ump->um_mountp, |
ip->i_ump->um_mountp, |
fsbtodb(fs, (bno + numfrags(fs, nsize))), |
FFS_FSBTODB(fs, (bno + ffs_numfrags(fs, nsize))), |
request - nsize); |
request - nsize); |
} else |
} else |
ffs_blkfree(fs, ip->i_devvp, |
ffs_blkfree(fs, ip->i_devvp, |
bno + numfrags(fs, nsize), |
bno + ffs_numfrags(fs, nsize), |
(long)(request - nsize), ip->i_number); |
(long)(request - nsize), ip->i_number); |
} |
} |
DIP_ADD(ip, blocks, btodb(nsize - osize)); |
DIP_ADD(ip, blocks, btodb(nsize - osize)); |
ip->i_flag |= IN_CHANGE | IN_UPDATE; |
ip->i_flag |= IN_CHANGE | IN_UPDATE; |
if (bpp != NULL) { |
if (bpp != NULL) { |
bp->b_blkno = fsbtodb(fs, bno); |
bp->b_blkno = FFS_FSBTODB(fs, bno); |
allocbuf(bp, nsize, 1); |
allocbuf(bp, nsize, 1); |
memset((char *)bp->b_data + osize, 0, (u_int)nsize - osize); |
memset((char *)bp->b_data + osize, 0, (u_int)nsize - osize); |
mutex_enter(bp->b_objlock); |
mutex_enter(bp->b_objlock); |
Line 627 ffs_valloc(struct vnode *pvp, int mode, |
|
Line 627 ffs_valloc(struct vnode *pvp, int mode, |
|
printf("ino %llu ipref %llu\n", (unsigned long long)ino, |
printf("ino %llu ipref %llu\n", (unsigned long long)ino, |
(unsigned long long)ipref); |
(unsigned long long)ipref); |
#if 0 |
#if 0 |
error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), |
error = bread(ump->um_devvp, FFS_FSBTODB(fs, ino_to_fsba(fs, ino)), |
(int)fs->fs_bsize, NOCRED, 0, &bp); |
(int)fs->fs_bsize, NOCRED, 0, &bp); |
#endif |
#endif |
|
|
Line 635 ffs_valloc(struct vnode *pvp, int mode, |
|
Line 635 ffs_valloc(struct vnode *pvp, int mode, |
|
panic("ffs_valloc: dup alloc"); |
panic("ffs_valloc: dup alloc"); |
} |
} |
if (DIP(ip, blocks)) { /* XXX */ |
if (DIP(ip, blocks)) { /* XXX */ |
printf("free inode %s/%llu had %" PRId64 " blocks\n", |
printf("free inode %llu on %s had %" PRId64 " blocks\n", |
fs->fs_fsmnt, (unsigned long long)ino, DIP(ip, blocks)); |
(unsigned long long)ino, fs->fs_fsmnt, DIP(ip, blocks)); |
DIP_ASSIGN(ip, blocks, 0); |
DIP_ASSIGN(ip, blocks, 0); |
} |
} |
ip->i_flag &= ~IN_SPACECOUNTED; |
ip->i_flag &= ~IN_SPACECOUNTED; |
Line 720 ffs_dirpref(struct inode *pip) |
|
Line 720 ffs_dirpref(struct inode *pip) |
|
/* |
/* |
* Count various limits which used for |
* Count various limits which used for |
* optimal allocation of a directory inode. |
* optimal allocation of a directory inode. |
|
* Try cylinder groups with >75% avgifree and avgbfree. |
|
* Avoid cylinder groups with no free blocks or inodes as that |
|
* triggers an I/O-expensive cylinder group scan. |
*/ |
*/ |
maxndir = min(avgndir + fs->fs_ipg / 16, fs->fs_ipg); |
maxndir = min(avgndir + fs->fs_ipg / 16, fs->fs_ipg); |
minifree = avgifree - fs->fs_ipg / 4; |
minifree = avgifree - avgifree / 4; |
if (minifree < 0) |
if (minifree < 1) |
minifree = 0; |
minifree = 1; |
minbfree = avgbfree - fragstoblks(fs, fs->fs_fpg) / 4; |
minbfree = avgbfree - avgbfree / 4; |
if (minbfree < 0) |
if (minbfree < 1) |
minbfree = 0; |
minbfree = 1; |
cgsize = (int64_t)fs->fs_fsize * fs->fs_fpg; |
cgsize = (int64_t)fs->fs_fsize * fs->fs_fpg; |
dirsize = (int64_t)fs->fs_avgfilesize * fs->fs_avgfpdir; |
dirsize = (int64_t)fs->fs_avgfilesize * fs->fs_avgfpdir; |
if (avgndir != 0) { |
if (avgndir != 0) { |
Line 736 ffs_dirpref(struct inode *pip) |
|
Line 739 ffs_dirpref(struct inode *pip) |
|
dirsize = curdsz; |
dirsize = curdsz; |
} |
} |
if (cgsize < dirsize * 255) |
if (cgsize < dirsize * 255) |
maxcontigdirs = cgsize / dirsize; |
maxcontigdirs = (avgbfree * fs->fs_bsize) / dirsize; |
else |
else |
maxcontigdirs = 255; |
maxcontigdirs = 255; |
if (fs->fs_avgfpdir > 0) |
if (fs->fs_avgfpdir > 0) |
Line 831 ffs_blkpref_ufs1(struct inode *ip, daddr |
|
Line 834 ffs_blkpref_ufs1(struct inode *ip, daddr |
|
if (flags & B_METAONLY) |
if (flags & B_METAONLY) |
return ip->i_ffs_first_indir_blk; |
return ip->i_ffs_first_indir_blk; |
else |
else |
return ip->i_ffs_first_data_blk + blkstofrags(fs, lbn); |
return ip->i_ffs_first_data_blk + ffs_blkstofrags(fs, lbn); |
} |
} |
|
|
if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) { |
if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) { |
if (lbn < NDADDR + NINDIR(fs)) { |
if (lbn < UFS_NDADDR + FFS_NINDIR(fs)) { |
cg = ino_to_cg(fs, ip->i_number); |
cg = ino_to_cg(fs, ip->i_number); |
return (cgbase(fs, cg) + fs->fs_frag); |
return (cgbase(fs, cg) + fs->fs_frag); |
} |
} |
Line 895 ffs_blkpref_ufs2(struct inode *ip, daddr |
|
Line 898 ffs_blkpref_ufs2(struct inode *ip, daddr |
|
if (flags & B_METAONLY) |
if (flags & B_METAONLY) |
return ip->i_ffs_first_indir_blk; |
return ip->i_ffs_first_indir_blk; |
else |
else |
return ip->i_ffs_first_data_blk + blkstofrags(fs, lbn); |
return ip->i_ffs_first_data_blk + ffs_blkstofrags(fs, lbn); |
} |
} |
|
|
if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) { |
if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) { |
if (lbn < NDADDR + NINDIR(fs)) { |
if (lbn < UFS_NDADDR + FFS_NINDIR(fs)) { |
cg = ino_to_cg(fs, ip->i_number); |
cg = ino_to_cg(fs, ip->i_number); |
return (cgbase(fs, cg) + fs->fs_frag); |
return (cgbase(fs, cg) + fs->fs_frag); |
} |
} |
Line 1018 ffs_fragextend(struct inode *ip, int cg, |
|
Line 1021 ffs_fragextend(struct inode *ip, int cg, |
|
|
|
KASSERT(mutex_owned(&ump->um_lock)); |
KASSERT(mutex_owned(&ump->um_lock)); |
|
|
if (fs->fs_cs(fs, cg).cs_nffree < numfrags(fs, nsize - osize)) |
if (fs->fs_cs(fs, cg).cs_nffree < ffs_numfrags(fs, nsize - osize)) |
return (0); |
return (0); |
frags = numfrags(fs, nsize); |
frags = ffs_numfrags(fs, nsize); |
bbase = fragnum(fs, bprev); |
bbase = ffs_fragnum(fs, bprev); |
if (bbase > fragnum(fs, (bprev + frags - 1))) { |
if (bbase > ffs_fragnum(fs, (bprev + frags - 1))) { |
/* cannot extend across a block boundary */ |
/* cannot extend across a block boundary */ |
return (0); |
return (0); |
} |
} |
mutex_exit(&ump->um_lock); |
mutex_exit(&ump->um_lock); |
error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), |
error = bread(ip->i_devvp, FFS_FSBTODB(fs, cgtod(fs, cg)), |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
if (error) |
if (error) |
goto fail; |
goto fail; |
Line 1040 ffs_fragextend(struct inode *ip, int cg, |
|
Line 1043 ffs_fragextend(struct inode *ip, int cg, |
|
cgp->cg_time = ufs_rw64(time_second, UFS_FSNEEDSWAP(fs)); |
cgp->cg_time = ufs_rw64(time_second, UFS_FSNEEDSWAP(fs)); |
bno = dtogd(fs, bprev); |
bno = dtogd(fs, bprev); |
blksfree = cg_blksfree(cgp, UFS_FSNEEDSWAP(fs)); |
blksfree = cg_blksfree(cgp, UFS_FSNEEDSWAP(fs)); |
for (i = numfrags(fs, osize); i < frags; i++) |
for (i = ffs_numfrags(fs, osize); i < frags; i++) |
if (isclr(blksfree, bno + i)) |
if (isclr(blksfree, bno + i)) |
goto fail; |
goto fail; |
/* |
/* |
Line 1052 ffs_fragextend(struct inode *ip, int cg, |
|
Line 1055 ffs_fragextend(struct inode *ip, int cg, |
|
for (i = frags; i < fs->fs_frag - bbase; i++) |
for (i = frags; i < fs->fs_frag - bbase; i++) |
if (isclr(blksfree, bno + i)) |
if (isclr(blksfree, bno + i)) |
break; |
break; |
ufs_add32(cgp->cg_frsum[i - numfrags(fs, osize)], -1, UFS_FSNEEDSWAP(fs)); |
ufs_add32(cgp->cg_frsum[i - ffs_numfrags(fs, osize)], -1, UFS_FSNEEDSWAP(fs)); |
if (i != frags) |
if (i != frags) |
ufs_add32(cgp->cg_frsum[i - frags], 1, UFS_FSNEEDSWAP(fs)); |
ufs_add32(cgp->cg_frsum[i - frags], 1, UFS_FSNEEDSWAP(fs)); |
mutex_enter(&ump->um_lock); |
mutex_enter(&ump->um_lock); |
for (i = numfrags(fs, osize); i < frags; i++) { |
for (i = ffs_numfrags(fs, osize); i < frags; i++) { |
clrbit(blksfree, bno + i); |
clrbit(blksfree, bno + i); |
ufs_add32(cgp->cg_cs.cs_nffree, -1, UFS_FSNEEDSWAP(fs)); |
ufs_add32(cgp->cg_cs.cs_nffree, -1, UFS_FSNEEDSWAP(fs)); |
fs->fs_cstotal.cs_nffree--; |
fs->fs_cstotal.cs_nffree--; |
Line 1069 ffs_fragextend(struct inode *ip, int cg, |
|
Line 1072 ffs_fragextend(struct inode *ip, int cg, |
|
return (bprev); |
return (bprev); |
|
|
fail: |
fail: |
brelse(bp, 0); |
if (bp != NULL) |
|
brelse(bp, 0); |
mutex_enter(&ump->um_lock); |
mutex_enter(&ump->um_lock); |
return (0); |
return (0); |
} |
} |
Line 1091 ffs_alloccg(struct inode *ip, int cg, da |
|
Line 1095 ffs_alloccg(struct inode *ip, int cg, da |
|
daddr_t blkno; |
daddr_t blkno; |
int error, frags, allocsiz, i; |
int error, frags, allocsiz, i; |
u_int8_t *blksfree; |
u_int8_t *blksfree; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
ump = ip->i_ump; |
ump = ip->i_ump; |
|
|
Line 1102 ffs_alloccg(struct inode *ip, int cg, da |
|
Line 1104 ffs_alloccg(struct inode *ip, int cg, da |
|
if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize) |
if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize) |
return (0); |
return (0); |
mutex_exit(&ump->um_lock); |
mutex_exit(&ump->um_lock); |
error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), |
error = bread(ip->i_devvp, FFS_FSBTODB(fs, cgtod(fs, cg)), |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
if (error) |
if (error) |
goto fail; |
goto fail; |
Line 1128 ffs_alloccg(struct inode *ip, int cg, da |
|
Line 1130 ffs_alloccg(struct inode *ip, int cg, da |
|
* it down to a smaller size if necessary |
* it down to a smaller size if necessary |
*/ |
*/ |
blksfree = cg_blksfree(cgp, needswap); |
blksfree = cg_blksfree(cgp, needswap); |
frags = numfrags(fs, size); |
frags = ffs_numfrags(fs, size); |
for (allocsiz = frags; allocsiz < fs->fs_frag; allocsiz++) |
for (allocsiz = frags; allocsiz < fs->fs_frag; allocsiz++) |
if (cgp->cg_frsum[allocsiz] != 0) |
if (cgp->cg_frsum[allocsiz] != 0) |
break; |
break; |
Line 1181 ffs_alloccg(struct inode *ip, int cg, da |
|
Line 1183 ffs_alloccg(struct inode *ip, int cg, da |
|
return blkno; |
return blkno; |
|
|
fail: |
fail: |
brelse(bp, 0); |
if (bp != NULL) |
|
brelse(bp, 0); |
mutex_enter(&ump->um_lock); |
mutex_enter(&ump->um_lock); |
return (0); |
return (0); |
} |
} |
Line 1200 ffs_alloccg(struct inode *ip, int cg, da |
|
Line 1203 ffs_alloccg(struct inode *ip, int cg, da |
|
static daddr_t |
static daddr_t |
ffs_alloccgblk(struct inode *ip, struct buf *bp, daddr_t bpref, int flags) |
ffs_alloccgblk(struct inode *ip, struct buf *bp, daddr_t bpref, int flags) |
{ |
{ |
struct ufsmount *ump; |
|
struct fs *fs = ip->i_fs; |
struct fs *fs = ip->i_fs; |
struct cg *cgp; |
struct cg *cgp; |
int cg; |
int cg; |
daddr_t blkno; |
daddr_t blkno; |
int32_t bno; |
int32_t bno; |
u_int8_t *blksfree; |
u_int8_t *blksfree; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
ump = ip->i_ump; |
|
|
|
KASSERT(mutex_owned(&ump->um_lock)); |
KASSERT(mutex_owned(&ip->i_ump->um_lock)); |
|
|
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
blksfree = cg_blksfree(cgp, needswap); |
blksfree = cg_blksfree(cgp, needswap); |
if (bpref == 0 || dtog(fs, bpref) != ufs_rw32(cgp->cg_cgx, needswap)) { |
if (bpref == 0 || dtog(fs, bpref) != ufs_rw32(cgp->cg_cgx, needswap)) { |
bpref = ufs_rw32(cgp->cg_rotor, needswap); |
bpref = ufs_rw32(cgp->cg_rotor, needswap); |
} else { |
} else { |
bpref = blknum(fs, bpref); |
bpref = ffs_blknum(fs, bpref); |
bno = dtogd(fs, bpref); |
bno = dtogd(fs, bpref); |
/* |
/* |
* if the requested block is available, use it |
* if the requested block is available, use it |
*/ |
*/ |
if (ffs_isblock(fs, blksfree, fragstoblks(fs, bno))) |
if (ffs_isblock(fs, blksfree, ffs_fragstoblks(fs, bno))) |
goto gotit; |
goto gotit; |
/* |
/* |
* if the requested data block isn't available and we are |
* if the requested data block isn't available and we are |
Line 1243 ffs_alloccgblk(struct inode *ip, struct |
|
Line 1241 ffs_alloccgblk(struct inode *ip, struct |
|
return (0); |
return (0); |
cgp->cg_rotor = ufs_rw32(bno, needswap); |
cgp->cg_rotor = ufs_rw32(bno, needswap); |
gotit: |
gotit: |
blkno = fragstoblks(fs, bno); |
blkno = ffs_fragstoblks(fs, bno); |
ffs_clrblock(fs, blksfree, blkno); |
ffs_clrblock(fs, blksfree, blkno); |
ffs_clusteracct(fs, cgp, blkno, -1); |
ffs_clusteracct(fs, cgp, blkno, -1); |
ufs_add32(cgp->cg_cs.cs_nbfree, -1, needswap); |
ufs_add32(cgp->cg_cs.cs_nbfree, -1, needswap); |
Line 1288 ffs_nodealloccg(struct inode *ip, int cg |
|
Line 1286 ffs_nodealloccg(struct inode *ip, int cg |
|
int32_t initediblk; |
int32_t initediblk; |
daddr_t nalloc; |
daddr_t nalloc; |
struct ufs2_dinode *dp2; |
struct ufs2_dinode *dp2; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
KASSERT(mutex_owned(&ump->um_lock)); |
KASSERT(mutex_owned(&ump->um_lock)); |
UFS_WAPBL_JLOCK_ASSERT(ip->i_ump->um_mountp); |
UFS_WAPBL_JLOCK_ASSERT(ip->i_ump->um_mountp); |
Line 1301 ffs_nodealloccg(struct inode *ip, int cg |
|
Line 1297 ffs_nodealloccg(struct inode *ip, int cg |
|
ibp = NULL; |
ibp = NULL; |
initediblk = -1; |
initediblk = -1; |
retry: |
retry: |
error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), |
error = bread(ip->i_devvp, FFS_FSBTODB(fs, cgtod(fs, cg)), |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
if (error) |
if (error) |
goto fail; |
goto fail; |
|
|
if (fs->fs_magic == FS_UFS2_MAGIC && ibp == NULL) { |
if (fs->fs_magic == FS_UFS2_MAGIC && ibp == NULL) { |
initediblk = ufs_rw32(cgp->cg_initediblk, needswap); |
initediblk = ufs_rw32(cgp->cg_initediblk, needswap); |
nalloc = fs->fs_ipg - ufs_rw32(cgp->cg_cs.cs_nifree, needswap); |
nalloc = fs->fs_ipg - ufs_rw32(cgp->cg_cs.cs_nifree, needswap); |
if (nalloc + INOPB(fs) > initediblk && |
if (nalloc + FFS_INOPB(fs) > initediblk && |
initediblk < ufs_rw32(cgp->cg_niblk, needswap)) { |
initediblk < ufs_rw32(cgp->cg_niblk, needswap)) { |
/* |
/* |
* We have to release the cg buffer here to prevent |
* We have to release the cg buffer here to prevent |
|
|
*/ |
*/ |
brelse(bp, 0); |
brelse(bp, 0); |
bp = NULL; |
bp = NULL; |
error = ffs_getblk(ip->i_devvp, fsbtodb(fs, |
error = ffs_getblk(ip->i_devvp, FFS_FSBTODB(fs, |
ino_to_fsba(fs, cg * fs->fs_ipg + initediblk)), |
ino_to_fsba(fs, cg * fs->fs_ipg + initediblk)), |
FFS_NOBLK, fs->fs_bsize, false, &ibp); |
FFS_NOBLK, fs->fs_bsize, false, &ibp); |
if (error) |
if (error) |
|
|
KASSERT(initediblk == ufs_rw32(cgp->cg_initediblk, needswap)); |
KASSERT(initediblk == ufs_rw32(cgp->cg_initediblk, needswap)); |
memset(ibp->b_data, 0, fs->fs_bsize); |
memset(ibp->b_data, 0, fs->fs_bsize); |
dp2 = (struct ufs2_dinode *)(ibp->b_data); |
dp2 = (struct ufs2_dinode *)(ibp->b_data); |
for (i = 0; i < INOPB(fs); i++) { |
for (i = 0; i < FFS_INOPB(fs); i++) { |
/* |
/* |
* Don't bother to swap, it's supposed to be |
* Don't bother to swap, it's supposed to be |
* random, after all. |
* random, after all. |
*/ |
*/ |
dp2->di_gen = (arc4random() & INT32_MAX) / 2 + 1; |
dp2->di_gen = (cprng_fast32() & INT32_MAX) / 2 + 1; |
dp2++; |
dp2++; |
} |
} |
initediblk += INOPB(fs); |
initediblk += FFS_INOPB(fs); |
cgp->cg_initediblk = ufs_rw32(initediblk, needswap); |
cgp->cg_initediblk = ufs_rw32(initediblk, needswap); |
} |
} |
|
|
Line 1457 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
Line 1453 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
u_int8_t *blksfree; |
u_int8_t *blksfree; |
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
|
|
KASSERT((u_int)size <= fs->fs_bsize && fragoff(fs, size) == 0 && |
KASSERT((u_int)size <= fs->fs_bsize && ffs_fragoff(fs, size) == 0 && |
fragnum(fs, bno) + numfrags(fs, size) <= fs->fs_frag); |
ffs_fragnum(fs, bno) + ffs_numfrags(fs, size) <= fs->fs_frag); |
KASSERT(bno < fs->fs_size); |
KASSERT(bno < fs->fs_size); |
|
|
cg = dtog(fs, bno); |
cg = dtog(fs, bno); |
error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)), |
error = bread(ump->um_devvp, FFS_FSBTODB(fs, cgtod(fs, cg)), |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
(int)fs->fs_cgsize, NOCRED, B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return error; |
return error; |
} |
} |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1480 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
Line 1475 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
|
|
mutex_enter(&ump->um_lock); |
mutex_enter(&ump->um_lock); |
if (size == fs->fs_bsize) { |
if (size == fs->fs_bsize) { |
fragno = fragstoblks(fs, cgbno); |
fragno = ffs_fragstoblks(fs, cgbno); |
if (!ffs_isblock(fs, blksfree, fragno)) { |
if (!ffs_isblock(fs, blksfree, fragno)) { |
mutex_exit(&ump->um_lock); |
mutex_exit(&ump->um_lock); |
brelse(bp, 0); |
brelse(bp, 0); |
Line 1492 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
Line 1487 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
fs->fs_cstotal.cs_nbfree--; |
fs->fs_cstotal.cs_nbfree--; |
fs->fs_cs(fs, cg).cs_nbfree--; |
fs->fs_cs(fs, cg).cs_nbfree--; |
} else { |
} else { |
bbase = cgbno - fragnum(fs, cgbno); |
bbase = cgbno - ffs_fragnum(fs, cgbno); |
|
|
frags = numfrags(fs, size); |
frags = ffs_numfrags(fs, size); |
for (i = 0; i < frags; i++) { |
for (i = 0; i < frags; i++) { |
if (isclr(blksfree, cgbno + i)) { |
if (isclr(blksfree, cgbno + i)) { |
mutex_exit(&ump->um_lock); |
mutex_exit(&ump->um_lock); |
Line 1505 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
Line 1500 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
/* |
/* |
* if a complete block is being split, account for it |
* if a complete block is being split, account for it |
*/ |
*/ |
fragno = fragstoblks(fs, bbase); |
fragno = ffs_fragstoblks(fs, bbase); |
if (ffs_isblock(fs, blksfree, fragno)) { |
if (ffs_isblock(fs, blksfree, fragno)) { |
ufs_add32(cgp->cg_cs.cs_nffree, fs->fs_frag, needswap); |
ufs_add32(cgp->cg_cs.cs_nffree, fs->fs_frag, needswap); |
fs->fs_cstotal.cs_nffree += fs->fs_frag; |
fs->fs_cstotal.cs_nffree += fs->fs_frag; |
Line 1551 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
Line 1546 ffs_blkalloc_ump(struct ufsmount *ump, d |
|
* |
* |
* => um_lock not held on entry or exit |
* => um_lock not held on entry or exit |
*/ |
*/ |
void |
static void |
ffs_blkfree(struct fs *fs, struct vnode *devvp, daddr_t bno, long size, |
ffs_blkfree_cg(struct fs *fs, struct vnode *devvp, daddr_t bno, long size) |
ino_t inum) |
|
{ |
{ |
struct cg *cgp; |
struct cg *cgp; |
struct buf *bp; |
struct buf *bp; |
Line 1562 ffs_blkfree(struct fs *fs, struct vnode |
|
Line 1556 ffs_blkfree(struct fs *fs, struct vnode |
|
int error, cg; |
int error, cg; |
dev_t dev; |
dev_t dev; |
const bool devvp_is_snapshot = (devvp->v_type != VBLK); |
const bool devvp_is_snapshot = (devvp->v_type != VBLK); |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
KASSERT(!devvp_is_snapshot); |
KASSERT(!devvp_is_snapshot); |
|
|
cg = dtog(fs, bno); |
cg = dtog(fs, bno); |
dev = devvp->v_rdev; |
dev = devvp->v_rdev; |
ump = VFSTOUFS(devvp->v_specmountpoint); |
ump = VFSTOUFS(spec_node_getmountedfs(devvp)); |
KASSERT(fs == ump->um_fs); |
KASSERT(fs == ump->um_fs); |
cgblkno = fsbtodb(fs, cgtod(fs, cg)); |
cgblkno = FFS_FSBTODB(fs, cgtod(fs, cg)); |
if (ffs_snapblkfree(fs, devvp, bno, size, inum)) |
|
return; |
|
|
|
error = ffs_check_bad_allocation(__func__, fs, bno, size, dev, inum); |
|
if (error) |
|
return; |
|
|
|
error = bread(devvp, cgblkno, (int)fs->fs_cgsize, |
error = bread(devvp, cgblkno, (int)fs->fs_cgsize, |
NOCRED, B_MODIFY, &bp); |
NOCRED, B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return; |
return; |
} |
} |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1597 ffs_blkfree(struct fs *fs, struct vnode |
|
Line 1582 ffs_blkfree(struct fs *fs, struct vnode |
|
bdwrite(bp); |
bdwrite(bp); |
} |
} |
|
|
|
struct discardopdata { |
|
struct work wk; /* must be first */ |
|
struct vnode *devvp; |
|
daddr_t bno; |
|
long size; |
|
}; |
|
|
|
struct discarddata { |
|
struct fs *fs; |
|
struct discardopdata *entry; |
|
long maxsize; |
|
kmutex_t entrylk; |
|
struct workqueue *wq; |
|
int wqcnt, wqdraining; |
|
kmutex_t wqlk; |
|
kcondvar_t wqcv; |
|
/* timer for flush? */ |
|
}; |
|
|
|
static void |
|
ffs_blkfree_td(struct fs *fs, struct discardopdata *td) |
|
{ |
|
long todo; |
|
|
|
while (td->size) { |
|
todo = min(td->size, |
|
ffs_lfragtosize(fs, (fs->fs_frag - ffs_fragnum(fs, td->bno)))); |
|
ffs_blkfree_cg(fs, td->devvp, td->bno, todo); |
|
td->bno += ffs_numfrags(fs, todo); |
|
td->size -= todo; |
|
} |
|
} |
|
|
|
static void |
|
ffs_discardcb(struct work *wk, void *arg) |
|
{ |
|
struct discardopdata *td = (void *)wk; |
|
struct discarddata *ts = arg; |
|
struct fs *fs = ts->fs; |
|
struct disk_discard_range ta; |
|
#ifdef TRIMDEBUG |
|
int error; |
|
#endif |
|
|
|
ta.bno = FFS_FSBTODB(fs, td->bno); |
|
ta.size = td->size >> DEV_BSHIFT; |
|
#ifdef TRIMDEBUG |
|
error = |
|
#endif |
|
VOP_IOCTL(td->devvp, DIOCDISCARD, &ta, FWRITE, FSCRED); |
|
#ifdef TRIMDEBUG |
|
printf("trim(%" PRId64 ",%ld):%d\n", td->bno, td->size, error); |
|
#endif |
|
|
|
ffs_blkfree_td(fs, td); |
|
kmem_free(td, sizeof(*td)); |
|
mutex_enter(&ts->wqlk); |
|
ts->wqcnt--; |
|
if (ts->wqdraining && !ts->wqcnt) |
|
cv_signal(&ts->wqcv); |
|
mutex_exit(&ts->wqlk); |
|
} |
|
|
|
void * |
|
ffs_discard_init(struct vnode *devvp, struct fs *fs) |
|
{ |
|
struct disk_discard_params tp; |
|
struct discarddata *ts; |
|
int error; |
|
|
|
error = VOP_IOCTL(devvp, DIOCGDISCARDPARAMS, &tp, FREAD, FSCRED); |
|
if (error) { |
|
printf("DIOCGDISCARDPARAMS: %d\n", error); |
|
return NULL; |
|
} |
|
if (tp.maxsize * DEV_BSIZE < fs->fs_bsize) { |
|
printf("tp.maxsize=%ld, fs_bsize=%d\n", tp.maxsize, fs->fs_bsize); |
|
return NULL; |
|
} |
|
|
|
ts = kmem_zalloc(sizeof (*ts), KM_SLEEP); |
|
error = workqueue_create(&ts->wq, "trimwq", ffs_discardcb, ts, |
|
0, 0, 0); |
|
if (error) { |
|
kmem_free(ts, sizeof (*ts)); |
|
return NULL; |
|
} |
|
mutex_init(&ts->entrylk, MUTEX_DEFAULT, IPL_NONE); |
|
mutex_init(&ts->wqlk, MUTEX_DEFAULT, IPL_NONE); |
|
cv_init(&ts->wqcv, "trimwqcv"); |
|
ts->maxsize = max(tp.maxsize * DEV_BSIZE, 100*1024); /* XXX */ |
|
ts->fs = fs; |
|
return ts; |
|
} |
|
|
|
void |
|
ffs_discard_finish(void *vts, int flags) |
|
{ |
|
struct discarddata *ts = vts; |
|
struct discardopdata *td = NULL; |
|
int res = 0; |
|
|
|
/* wait for workqueue to drain */ |
|
mutex_enter(&ts->wqlk); |
|
if (ts->wqcnt) { |
|
ts->wqdraining = 1; |
|
res = cv_timedwait(&ts->wqcv, &ts->wqlk, mstohz(5000)); |
|
} |
|
mutex_exit(&ts->wqlk); |
|
if (res) |
|
printf("ffs_discarddata drain timeout\n"); |
|
|
|
mutex_enter(&ts->entrylk); |
|
if (ts->entry) { |
|
td = ts->entry; |
|
ts->entry = NULL; |
|
} |
|
mutex_exit(&ts->entrylk); |
|
if (td) { |
|
/* XXX don't tell disk, its optional */ |
|
ffs_blkfree_td(ts->fs, td); |
|
#ifdef TRIMDEBUG |
|
printf("finish(%" PRId64 ",%ld)\n", td->bno, td->size); |
|
#endif |
|
kmem_free(td, sizeof(*td)); |
|
} |
|
|
|
cv_destroy(&ts->wqcv); |
|
mutex_destroy(&ts->entrylk); |
|
mutex_destroy(&ts->wqlk); |
|
workqueue_destroy(ts->wq); |
|
kmem_free(ts, sizeof(*ts)); |
|
} |
|
|
|
void |
|
ffs_blkfree(struct fs *fs, struct vnode *devvp, daddr_t bno, long size, |
|
ino_t inum) |
|
{ |
|
struct ufsmount *ump; |
|
int error; |
|
dev_t dev; |
|
struct discarddata *ts; |
|
struct discardopdata *td; |
|
|
|
dev = devvp->v_rdev; |
|
ump = VFSTOUFS(spec_node_getmountedfs(devvp)); |
|
if (ffs_snapblkfree(fs, devvp, bno, size, inum)) |
|
return; |
|
|
|
error = ffs_check_bad_allocation(__func__, fs, bno, size, dev, inum); |
|
if (error) |
|
return; |
|
|
|
if (!ump->um_discarddata) { |
|
ffs_blkfree_cg(fs, devvp, bno, size); |
|
return; |
|
} |
|
|
|
#ifdef TRIMDEBUG |
|
printf("blkfree(%" PRId64 ",%ld)\n", bno, size); |
|
#endif |
|
ts = ump->um_discarddata; |
|
td = NULL; |
|
|
|
mutex_enter(&ts->entrylk); |
|
if (ts->entry) { |
|
td = ts->entry; |
|
/* ffs deallocs backwards, check for prepend only */ |
|
if (td->bno == bno + ffs_numfrags(fs, size) |
|
&& td->size + size <= ts->maxsize) { |
|
td->bno = bno; |
|
td->size += size; |
|
if (td->size < ts->maxsize) { |
|
#ifdef TRIMDEBUG |
|
printf("defer(%" PRId64 ",%ld)\n", td->bno, td->size); |
|
#endif |
|
mutex_exit(&ts->entrylk); |
|
return; |
|
} |
|
size = 0; /* mark done */ |
|
} |
|
ts->entry = NULL; |
|
} |
|
mutex_exit(&ts->entrylk); |
|
|
|
if (td) { |
|
#ifdef TRIMDEBUG |
|
printf("enq old(%" PRId64 ",%ld)\n", td->bno, td->size); |
|
#endif |
|
mutex_enter(&ts->wqlk); |
|
ts->wqcnt++; |
|
mutex_exit(&ts->wqlk); |
|
workqueue_enqueue(ts->wq, &td->wk, NULL); |
|
} |
|
if (!size) |
|
return; |
|
|
|
td = kmem_alloc(sizeof(*td), KM_SLEEP); |
|
td->devvp = devvp; |
|
td->bno = bno; |
|
td->size = size; |
|
|
|
if (td->size < ts->maxsize) { /* XXX always the case */ |
|
mutex_enter(&ts->entrylk); |
|
if (!ts->entry) { /* possible race? */ |
|
#ifdef TRIMDEBUG |
|
printf("defer(%" PRId64 ",%ld)\n", td->bno, td->size); |
|
#endif |
|
ts->entry = td; |
|
td = NULL; |
|
} |
|
mutex_exit(&ts->entrylk); |
|
} |
|
if (td) { |
|
#ifdef TRIMDEBUG |
|
printf("enq new(%" PRId64 ",%ld)\n", td->bno, td->size); |
|
#endif |
|
mutex_enter(&ts->wqlk); |
|
ts->wqcnt++; |
|
mutex_exit(&ts->wqlk); |
|
workqueue_enqueue(ts->wq, &td->wk, NULL); |
|
} |
|
} |
|
|
/* |
/* |
* Free a block or fragment from a snapshot cg copy. |
* Free a block or fragment from a snapshot cg copy. |
* |
* |
Line 1617 ffs_blkfree_snap(struct fs *fs, struct v |
|
Line 1826 ffs_blkfree_snap(struct fs *fs, struct v |
|
int error, cg; |
int error, cg; |
dev_t dev; |
dev_t dev; |
const bool devvp_is_snapshot = (devvp->v_type != VBLK); |
const bool devvp_is_snapshot = (devvp->v_type != VBLK); |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
KASSERT(devvp_is_snapshot); |
KASSERT(devvp_is_snapshot); |
|
|
cg = dtog(fs, bno); |
cg = dtog(fs, bno); |
dev = VTOI(devvp)->i_devvp->v_rdev; |
dev = VTOI(devvp)->i_devvp->v_rdev; |
ump = VFSTOUFS(devvp->v_mount); |
ump = VFSTOUFS(devvp->v_mount); |
cgblkno = fragstoblks(fs, cgtod(fs, cg)); |
cgblkno = ffs_fragstoblks(fs, cgtod(fs, cg)); |
|
|
error = ffs_check_bad_allocation(__func__, fs, bno, size, dev, inum); |
error = ffs_check_bad_allocation(__func__, fs, bno, size, dev, inum); |
if (error) |
if (error) |
Line 1635 ffs_blkfree_snap(struct fs *fs, struct v |
|
Line 1842 ffs_blkfree_snap(struct fs *fs, struct v |
|
error = bread(devvp, cgblkno, (int)fs->fs_cgsize, |
error = bread(devvp, cgblkno, (int)fs->fs_cgsize, |
NOCRED, B_MODIFY, &bp); |
NOCRED, B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return; |
return; |
} |
} |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1669 ffs_blkfree_common(struct ufsmount *ump, |
|
Line 1875 ffs_blkfree_common(struct ufsmount *ump, |
|
blksfree = cg_blksfree(cgp, needswap); |
blksfree = cg_blksfree(cgp, needswap); |
mutex_enter(&ump->um_lock); |
mutex_enter(&ump->um_lock); |
if (size == fs->fs_bsize) { |
if (size == fs->fs_bsize) { |
fragno = fragstoblks(fs, cgbno); |
fragno = ffs_fragstoblks(fs, cgbno); |
if (!ffs_isfreeblock(fs, blksfree, fragno)) { |
if (!ffs_isfreeblock(fs, blksfree, fragno)) { |
if (devvp_is_snapshot) { |
if (devvp_is_snapshot) { |
mutex_exit(&ump->um_lock); |
mutex_exit(&ump->um_lock); |
Line 1696 ffs_blkfree_common(struct ufsmount *ump, |
|
Line 1902 ffs_blkfree_common(struct ufsmount *ump, |
|
ufs_add32(old_cg_blktot(cgp, needswap)[i], 1, needswap); |
ufs_add32(old_cg_blktot(cgp, needswap)[i], 1, needswap); |
} |
} |
} else { |
} else { |
bbase = cgbno - fragnum(fs, cgbno); |
bbase = cgbno - ffs_fragnum(fs, cgbno); |
/* |
/* |
* decrement the counts associated with the old frags |
* decrement the counts associated with the old frags |
*/ |
*/ |
Line 1705 ffs_blkfree_common(struct ufsmount *ump, |
|
Line 1911 ffs_blkfree_common(struct ufsmount *ump, |
|
/* |
/* |
* deallocate the fragment |
* deallocate the fragment |
*/ |
*/ |
frags = numfrags(fs, size); |
frags = ffs_numfrags(fs, size); |
for (i = 0; i < frags; i++) { |
for (i = 0; i < frags; i++) { |
if (isset(blksfree, cgbno + i)) { |
if (isset(blksfree, cgbno + i)) { |
printf("dev = 0x%llx, block = %" PRId64 |
printf("dev = 0x%llx, block = %" PRId64 |
Line 1727 ffs_blkfree_common(struct ufsmount *ump, |
|
Line 1933 ffs_blkfree_common(struct ufsmount *ump, |
|
/* |
/* |
* if a complete block has been reassembled, account for it |
* if a complete block has been reassembled, account for it |
*/ |
*/ |
fragno = fragstoblks(fs, bbase); |
fragno = ffs_fragstoblks(fs, bbase); |
if (ffs_isblock(fs, blksfree, fragno)) { |
if (ffs_isblock(fs, blksfree, fragno)) { |
ufs_add32(cgp->cg_cs.cs_nffree, -fs->fs_frag, needswap); |
ufs_add32(cgp->cg_cs.cs_nffree, -fs->fs_frag, needswap); |
fs->fs_cstotal.cs_nffree -= fs->fs_frag; |
fs->fs_cstotal.cs_nffree -= fs->fs_frag; |
Line 1781 ffs_freefile(struct mount *mp, ino_t ino |
|
Line 1987 ffs_freefile(struct mount *mp, ino_t ino |
|
int error, cg; |
int error, cg; |
daddr_t cgbno; |
daddr_t cgbno; |
dev_t dev; |
dev_t dev; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
cg = ino_to_cg(fs, ino); |
cg = ino_to_cg(fs, ino); |
devvp = ump->um_devvp; |
devvp = ump->um_devvp; |
dev = devvp->v_rdev; |
dev = devvp->v_rdev; |
cgbno = fsbtodb(fs, cgtod(fs, cg)); |
cgbno = FFS_FSBTODB(fs, cgtod(fs, cg)); |
|
|
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) |
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) |
panic("ifree: range: dev = 0x%llx, ino = %llu, fs = %s", |
panic("ifree: range: dev = 0x%llx, ino = %llu, fs = %s", |
Line 1796 ffs_freefile(struct mount *mp, ino_t ino |
|
Line 2000 ffs_freefile(struct mount *mp, ino_t ino |
|
error = bread(devvp, cgbno, (int)fs->fs_cgsize, |
error = bread(devvp, cgbno, (int)fs->fs_cgsize, |
NOCRED, B_MODIFY, &bp); |
NOCRED, B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return (error); |
return (error); |
} |
} |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1821 ffs_freefile_snap(struct fs *fs, struct |
|
Line 2024 ffs_freefile_snap(struct fs *fs, struct |
|
int error, cg; |
int error, cg; |
daddr_t cgbno; |
daddr_t cgbno; |
dev_t dev; |
dev_t dev; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
KASSERT(devvp->v_type != VBLK); |
KASSERT(devvp->v_type != VBLK); |
|
|
cg = ino_to_cg(fs, ino); |
cg = ino_to_cg(fs, ino); |
dev = VTOI(devvp)->i_devvp->v_rdev; |
dev = VTOI(devvp)->i_devvp->v_rdev; |
ump = VFSTOUFS(devvp->v_mount); |
ump = VFSTOUFS(devvp->v_mount); |
cgbno = fragstoblks(fs, cgtod(fs, cg)); |
cgbno = ffs_fragstoblks(fs, cgtod(fs, cg)); |
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) |
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) |
panic("ifree: range: dev = 0x%llx, ino = %llu, fs = %s", |
panic("ifree: range: dev = 0x%llx, ino = %llu, fs = %s", |
(unsigned long long)dev, (unsigned long long)ino, |
(unsigned long long)dev, (unsigned long long)ino, |
Line 1838 ffs_freefile_snap(struct fs *fs, struct |
|
Line 2039 ffs_freefile_snap(struct fs *fs, struct |
|
error = bread(devvp, cgbno, (int)fs->fs_cgsize, |
error = bread(devvp, cgbno, (int)fs->fs_cgsize, |
NOCRED, B_MODIFY, &bp); |
NOCRED, B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return (error); |
return (error); |
} |
} |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1860 ffs_freefile_common(struct ufsmount *ump |
|
Line 2060 ffs_freefile_common(struct ufsmount *ump |
|
int cg; |
int cg; |
struct cg *cgp; |
struct cg *cgp; |
u_int8_t *inosused; |
u_int8_t *inosused; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
cg = ino_to_cg(fs, ino); |
cg = ino_to_cg(fs, ino); |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1916 ffs_checkfreefile(struct fs *fs, struct |
|
Line 2114 ffs_checkfreefile(struct fs *fs, struct |
|
|
|
cg = ino_to_cg(fs, ino); |
cg = ino_to_cg(fs, ino); |
if (devvp_is_snapshot) |
if (devvp_is_snapshot) |
cgbno = fragstoblks(fs, cgtod(fs, cg)); |
cgbno = ffs_fragstoblks(fs, cgtod(fs, cg)); |
else |
else |
cgbno = fsbtodb(fs, cgtod(fs, cg)); |
cgbno = FFS_FSBTODB(fs, cgtod(fs, cg)); |
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) |
if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) |
return 1; |
return 1; |
if (bread(devvp, cgbno, (int)fs->fs_cgsize, NOCRED, 0, &bp)) { |
if (bread(devvp, cgbno, (int)fs->fs_cgsize, NOCRED, 0, &bp)) { |
brelse(bp, 0); |
|
return 1; |
return 1; |
} |
} |
cgp = (struct cg *)bp->b_data; |
cgp = (struct cg *)bp->b_data; |
Line 1951 ffs_mapsearch(struct fs *fs, struct cg * |
|
Line 2148 ffs_mapsearch(struct fs *fs, struct cg * |
|
int blk, field, subfield, pos; |
int blk, field, subfield, pos; |
int ostart, olen; |
int ostart, olen; |
u_int8_t *blksfree; |
u_int8_t *blksfree; |
#ifdef FFS_EI |
|
const int needswap = UFS_FSNEEDSWAP(fs); |
const int needswap = UFS_FSNEEDSWAP(fs); |
#endif |
|
|
|
/* KASSERT(mutex_owned(&ump->um_lock)); */ |
/* KASSERT(mutex_owned(&ump->um_lock)); */ |
|
|