Remove XXXUBC code for ffs_reallocblks, that has been conditionalized in

2002 and #if 0'ed in 2005. It would need a considerable amount of work
to bring back and obscures the more important block allocation.
This commit is contained in:
joerg 2008-11-06 22:31:08 +00:00
parent a74f73830c
commit ecbfc2933c
2 changed files with 3 additions and 440 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_alloc.c,v 1.113 2008/08/06 12:54:26 hannken Exp $ */
/* $NetBSD: ffs_alloc.c,v 1.114 2008/11/06 22:31:08 joerg Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.113 2008/08/06 12:54:26 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.114 2008/11/06 22:31:08 joerg Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -102,9 +102,6 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.113 2008/08/06 12:54:26 hannken Exp
static daddr_t ffs_alloccg(struct inode *, int, daddr_t, int, int);
static daddr_t ffs_alloccgblk(struct inode *, struct buf *, daddr_t, int);
#ifdef XXXUBC
static daddr_t ffs_clusteralloc(struct inode *, int, daddr_t, int);
#endif
static ino_t ffs_dirpref(struct inode *);
static daddr_t ffs_fragextend(struct inode *, int, daddr_t, int, int);
static void ffs_fserr(struct fs *, u_int, const char *);
@ -113,11 +110,6 @@ static daddr_t ffs_hashalloc(struct inode *, int, daddr_t, int, int,
static daddr_t ffs_nodealloccg(struct inode *, int, daddr_t, int, int);
static int32_t ffs_mapsearch(struct fs *, struct cg *,
daddr_t, int);
#if defined(DIAGNOSTIC) || defined(DEBUG)
#ifdef XXXUBC
static int ffs_checkblk(struct inode *, daddr_t, long size);
#endif
#endif
/* if 1, changes in optimalization strategy are logged */
int ffs_log_changeopt = 0;
@ -480,255 +472,6 @@ nospace:
return (ENOSPC);
}
#if 0
/*
* Reallocate a sequence of blocks into a contiguous sequence of blocks.
*
* The vnode and an array of buffer pointers for a range of sequential
* logical blocks to be made contiguous is given. The allocator attempts
* to find a range of sequential blocks starting as close as possible
* from the end of the allocation for the logical block immediately
* preceding the current range. If successful, the physical block numbers
* in the buffer pointers and in the inode are changed to reflect the new
* allocation. If unsuccessful, the allocation is left unchanged. The
* success in doing the reallocation is returned. Note that the error
* return is not reflected back to the user. Rather the previous block
* allocation will be used.
*/
#ifdef XXXUBC
#ifdef DEBUG
#include <sys/sysctl.h>
int prtrealloc = 0;
struct ctldebug debug15 = { "prtrealloc", &prtrealloc };
#endif
#endif
/*
* NOTE: when re-enabling this, it must be updated for UFS2 and WAPBL.
*/
int doasyncfree = 1;
int
ffs_reallocblks(void *v)
{
#ifdef XXXUBC
struct vop_reallocblks_args /* {
struct vnode *a_vp;
struct cluster_save *a_buflist;
} */ *ap = v;
struct fs *fs;
struct inode *ip;
struct vnode *vp;
struct buf *sbp, *ebp;
int32_t *bap, *ebap = NULL, *sbap; /* XXX ondisk32 */
struct cluster_save *buflist;
daddr_t start_lbn, end_lbn, soff, newblk, blkno;
struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
int i, len, start_lvl, end_lvl, pref, ssize;
struct ufsmount *ump;
#endif /* XXXUBC */
/* XXXUBC don't reallocblks for now */
return ENOSPC;
#ifdef XXXUBC
vp = ap->a_vp;
ip = VTOI(vp);
fs = ip->i_fs;
ump = ip->i_ump;
if (fs->fs_contigsumsize <= 0)
return (ENOSPC);
buflist = ap->a_buflist;
len = buflist->bs_nchildren;
start_lbn = buflist->bs_children[0]->b_lblkno;
end_lbn = start_lbn + len - 1;
#ifdef DIAGNOSTIC
for (i = 0; i < len; i++)
if (!ffs_checkblk(ip,
dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
panic("ffs_reallocblks: unallocated block 1");
for (i = 1; i < len; i++)
if (buflist->bs_children[i]->b_lblkno != start_lbn + i)
panic("ffs_reallocblks: non-logical cluster");
blkno = buflist->bs_children[0]->b_blkno;
ssize = fsbtodb(fs, fs->fs_frag);
for (i = 1; i < len - 1; i++)
if (buflist->bs_children[i]->b_blkno != blkno + (i * ssize))
panic("ffs_reallocblks: non-physical cluster %d", i);
#endif
/*
* If the latest allocation is in a new cylinder group, assume that
* the filesystem has decided to move and do not force it back to
* the previous cylinder group.
*/
if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) !=
dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno)))
return (ENOSPC);
if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) ||
ufs_getlbns(vp, end_lbn, end_ap, &end_lvl))
return (ENOSPC);
/*
* Get the starting offset and block map for the first block.
*/
if (start_lvl == 0) {
sbap = &ip->i_ffs1_db[0];
soff = start_lbn;
} else {
idp = &start_ap[start_lvl - 1];
if (bread(vp, idp->in_lbn, (int)fs->fs_bsize,
NOCRED, B_MODIFY, &sbp)) {
brelse(sbp, 0);
return (ENOSPC);
}
sbap = (int32_t *)sbp->b_data;
soff = idp->in_off;
}
/*
* Find the preferred location for the cluster.
*/
mutex_enter(&ump->um_lock);
pref = ffs_blkpref(ip, start_lbn, soff, sbap);
/*
* If the block range spans two block maps, get the second map.
*/
if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {
ssize = len;
} else {
#ifdef DIAGNOSTIC
if (start_ap[start_lvl-1].in_lbn == idp->in_lbn)
panic("ffs_reallocblk: start == end");
#endif
ssize = len - (idp->in_off + 1);
if (bread(vp, idp->in_lbn, (int)fs->fs_bsize,
NOCRED, B_MODIFY, &ebp))
goto fail;
ebap = (int32_t *)ebp->b_data; /* XXX ondisk32 */
}
/*
* Search the block map looking for an allocation of the desired size.
*/
if ((newblk = (daddr_t)ffs_hashalloc(ip, dtog(fs, pref), (long)pref,
len, flags, ffs_clusteralloc)) == 0) {
mutex_exit(&ump->um_lock);
goto fail;
}
/*
* We have found a new contiguous block.
*
* First we have to replace the old block pointers with the new
* block pointers in the inode and indirect blocks associated
* with the file.
*/
#ifdef DEBUG
if (prtrealloc)
printf("realloc: ino %d, lbns %d-%d\n\told:", ip->i_number,
start_lbn, end_lbn);
#endif
blkno = newblk;
for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) {
daddr_t ba;
if (i == ssize) {
bap = ebap;
soff = -i;
}
/* XXX ondisk32 */
ba = ufs_rw32(*bap, UFS_FSNEEDSWAP(fs));
#ifdef DIAGNOSTIC
if (!ffs_checkblk(ip,
dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
panic("ffs_reallocblks: unallocated block 2");
if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != ba)
panic("ffs_reallocblks: alloc mismatch");
#endif
#ifdef DEBUG
if (prtrealloc)
printf(" %d,", ba);
#endif
if (DOINGSOFTDEP(vp)) {
if (sbap == &ip->i_ffs1_db[0] && i < ssize)
softdep_setup_allocdirect(ip, start_lbn + i,
blkno, ba, fs->fs_bsize, fs->fs_bsize,
buflist->bs_children[i]);
else
softdep_setup_allocindir_page(ip, start_lbn + i,
i < ssize ? sbp : ebp, soff + i, blkno,
ba, buflist->bs_children[i]);
}
/* XXX ondisk32 */
*bap++ = ufs_rw32((u_int32_t)blkno, UFS_FSNEEDSWAP(fs));
}
/*
* Next we must write out the modified inode and indirect blocks.
* For strict correctness, the writes should be synchronous since
* the old block values may have been written to disk. In practise
* they are almost never written, but if we are concerned about
* strict correctness, the `doasyncfree' flag should be set to zero.
*
* The test on `doasyncfree' should be changed to test a flag
* that shows whether the associated buffers and inodes have
* been written. The flag should be set when the cluster is
* started and cleared whenever the buffer or inode is flushed.
* We can then check below to see if it is set, and do the
* synchronous write only when it has been cleared.
*/
if (sbap != &ip->i_ffs1_db[0]) {
if (doasyncfree)
bdwrite(sbp);
else
bwrite(sbp);
} else {
ip->i_flag |= IN_CHANGE | IN_UPDATE;
if (!doasyncfree)
ffs_update(vp, NULL, NULL, 1);
}
if (ssize < len) {
if (doasyncfree)
bdwrite(ebp);
else
bwrite(ebp);
}
/*
* Last, free the old blocks and assign the new blocks to the buffers.
*/
#ifdef DEBUG
if (prtrealloc)
printf("\n\tnew:");
#endif
for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
if (!DOINGSOFTDEP(vp))
ffs_blkfree(fs, ip->i_devvp,
dbtofsb(fs, buflist->bs_children[i]->b_blkno),
fs->fs_bsize, ip->i_number);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
#ifdef DEBUG
if (!ffs_checkblk(ip,
dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
panic("ffs_reallocblks: unallocated block 3");
if (prtrealloc)
printf(" %d,", blkno);
#endif
}
#ifdef DEBUG
if (prtrealloc) {
prtrealloc--;
printf("\n");
}
#endif
return (0);
fail:
if (ssize < len)
brelse(ebp, 0);
if (sbap != &ip->i_ffs1_db[0])
brelse(sbp, 0);
return (ENOSPC);
#endif /* XXXUBC */
}
#endif /* 0 */
/*
* Allocate an inode in the file system.
*
@ -1467,132 +1210,6 @@ gotit:
return (blkno);
}
#ifdef XXXUBC
/*
* Determine whether a cluster can be allocated.
*
* We do not currently check for optimal rotational layout if there
* are multiple choices in the same cylinder group. Instead we just
* take the first one that we find following bpref.
*/
/*
* This function must be fixed for UFS2 if re-enabled.
*/
static daddr_t
ffs_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len)
{
struct ufsmount *ump;
struct fs *fs;
struct cg *cgp;
struct buf *bp;
int i, got, run, bno, bit, map;
u_char *mapp;
int32_t *lp;
fs = ip->i_fs;
ump = ip->i_ump;
KASSERT(mutex_owned(&ump->um_lock));
if (fs->fs_maxcluster[cg] < len)
return (0);
mutex_exit(&ump->um_lock);
if (bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
NOCRED, 0, &bp))
goto fail;
cgp = (struct cg *)bp->b_data;
if (!cg_chkmagic(cgp, UFS_FSNEEDSWAP(fs)))
goto fail;
/*
* Check to see if a cluster of the needed size (or bigger) is
* available in this cylinder group.
*/
lp = &cg_clustersum(cgp, UFS_FSNEEDSWAP(fs))[len];
for (i = len; i <= fs->fs_contigsumsize; i++)
if (ufs_rw32(*lp++, UFS_FSNEEDSWAP(fs)) > 0)
break;
if (i > fs->fs_contigsumsize) {
/*
* This is the first time looking for a cluster in this
* cylinder group. Update the cluster summary information
* to reflect the true maximum sized cluster so that
* future cluster allocation requests can avoid reading
* the cylinder group map only to find no clusters.
*/
lp = &cg_clustersum(cgp, UFS_FSNEEDSWAP(fs))[len - 1];
for (i = len - 1; i > 0; i--)
if (ufs_rw32(*lp--, UFS_FSNEEDSWAP(fs)) > 0)
break;
mutex_enter(&ump->um_lock);
fs->fs_maxcluster[cg] = i;
mutex_exit(&ump->um_lock);
goto fail;
}
/*
* Search the cluster map to find a big enough cluster.
* We take the first one that we find, even if it is larger
* than we need as we prefer to get one close to the previous
* block allocation. We do not search before the current
* preference point as we do not want to allocate a block
* that is allocated before the previous one (as we will
* then have to wait for another pass of the elevator
* algorithm before it will be read). We prefer to fail and
* be recalled to try an allocation in the next cylinder group.
*/
if (dtog(fs, bpref) != cg)
bpref = 0;
else
bpref = fragstoblks(fs, dtogd(fs, blknum(fs, bpref)));
mapp = &cg_clustersfree(cgp, UFS_FSNEEDSWAP(fs))[bpref / NBBY];
map = *mapp++;
bit = 1 << (bpref % NBBY);
for (run = 0, got = bpref;
got < ufs_rw32(cgp->cg_nclusterblks, UFS_FSNEEDSWAP(fs)); got++) {
if ((map & bit) == 0) {
run = 0;
} else {
run++;
if (run == len)
break;
}
if ((got & (NBBY - 1)) != (NBBY - 1)) {
bit <<= 1;
} else {
map = *mapp++;
bit = 1;
}
}
if (got == ufs_rw32(cgp->cg_nclusterblks, UFS_FSNEEDSWAP(fs)))
goto fail;
/*
* Allocate the cluster that we have found.
*/
#ifdef DIAGNOSTIC
for (i = 1; i <= len; i++)
if (!ffs_isblock(fs, cg_blksfree(cgp, UFS_FSNEEDSWAP(fs)),
got - run + i))
panic("ffs_clusteralloc: map mismatch");
#endif
bno = cg * fs->fs_fpg + blkstofrags(fs, got - run + 1);
if (dtog(fs, bno) != cg)
panic("ffs_clusteralloc: allocated out of group");
len = blkstofrags(fs, len);
mutex_enter(&ump->um_lock);
for (i = 0; i < len; i += fs->fs_frag)
if ((got = ffs_alloccgblk(ip, bp, bno + i, flags)) != bno + i)
panic("ffs_clusteralloc: lost block");
ACTIVECG_CLR(fs, cg);
mutex_exit(&ump->um_lock);
bdwrite(bp);
return (bno);
fail:
brelse(bp, 0);
mutex_enter(&ump->um_lock);
return (0);
}
#endif /* XXXUBC */
/*
* Determine whether an inode can be allocated.
*
@ -2026,57 +1643,6 @@ ffs_blkfree(struct fs *fs, struct vnode *devvp, daddr_t bno, long size,
bdwrite(bp);
}
#if defined(DIAGNOSTIC) || defined(DEBUG)
#ifdef XXXUBC
/*
* Verify allocation of a block or fragment. Returns true if block or
* fragment is allocated, false if it is free.
*/
static int
ffs_checkblk(struct inode *ip, daddr_t bno, long size)
{
struct fs *fs;
struct cg *cgp;
struct buf *bp;
int i, error, frags, free;
fs = ip->i_fs;
if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
printf("bsize = %d, size = %ld, fs = %s\n",
fs->fs_bsize, size, fs->fs_fsmnt);
panic("checkblk: bad size");
}
if (bno >= fs->fs_size)
panic("checkblk: bad block %d", bno);
error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, dtog(fs, bno))),
(int)fs->fs_cgsize, NOCRED, 0, &bp);
if (error) {
brelse(bp, 0);
return 0;
}
cgp = (struct cg *)bp->b_data;
if (!cg_chkmagic(cgp, UFS_FSNEEDSWAP(fs))) {
brelse(bp, 0);
return 0;
}
bno = dtogd(fs, bno);
if (size == fs->fs_bsize) {
free = ffs_isblock(fs, cg_blksfree(cgp, UFS_FSNEEDSWAP(fs)),
fragstoblks(fs, bno));
} else {
frags = numfrags(fs, size);
for (free = 0, i = 0; i < frags; i++)
if (isset(cg_blksfree(cgp, UFS_FSNEEDSWAP(fs)), bno + i))
free++;
if (free != 0 && free != frags)
panic("checkblk: partially free fragment");
}
brelse(bp, 0);
return (!free);
}
#endif /* XXXUBC */
#endif /* DIAGNOSTIC */
/*
* Free an inode.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_extern.h,v 1.70 2008/10/10 09:21:58 hannken Exp $ */
/* $NetBSD: ffs_extern.h,v 1.71 2008/11/06 22:31:08 joerg Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -91,9 +91,6 @@ int ffs_alloc(struct inode *, daddr_t, daddr_t , int, int, kauth_cred_t,
daddr_t *);
int ffs_realloccg(struct inode *, daddr_t, daddr_t, int, int ,
kauth_cred_t, struct buf **, daddr_t *);
#if 0
int ffs_reallocblks(void *);
#endif
int ffs_valloc(struct vnode *, int, kauth_cred_t, struct vnode **);
daddr_t ffs_blkpref_ufs1(struct inode *, daddr_t, int, int, int32_t *);
daddr_t ffs_blkpref_ufs2(struct inode *, daddr_t, int, int, int64_t *);