[PATCH] Better RAS when btstack is overrun (2 of 2)
[email protected] Thu, 10 Jun 2004 12:41:53 -0500
| Newsgroups | gmane.comp.file-systems.jfs.patches |
|---|---|
| Message-ID | <[email protected]> |
# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/06/09 16:32:52-05:00 [email protected] # JFS: Better RAS when btstack is overrun # # The current warning and/or trap when the btstack is overrun in # dtSearch or dtReadFirst are not very helpful. Add code to detect # the stack overrun earlier, print something useful, and return # gracefully. # # I've found that dbFree being called with blkno == 0 can lead to this # error, so I put in a specific check for that. # # Signed-off-by: Dave Kleikamp <[email protected]> # diff -Nru a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h --- a/fs/jfs/jfs_btree.h 2004-06-10 12:37:22 -05:00 +++ b/fs/jfs/jfs_btree.h 2004-06-10 12:37:22 -05:00 @@ -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 @@ * 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 @@ #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)\ @@ -138,6 +140,16 @@ #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 -Nru a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c --- a/fs/jfs/jfs_dmap.c 2004-06-10 12:37:22 -05:00 +++ b/fs/jfs/jfs_dmap.c 2004-06-10 12:37:22 -05:00 @@ -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 @@ 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 -Nru a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c --- a/fs/jfs/jfs_dtree.c 2004-06-10 12:37:22 -05:00 +++ b/fs/jfs/jfs_dtree.c 2004-06-10 12:37:22 -05:00 @@ -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 @@ */ 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 @@ /* * 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 -Nru a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h --- a/fs/jfs/jfs_types.h 2004-06-10 12:37:22 -05:00 +++ b/fs/jfs/jfs_types.h 2004-06-10 12:37:22 -05:00 @@ -113,11 +113,12 @@ #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]; };