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