PERFORCE change 188181 for review
Zheng Liu
lz at FreeBSD.org
Wed Jan 26 04:05:43 UTC 2011
http://p4web.freebsd.org/@@188181?ac=10
Change 188181 by lz at gnehzuil-freebsd on 2011/01/26 04:05:10
Add ext2_clusteralloc() function.
Affected files ...
.. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#31 edit
Differences ...
==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#31 (text+ko) ====
@@ -53,6 +53,8 @@
#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/ext2_rsv_win.h>
+#define FANCY_REALLOC 1
+
#define phy_blk(cg, fs) (((cg) * (fs->e2fs->e2fs_fpg)) + fs->e2fs->e2fs_first_dblock)
static daddr_t ext2_alloccg(struct inode *, int, daddr_t, int);
@@ -64,6 +66,11 @@
static daddr_t ext2_nodealloccg(struct inode *, int, daddr_t, int);
static daddr_t ext2_mapsearch(struct m_ext2fs *, char *, daddr_t);
+/* For reallocblks */
+#ifdef FANCY_REALLOC
+static daddr_t ext2_clusteralloc(struct inode *, int, daddr_t, int);
+#endif
+
/* For reservation window */
static u_long ext2_alloc_blk(struct inode *, int, struct buf *, int32_t, struct ext2_rsv_win *);
static int ext2_alloc_new_rsv(struct inode *, int, struct buf *, int32_t);
@@ -94,7 +101,7 @@
SYSCTL_NODE(_vfs, OID_AUTO, ext2fs, CTLFLAG_RW, 0, "EXT2FS filesystem");
-static int rsv = 1;
+static int rsv = 0;
SYSCTL_INT(_vfs_ext2fs, OID_AUTO, rsv, CTLFLAG_RW, &rsv, 0, "");
static int rsv_winsize = 8;
@@ -667,13 +674,15 @@
*/
#ifdef FANCY_REALLOC
-#include <sys/sysctl.h>
+
static int doasyncfree = 1;
+
+SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0,
+ "Use asychronous writes to update block pointers when freeing blocks");
+
static int doreallocblks = 1;
-#ifdef OPT_DEBUG
-SYSCTL_INT(_debug, 14, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "");
-#endif /* OPT_DEBUG */
+SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0, "");
#endif
int
@@ -840,6 +849,80 @@
#endif /* FANCY_REALLOC */
}
+static daddr_t
+ext2_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len)
+{
+ struct m_ext2fs *fs;
+ struct ext2mount *ump;
+ struct buf *bp;
+ int error, i, got, run;
+ char *bbp;
+ daddr_t bno;
+
+ fs = ip->i_e2fs;
+ ump = ip->i_ump;
+
+ /*
+ * TODO: we need to define a new member in m_ext2fs structure
+ * to save max cluster. But for simplicity, we assume that the
+ * max cluster is equal to the number of blocks per group.
+ */
+ if (fs->e2fs_gd[cg].ext2bgd_nbfree < len)
+ return (0);
+
+ EXT2_UNLOCK(ump);
+ error = bread(ip->i_devvp,
+ fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_b_bitmap),
+ (int)fs->e2fs_bsize, NOCRED, &bp);
+ if (error)
+ goto fail_lock;
+
+ bbp = (char *)bp->b_data;
+ bp->b_xflags |= BX_BKGRDWRITE;
+
+ /*
+ * TODO: check to see if a cluster of the needed size is
+ * available in this cg.
+ */
+
+ if (dtog(fs, bpref) != cg)
+ bpref = 0;
+ else
+ bpref = dtogd(fs, bpref);
+
+ for (run = 0, got = bpref; got < fs->e2fs_bpg; got++) {
+ if (!isclr(bbp, got))
+ run = 0;
+ else {
+ run++;
+ if (run == len)
+ break;
+ }
+ }
+
+ if (got >= fs->e2fs_bpg)
+ goto fail_lock;
+
+ for (i = 1; i <= len; i++)
+ if (!isclr(bbp, got - run + i))
+ panic("ext2_clusteralloc: map mismatch");
+ bno = got - run + 1;
+ if (bno >= fs->e2fs_bpg)
+ panic("ext2_clusteralloc: allocated out of group");
+
+ for (i = 0; i < len; i++)
+ setbit(bbp, (daddr_t)bno + i);
+
+ bdwrite(bp);
+
+ return (phy_blk(cg, fs) + bno);
+
+fail_lock:
+ EXT2_LOCK(ump);
+ brelse(bp);
+ return (0);
+}
+
/*
* Allocate an inode in the file system.
*
@@ -1148,7 +1231,10 @@
struct m_ext2fs *fs;
struct buf *bp;
struct ext2mount *ump;
- int error, bno, start, end, loc;
+ /*daddr_t bno, runstart, runlen;*/
+ /*int bit, loc, end, error, start;*/
+ daddr_t bno;
+ int error;
char *bbp;
/* XXX ondisk32 */
fs = ip->i_e2fs;
@@ -1184,23 +1270,59 @@
* first try to get 8 contigous blocks, then fall back to a single
* block.
*/
+#if 0
if (bpref)
start = dtogd(fs, bpref) / NBBY;
else
start = 0;
end = howmany(fs->e2fs->e2fs_fpg, NBBY) - start;
- for (loc = start; loc < end; loc++) {
- if (bbp[loc] == 0) {
- bno = loc * NBBY;
- goto gotit;
- }
- }
- for (loc = 0; loc < start; loc++) {
- if (bbp[loc] == 0) {
- bno = loc * NBBY;
- goto gotit;
- }
- }
+retry:
+ runlen = 0;
+ runstart = 0;
+ for (loc = start; loc < end; loc++) {
+ if (bbp[loc] == (char)0xff) {
+ runlen = 0;
+ continue;
+ }
+
+ /* Start of a run, find the number of high clear bits. */
+ if (runlen == 0) {
+ bit = fls(bbp[loc]);
+ runlen = NBBY - bit;
+ runstart = loc * NBBY + bit;
+ } else if (bbp[loc] == 0) {
+ /* Contunue a run. */
+ runlen += NBBY;
+ } else {
+ /*
+ * Finish the current run. If it isn't long
+ * enough, start a new one.
+ */
+ bit = fls(bbp[loc]) - 1;
+ runlen += bit;
+ if (runlen >= 8) {
+ bno = runstart;
+ goto gotit;
+ }
+
+ /* Run was too short, start a new one. */
+ bit = fls(bbp[loc]);
+ runlen = NBBY - bit;
+ runstart = loc * NBBY + bit;
+ }
+
+ /* If the current run is long enough, use it. */
+ if (runlen >= 8) {
+ bno = runstart;
+ goto gotit;
+ }
+ }
+ if (start != 0) {
+ end = start;
+ start = 0;
+ goto retry;
+ }
+#endif /* 0 */
bno = ext2_mapsearch(fs, bbp, bpref);
if (bno < 0){
@@ -1433,11 +1555,14 @@
loc = skpc(0xff, len, &bbp[start]);
if (loc == 0) {
/* XXX: just for reservation window */
- return -1;
- /*printf("start = %d, len = %d, fs = %s\n",*/
- /*start, len, fs->e2fs_fsmnt);*/
- /*panic("ext2fs_alloccg: map corrupted");*/
- /* NOTREACHED */
+ if (rsv == 1)
+ return (-1);
+ else {
+ printf("start = %d, len = %d, fs = %s\n",
+ start, len, fs->e2fs_fsmnt);
+ panic("ext2fs_alloccg: map corrupted");
+ /* NOTREACHED */
+ }
}
}
i = start + len - loc;
More information about the p4-projects
mailing list