Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ffs/ffs_balloc.c
Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct inode *ip; | struct inode *ip; | ||||
struct ufs1_dinode *dp; | struct ufs1_dinode *dp; | ||||
ufs_lbn_t lbn, lastlbn; | ufs_lbn_t lbn, lastlbn; | ||||
struct fs *fs; | struct fs *fs; | ||||
ufs1_daddr_t nb; | ufs1_daddr_t nb; | ||||
struct buf *bp, *nbp; | struct buf *bp, *nbp; | ||||
struct ufsmount *ump; | struct ufsmount *ump; | ||||
struct indir indirs[NIADDR + 2]; | struct indir indirs[UFS_NIADDR + 2]; | ||||
int deallocated, osize, nsize, num, i, error; | int deallocated, osize, nsize, num, i, error; | ||||
ufs2_daddr_t newb; | ufs2_daddr_t newb; | ||||
ufs1_daddr_t *bap, pref; | ufs1_daddr_t *bap, pref; | ||||
ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; | ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[UFS_NIADDR + 1]; | ||||
ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1]; | ufs2_daddr_t *lbns_remfree, lbns[UFS_NIADDR + 1]; | ||||
int unwindidx = -1; | int unwindidx = -1; | ||||
int saved_inbdflush; | int saved_inbdflush; | ||||
static struct timeval lastfail; | static struct timeval lastfail; | ||||
static int curfail; | static int curfail; | ||||
int gbflags, reclaimed; | int gbflags, reclaimed; | ||||
ip = VTOI(vp); | ip = VTOI(vp); | ||||
dp = ip->i_din1; | dp = ip->i_din1; | ||||
Show All 14 Lines | ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, | ||||
if (DOINGSOFTDEP(vp)) | if (DOINGSOFTDEP(vp)) | ||||
softdep_prealloc(vp, MNT_WAIT); | softdep_prealloc(vp, MNT_WAIT); | ||||
/* | /* | ||||
* If the next write will extend the file into a new block, | * If the next write will extend the file into a new block, | ||||
* and the file is currently composed of a fragment | * and the file is currently composed of a fragment | ||||
* this fragment has to be extended to be a full block. | * this fragment has to be extended to be a full block. | ||||
*/ | */ | ||||
lastlbn = lblkno(fs, ip->i_size); | lastlbn = lblkno(fs, ip->i_size); | ||||
if (lastlbn < NDADDR && lastlbn < lbn) { | if (lastlbn < UFS_NDADDR && lastlbn < lbn) { | ||||
nb = lastlbn; | nb = lastlbn; | ||||
osize = blksize(fs, ip, nb); | osize = blksize(fs, ip, nb); | ||||
if (osize < fs->fs_bsize && osize > 0) { | if (osize < fs->fs_bsize && osize > 0) { | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
error = ffs_realloccg(ip, nb, dp->di_db[nb], | error = ffs_realloccg(ip, nb, dp->di_db[nb], | ||||
ffs_blkpref_ufs1(ip, lastlbn, (int)nb, | ffs_blkpref_ufs1(ip, lastlbn, (int)nb, | ||||
&dp->di_db[0]), osize, (int)fs->fs_bsize, flags, | &dp->di_db[0]), osize, (int)fs->fs_bsize, flags, | ||||
cred, &bp); | cred, &bp); | ||||
Show All 11 Lines | if (osize < fs->fs_bsize && osize > 0) { | ||||
bwrite(bp); | bwrite(bp); | ||||
else if (DOINGASYNC(vp)) | else if (DOINGASYNC(vp)) | ||||
bdwrite(bp); | bdwrite(bp); | ||||
else | else | ||||
bawrite(bp); | bawrite(bp); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* The first NDADDR blocks are direct blocks | * The first UFS_NDADDR blocks are direct blocks | ||||
*/ | */ | ||||
if (lbn < NDADDR) { | if (lbn < UFS_NDADDR) { | ||||
if (flags & BA_METAONLY) | if (flags & BA_METAONLY) | ||||
panic("ffs_balloc_ufs1: BA_METAONLY for direct block"); | panic("ffs_balloc_ufs1: BA_METAONLY for direct block"); | ||||
nb = dp->di_db[lbn]; | nb = dp->di_db[lbn]; | ||||
if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { | if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { | ||||
error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); | error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp); | ||||
if (error) { | if (error) { | ||||
brelse(bp); | brelse(bp); | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | if (nb == 0) { | ||||
MPASS(allocblk < allociblk + nitems(allociblk)); | MPASS(allocblk < allociblk + nitems(allociblk)); | ||||
MPASS(lbns_remfree < lbns + nitems(lbns)); | MPASS(lbns_remfree < lbns + nitems(lbns)); | ||||
*allocblk++ = nb; | *allocblk++ = nb; | ||||
*lbns_remfree++ = indirs[1].in_lbn; | *lbns_remfree++ = indirs[1].in_lbn; | ||||
bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, gbflags); | bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, gbflags); | ||||
bp->b_blkno = fsbtodb(fs, nb); | bp->b_blkno = fsbtodb(fs, nb); | ||||
vfs_bio_clrbuf(bp); | vfs_bio_clrbuf(bp); | ||||
if (DOINGSOFTDEP(vp)) { | if (DOINGSOFTDEP(vp)) { | ||||
softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, | softdep_setup_allocdirect(ip, UFS_NDADDR + | ||||
newb, 0, fs->fs_bsize, 0, bp); | indirs[0].in_off, newb, 0, fs->fs_bsize, 0, bp); | ||||
bdwrite(bp); | bdwrite(bp); | ||||
} else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) { | } else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) { | ||||
if (bp->b_bufsize == fs->fs_bsize) | if (bp->b_bufsize == fs->fs_bsize) | ||||
bp->b_flags |= B_CLUSTEROK; | bp->b_flags |= B_CLUSTEROK; | ||||
bdwrite(bp); | bdwrite(bp); | ||||
} else { | } else { | ||||
if ((error = bwrite(bp)) != 0) | if ((error = bwrite(bp)) != 0) | ||||
goto fail; | goto fail; | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | if (nb == 0) { | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
/* | /* | ||||
* If allocating metadata at the front of the cylinder | * If allocating metadata at the front of the cylinder | ||||
* group and parent indirect block has just been allocated, | * group and parent indirect block has just been allocated, | ||||
* then cluster next to it if it is the first indirect in | * then cluster next to it if it is the first indirect in | ||||
* the file. Otherwise it has been allocated in the metadata | * the file. Otherwise it has been allocated in the metadata | ||||
* area, so we want to find our own place out in the data area. | * area, so we want to find our own place out in the data area. | ||||
*/ | */ | ||||
if (pref == 0 || (lbn > NDADDR && fs->fs_metaspace != 0)) | if (pref == 0 || (lbn > UFS_NDADDR && fs->fs_metaspace != 0)) | ||||
pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, | pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, | ||||
&bap[0]); | &bap[0]); | ||||
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, | error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, | ||||
flags | IO_BUFLOCKED, cred, &newb); | flags | IO_BUFLOCKED, cred, &newb); | ||||
if (error) { | if (error) { | ||||
brelse(bp); | brelse(bp); | ||||
if (DOINGSOFTDEP(vp) && ++reclaimed == 1) { | if (DOINGSOFTDEP(vp) && ++reclaimed == 1) { | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, | ||||
struct ucred *cred, int flags, struct buf **bpp) | struct ucred *cred, int flags, struct buf **bpp) | ||||
{ | { | ||||
struct inode *ip; | struct inode *ip; | ||||
struct ufs2_dinode *dp; | struct ufs2_dinode *dp; | ||||
ufs_lbn_t lbn, lastlbn; | ufs_lbn_t lbn, lastlbn; | ||||
struct fs *fs; | struct fs *fs; | ||||
struct buf *bp, *nbp; | struct buf *bp, *nbp; | ||||
struct ufsmount *ump; | struct ufsmount *ump; | ||||
struct indir indirs[NIADDR + 2]; | struct indir indirs[UFS_NIADDR + 2]; | ||||
ufs2_daddr_t nb, newb, *bap, pref; | ufs2_daddr_t nb, newb, *bap, pref; | ||||
ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; | ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[UFS_NIADDR + 1]; | ||||
ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1]; | ufs2_daddr_t *lbns_remfree, lbns[UFS_NIADDR + 1]; | ||||
int deallocated, osize, nsize, num, i, error; | int deallocated, osize, nsize, num, i, error; | ||||
int unwindidx = -1; | int unwindidx = -1; | ||||
int saved_inbdflush; | int saved_inbdflush; | ||||
static struct timeval lastfail; | static struct timeval lastfail; | ||||
static int curfail; | static int curfail; | ||||
int gbflags, reclaimed; | int gbflags, reclaimed; | ||||
ip = VTOI(vp); | ip = VTOI(vp); | ||||
Show All 12 Lines | ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, | ||||
if (DOINGSOFTDEP(vp)) | if (DOINGSOFTDEP(vp)) | ||||
softdep_prealloc(vp, MNT_WAIT); | softdep_prealloc(vp, MNT_WAIT); | ||||
/* | /* | ||||
* Check for allocating external data. | * Check for allocating external data. | ||||
*/ | */ | ||||
if (flags & IO_EXT) { | if (flags & IO_EXT) { | ||||
if (lbn >= NXADDR) | if (lbn >= UFS_NXADDR) | ||||
return (EFBIG); | return (EFBIG); | ||||
/* | /* | ||||
* If the next write will extend the data into a new block, | * If the next write will extend the data into a new block, | ||||
* and the data is currently composed of a fragment | * and the data is currently composed of a fragment | ||||
* this fragment has to be extended to be a full block. | * this fragment has to be extended to be a full block. | ||||
*/ | */ | ||||
lastlbn = lblkno(fs, dp->di_extsize); | lastlbn = lblkno(fs, dp->di_extsize); | ||||
if (lastlbn < lbn) { | if (lastlbn < lbn) { | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | if (flags & IO_EXT) { | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* If the next write will extend the file into a new block, | * If the next write will extend the file into a new block, | ||||
* and the file is currently composed of a fragment | * and the file is currently composed of a fragment | ||||
* this fragment has to be extended to be a full block. | * this fragment has to be extended to be a full block. | ||||
*/ | */ | ||||
lastlbn = lblkno(fs, ip->i_size); | lastlbn = lblkno(fs, ip->i_size); | ||||
if (lastlbn < NDADDR && lastlbn < lbn) { | if (lastlbn < UFS_NDADDR && lastlbn < lbn) { | ||||
nb = lastlbn; | nb = lastlbn; | ||||
osize = blksize(fs, ip, nb); | osize = blksize(fs, ip, nb); | ||||
if (osize < fs->fs_bsize && osize > 0) { | if (osize < fs->fs_bsize && osize > 0) { | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
error = ffs_realloccg(ip, nb, dp->di_db[nb], | error = ffs_realloccg(ip, nb, dp->di_db[nb], | ||||
ffs_blkpref_ufs2(ip, lastlbn, (int)nb, | ffs_blkpref_ufs2(ip, lastlbn, (int)nb, | ||||
&dp->di_db[0]), osize, (int)fs->fs_bsize, | &dp->di_db[0]), osize, (int)fs->fs_bsize, | ||||
flags, cred, &bp); | flags, cred, &bp); | ||||
Show All 10 Lines | if (osize < fs->fs_bsize && osize > 0) { | ||||
ip->i_flag |= IN_CHANGE | IN_UPDATE; | ip->i_flag |= IN_CHANGE | IN_UPDATE; | ||||
if (flags & IO_SYNC) | if (flags & IO_SYNC) | ||||
bwrite(bp); | bwrite(bp); | ||||
else | else | ||||
bawrite(bp); | bawrite(bp); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* The first NDADDR blocks are direct blocks | * The first UFS_NDADDR blocks are direct blocks | ||||
*/ | */ | ||||
if (lbn < NDADDR) { | if (lbn < UFS_NDADDR) { | ||||
if (flags & BA_METAONLY) | if (flags & BA_METAONLY) | ||||
panic("ffs_balloc_ufs2: BA_METAONLY for direct block"); | panic("ffs_balloc_ufs2: BA_METAONLY for direct block"); | ||||
nb = dp->di_db[lbn]; | nb = dp->di_db[lbn]; | ||||
if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { | if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) { | ||||
error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED, | error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED, | ||||
gbflags, &bp); | gbflags, &bp); | ||||
if (error) { | if (error) { | ||||
brelse(bp); | brelse(bp); | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | if (nb == 0) { | ||||
MPASS(lbns_remfree < lbns + nitems(lbns)); | MPASS(lbns_remfree < lbns + nitems(lbns)); | ||||
*allocblk++ = nb; | *allocblk++ = nb; | ||||
*lbns_remfree++ = indirs[1].in_lbn; | *lbns_remfree++ = indirs[1].in_lbn; | ||||
bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, | bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, | ||||
GB_UNMAPPED); | GB_UNMAPPED); | ||||
bp->b_blkno = fsbtodb(fs, nb); | bp->b_blkno = fsbtodb(fs, nb); | ||||
vfs_bio_clrbuf(bp); | vfs_bio_clrbuf(bp); | ||||
if (DOINGSOFTDEP(vp)) { | if (DOINGSOFTDEP(vp)) { | ||||
softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, | softdep_setup_allocdirect(ip, UFS_NDADDR + | ||||
newb, 0, fs->fs_bsize, 0, bp); | indirs[0].in_off, newb, 0, fs->fs_bsize, 0, bp); | ||||
bdwrite(bp); | bdwrite(bp); | ||||
} else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) { | } else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) { | ||||
if (bp->b_bufsize == fs->fs_bsize) | if (bp->b_bufsize == fs->fs_bsize) | ||||
bp->b_flags |= B_CLUSTEROK; | bp->b_flags |= B_CLUSTEROK; | ||||
bdwrite(bp); | bdwrite(bp); | ||||
} else { | } else { | ||||
if ((error = bwrite(bp)) != 0) | if ((error = bwrite(bp)) != 0) | ||||
goto fail; | goto fail; | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | if (nb == 0) { | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
/* | /* | ||||
* If allocating metadata at the front of the cylinder | * If allocating metadata at the front of the cylinder | ||||
* group and parent indirect block has just been allocated, | * group and parent indirect block has just been allocated, | ||||
* then cluster next to it if it is the first indirect in | * then cluster next to it if it is the first indirect in | ||||
* the file. Otherwise it has been allocated in the metadata | * the file. Otherwise it has been allocated in the metadata | ||||
* area, so we want to find our own place out in the data area. | * area, so we want to find our own place out in the data area. | ||||
*/ | */ | ||||
if (pref == 0 || (lbn > NDADDR && fs->fs_metaspace != 0)) | if (pref == 0 || (lbn > UFS_NDADDR && fs->fs_metaspace != 0)) | ||||
pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, | pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, | ||||
&bap[0]); | &bap[0]); | ||||
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, | error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, | ||||
flags | IO_BUFLOCKED, cred, &newb); | flags | IO_BUFLOCKED, cred, &newb); | ||||
if (error) { | if (error) { | ||||
brelse(bp); | brelse(bp); | ||||
if (DOINGSOFTDEP(vp) && ++reclaimed == 1) { | if (DOINGSOFTDEP(vp) && ++reclaimed == 1) { | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
▲ Show 20 Lines • Show All 167 Lines • Show Last 20 Lines |