diff options
| -rw-r--r-- | fs/jfs/jfs_btree.h | 24 | ||||
| -rw-r--r-- | fs/jfs/jfs_dmap.c | 4 | ||||
| -rw-r--r-- | fs/jfs/jfs_dtree.c | 11 | ||||
| -rw-r--r-- | fs/jfs/jfs_types.h | 3 |
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]; }; |
