浏览代码

Merge head 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6

Linus Torvalds 20 年之前
父节点
当前提交
49302d0c42
共有 4 个文件被更改,包括 42 次插入31 次删除
  1. 30 16
      fs/jfs/jfs_dmap.c
  2. 9 4
      fs/jfs/jfs_dtree.c
  3. 2 1
      fs/jfs/jfs_logmgr.c
  4. 1 10
      fs/jfs/jfs_metapage.c

+ 30 - 16
fs/jfs/jfs_dmap.c

@@ -75,7 +75,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 			int nblocks);
 			int nblocks);
 static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
 static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
 static void dbBackSplit(dmtree_t * tp, int leafno);
 static void dbBackSplit(dmtree_t * tp, int leafno);
-static void dbJoin(dmtree_t * tp, int leafno, int newval);
+static int dbJoin(dmtree_t * tp, int leafno, int newval);
 static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
 static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
 static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
 static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
 		    int level);
 		    int level);
@@ -98,8 +98,8 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
 static int dbFindBits(u32 word, int l2nb);
 static int dbFindBits(u32 word, int l2nb);
 static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
 static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
-static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
-		       int nblocks);
+static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		      int nblocks);
 static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 		      int nblocks);
 		      int nblocks);
 static int dbMaxBud(u8 * cp);
 static int dbMaxBud(u8 * cp);
@@ -378,6 +378,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
 
 
 		/* free the blocks. */
 		/* free the blocks. */
 		if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) {
 		if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) {
+			jfs_error(ip->i_sb, "dbFree: error in block map\n");
 			release_metapage(mp);
 			release_metapage(mp);
 			IREAD_UNLOCK(ipbmap);
 			IREAD_UNLOCK(ipbmap);
 			return (rc);
 			return (rc);
@@ -2020,7 +2021,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 		      int nblocks)
 		      int nblocks)
 {
 {
 	s8 oldroot;
 	s8 oldroot;
-	int rc, word;
+	int rc = 0, word;
 
 
 	/* save the current value of the root (i.e. maximum free string)
 	/* save the current value of the root (i.e. maximum free string)
 	 * of the dmap tree.
 	 * of the dmap tree.
@@ -2028,11 +2029,11 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 	oldroot = dp->tree.stree[ROOT];
 	oldroot = dp->tree.stree[ROOT];
 
 
 	/* free the specified (blocks) bits */
 	/* free the specified (blocks) bits */
-	dbFreeBits(bmp, dp, blkno, nblocks);
+	rc = dbFreeBits(bmp, dp, blkno, nblocks);
 
 
-	/* if the root has not changed, done. */
-	if (dp->tree.stree[ROOT] == oldroot)
-		return (0);
+	/* if error or the root has not changed, done. */
+	if (rc || (dp->tree.stree[ROOT] == oldroot))
+		return (rc);
 
 
 	/* root changed. bubble the change up to the dmap control pages.
 	/* root changed. bubble the change up to the dmap control pages.
 	 * if the adjustment of the upper level control pages fails,
 	 * if the adjustment of the upper level control pages fails,
@@ -2221,15 +2222,16 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *      blkno	-  starting block number of the bits to be freed.
  *      blkno	-  starting block number of the bits to be freed.
  *      nblocks	-  number of bits to be freed.
  *      nblocks	-  number of bits to be freed.
  *
  *
- * RETURN VALUES: none
+ * RETURN VALUES: 0 for success
  *
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
  */
-static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 		       int nblocks)
 		       int nblocks)
 {
 {
 	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
 	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
 	dmtree_t *tp = (dmtree_t *) & dp->tree;
 	dmtree_t *tp = (dmtree_t *) & dp->tree;
+	int rc = 0;
 	int size;
 	int size;
 
 
 	/* determine the bit number and word within the dmap of the
 	/* determine the bit number and word within the dmap of the
@@ -2278,8 +2280,10 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
 
 			/* update the leaf for this dmap word.
 			/* update the leaf for this dmap word.
 			 */
 			 */
-			dbJoin(tp, word,
-			       dbMaxBud((u8 *) & dp->wmap[word]));
+			rc = dbJoin(tp, word,
+				    dbMaxBud((u8 *) & dp->wmap[word]));
+			if (rc)
+				return rc;
 
 
 			word += 1;
 			word += 1;
 		} else {
 		} else {
@@ -2310,7 +2314,9 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
 
 				/* update the leaf.
 				/* update the leaf.
 				 */
 				 */
-				dbJoin(tp, word, size);
+				rc = dbJoin(tp, word, size);
+				if (rc)
+					return rc;
 
 
 				/* get the number of dmap words handled.
 				/* get the number of dmap words handled.
 				 */
 				 */
@@ -2357,6 +2363,8 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 	}
 	}
 
 
 	BMAP_UNLOCK(bmp);
 	BMAP_UNLOCK(bmp);
+
+	return 0;
 }
 }
 
 
 
 
@@ -2464,7 +2472,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
 		}
 		}
 		dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
 		dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
 	} else {
 	} else {
-		dbJoin((dmtree_t *) dcp, leafno, newval);
+		rc = dbJoin((dmtree_t *) dcp, leafno, newval);
+		if (rc)
+			return rc;
 	}
 	}
 
 
 	/* check if the root of the current dmap control page changed due
 	/* check if the root of the current dmap control page changed due
@@ -2689,7 +2699,7 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
  *
  *
  * RETURN VALUES: none
  * RETURN VALUES: none
  */
  */
-static void dbJoin(dmtree_t * tp, int leafno, int newval)
+static int dbJoin(dmtree_t * tp, int leafno, int newval)
 {
 {
 	int budsz, buddy;
 	int budsz, buddy;
 	s8 *leaf;
 	s8 *leaf;
@@ -2729,7 +2739,9 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval)
 			if (newval > leaf[buddy])
 			if (newval > leaf[buddy])
 				break;
 				break;
 
 
-			assert(newval == leaf[buddy]);
+			/* It shouldn't be less */
+			if (newval < leaf[buddy])
+				return -EIO;
 
 
 			/* check which (leafno or buddy) is the left buddy.
 			/* check which (leafno or buddy) is the left buddy.
 			 * the left buddy gets to claim the blocks resulting
 			 * the left buddy gets to claim the blocks resulting
@@ -2761,6 +2773,8 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval)
 	/* update the leaf value.
 	/* update the leaf value.
 	 */
 	 */
 	dbAdjTree(tp, leafno, newval);
 	dbAdjTree(tp, leafno, newval);
+
+	return 0;
 }
 }
 
 
 
 

+ 9 - 4
fs/jfs/jfs_dtree.c

@@ -381,9 +381,12 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
 		 * It's time to move the inline table to an external
 		 * It's time to move the inline table to an external
 		 * page and begin to build the xtree
 		 * page and begin to build the xtree
 		 */
 		 */
-		if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage) ||
-		    dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
-			goto clean_up;	/* No space */
+		if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
+			goto clean_up;
+		if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
+			DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
+			goto clean_up;
+		}
 
 
 		/*
 		/*
 		 * Save the table, we're going to overwrite it with the
 		 * Save the table, we're going to overwrite it with the
@@ -397,13 +400,15 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
 		xtInitRoot(tid, ip);
 		xtInitRoot(tid, ip);
 
 
 		/*
 		/*
-		 * Allocate the first block & add it to the xtree
+		 * Add the first block to the xtree
 		 */
 		 */
 		if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
 		if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
 			/* This really shouldn't fail */
 			/* This really shouldn't fail */
 			jfs_warn("add_index: xtInsert failed!");
 			jfs_warn("add_index: xtInsert failed!");
 			memcpy(&jfs_ip->i_dirtable, temp_table,
 			memcpy(&jfs_ip->i_dirtable, temp_table,
 			       sizeof (temp_table));
 			       sizeof (temp_table));
+			dbFree(ip, xaddr, sbi->nbperpage);
+			DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
 			goto clean_up;
 			goto clean_up;
 		}
 		}
 		ip->i_size = PSIZE;
 		ip->i_size = PSIZE;

+ 2 - 1
fs/jfs/jfs_logmgr.c

@@ -1030,7 +1030,8 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
 	 * starting until all current transactions are completed
 	 * starting until all current transactions are completed
 	 * by setting syncbarrier flag.
 	 * by setting syncbarrier flag.
 	 */
 	 */
-	if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) {
+	if (!test_bit(log_SYNCBARRIER, &log->flag) &&
+	    (written > LOGSYNC_BARRIER(logsize)) && log->active) {
 		set_bit(log_SYNCBARRIER, &log->flag);
 		set_bit(log_SYNCBARRIER, &log->flag);
 		jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn,
 		jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn,
 			 log->syncpt);
 			 log->syncpt);

+ 1 - 10
fs/jfs/jfs_metapage.c

@@ -561,7 +561,6 @@ static int metapage_releasepage(struct page *page, int gfp_mask)
 			dump_mem("page", page, sizeof(struct page));
 			dump_mem("page", page, sizeof(struct page));
 			dump_stack();
 			dump_stack();
 		}
 		}
-		WARN_ON(mp->lsn);
 		if (mp->lsn)
 		if (mp->lsn)
 			remove_from_logsync(mp);
 			remove_from_logsync(mp);
 		remove_metapage(page, mp);
 		remove_metapage(page, mp);
@@ -641,7 +640,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
 	} else {
 	} else {
 		page = read_cache_page(mapping, page_index,
 		page = read_cache_page(mapping, page_index,
 			    (filler_t *)mapping->a_ops->readpage, NULL);
 			    (filler_t *)mapping->a_ops->readpage, NULL);
-		if (IS_ERR(page)) {
+		if (IS_ERR(page) || !PageUptodate(page)) {
 			jfs_err("read_cache_page failed!");
 			jfs_err("read_cache_page failed!");
 			return NULL;
 			return NULL;
 		}
 		}
@@ -783,14 +782,6 @@ void release_metapage(struct metapage * mp)
 	if (test_bit(META_discard, &mp->flag) && !mp->count) {
 	if (test_bit(META_discard, &mp->flag) && !mp->count) {
 		clear_page_dirty(page);
 		clear_page_dirty(page);
 		ClearPageUptodate(page);
 		ClearPageUptodate(page);
-#ifdef _NOT_YET
-		if (page->mapping) {
-		/* Remove from page cache and page cache reference */
-			remove_from_page_cache(page);
-			page_cache_release(page);
-			metapage_releasepage(page, 0);
-		}
-#endif
 	}
 	}
 #else
 #else
 	/* Try to keep metapages from using up too much memory */
 	/* Try to keep metapages from using up too much memory */