summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/jfs/jfs_btree.h24
-rw-r--r--fs/jfs/jfs_dmap.c4
-rw-r--r--fs/jfs/jfs_dtree.c11
-rw-r--r--fs/jfs/jfs_types.h3
4 files changed, 31 insertions, 11 deletions
diff --git a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h
index 53c0a6ea72d8..ba4fb09f5fa2 100644
--- a/fs/jfs/jfs_btree.h
+++ b/fs/jfs/jfs_btree.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2001
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -108,13 +108,12 @@ struct btpage {
* record the path traversed during the search;
* top frame record the leaf page/entry selected.
*/
-#define MAXTREEHEIGHT 8
struct btframe { /* stack frame */
s64 bn; /* 8: */
s16 index; /* 2: */
- s16 lastindex; /* 2: */
- struct metapage *mp; /* 4: */
-}; /* (16) */
+ s16 lastindex; /* 2: unused */
+ struct metapage *mp; /* 4/8: */
+}; /* (16/24) */
struct btstack {
struct btframe *top;
@@ -125,12 +124,15 @@ struct btstack {
#define BT_CLR(btstack)\
(btstack)->top = (btstack)->stack
+#define BT_STACK_FULL(btstack)\
+ ( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1]))
+
#define BT_PUSH(BTSTACK, BN, INDEX)\
{\
+ assert(!BT_STACK_FULL(BTSTACK));\
(BTSTACK)->top->bn = BN;\
(BTSTACK)->top->index = INDEX;\
++(BTSTACK)->top;\
- assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
}
#define BT_POP(btstack)\
@@ -139,6 +141,16 @@ struct btstack {
#define BT_STACK(btstack)\
( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
+static inline void BT_STACK_DUMP(struct btstack *btstack)
+{
+ int i;
+ printk("btstack dump:\n");
+ for (i = 0; i < MAXTREEHEIGHT; i++)
+ printk(KERN_ERR "bn = %Lx, index = %d\n",
+ btstack->stack[i].bn,
+ btstack->stack[i].index);
+}
+
/* retrieve search results */
#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
{\
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 3e9e629f4c2f..1b55df36f5cc 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) International Business Machines Corp., 2000-2003
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -382,7 +382,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
IREAD_LOCK(ipbmap);
/* block to be freed better be within the mapsize. */
- if (blkno + nblocks > bmp->db_mapsize) {
+ if (unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) {
IREAD_UNLOCK(ipbmap);
printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n",
(unsigned long long) blkno,
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index b125ca4f9ebe..3c3140dd758f 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) International Business Machines Corp., 2000-2003
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -766,11 +766,12 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
*/
getChild:
/* update max. number of pages to split */
- if (btstack->nsplit >= 8) {
+ if (BT_STACK_FULL(btstack)) {
/* Something's corrupted, mark filesytem dirty so
* chkdsk will fix it.
*/
jfs_error(sb, "stack overrun in dtSearch!");
+ BT_STACK_DUMP(btstack);
rc = -EIO;
goto out;
}
@@ -3346,6 +3347,12 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack)
/*
* descend down to leftmost child page
*/
+ if (BT_STACK_FULL(btstack)) {
+ DT_PUTPAGE(mp);
+ jfs_error(ip->i_sb, "dtReadFirst: btstack overrun");
+ BT_STACK_DUMP(btstack);
+ return -EIO;
+ }
/* push (bn, index) of the parent page/entry */
BT_PUSH(btstack, bn, 0);
diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h
index 87ecbab5d66f..3fefbf063a93 100644
--- a/fs/jfs/jfs_types.h
+++ b/fs/jfs/jfs_types.h
@@ -113,11 +113,12 @@ typedef struct {
#define addressPXD(pxd)\
( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
+#define MAXTREEHEIGHT 8
/* pxd list */
struct pxdlist {
s16 maxnpxd;
s16 npxd;
- pxd_t pxd[8];
+ pxd_t pxd[MAXTREEHEIGHT];
};