Commit fa2c79c3 authored by Dave Kleikamp's avatar Dave Kleikamp Committed by Dave Kleikamp

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: default avatarDave Kleikamp <shaggy@austin.ibm.com>
parent 86f996c0
/* /*
* 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -108,13 +108,12 @@ struct btpage { ...@@ -108,13 +108,12 @@ struct btpage {
* record the path traversed during the search; * record the path traversed during the search;
* top frame record the leaf page/entry selected. * top frame record the leaf page/entry selected.
*/ */
#define MAXTREEHEIGHT 8
struct btframe { /* stack frame */ struct btframe { /* stack frame */
s64 bn; /* 8: */ s64 bn; /* 8: */
s16 index; /* 2: */ s16 index; /* 2: */
s16 lastindex; /* 2: */ s16 lastindex; /* 2: unused */
struct metapage *mp; /* 4: */ struct metapage *mp; /* 4/8: */
}; /* (16) */ }; /* (16/24) */
struct btstack { struct btstack {
struct btframe *top; struct btframe *top;
...@@ -125,12 +124,15 @@ struct btstack { ...@@ -125,12 +124,15 @@ struct btstack {
#define BT_CLR(btstack)\ #define BT_CLR(btstack)\
(btstack)->top = (btstack)->stack (btstack)->top = (btstack)->stack
#define BT_STACK_FULL(btstack)\
( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1]))
#define BT_PUSH(BTSTACK, BN, INDEX)\ #define BT_PUSH(BTSTACK, BN, INDEX)\
{\ {\
assert(!BT_STACK_FULL(BTSTACK));\
(BTSTACK)->top->bn = BN;\ (BTSTACK)->top->bn = BN;\
(BTSTACK)->top->index = INDEX;\ (BTSTACK)->top->index = INDEX;\
++(BTSTACK)->top;\ ++(BTSTACK)->top;\
assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
} }
#define BT_POP(btstack)\ #define BT_POP(btstack)\
...@@ -139,6 +141,16 @@ struct btstack { ...@@ -139,6 +141,16 @@ struct btstack {
#define BT_STACK(btstack)\ #define BT_STACK(btstack)\
( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top ) ( (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 */ /* retrieve search results */
#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\ #define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
{\ {\
......
/* /*
* 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 * 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 * 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) ...@@ -382,7 +382,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
IREAD_LOCK(ipbmap); IREAD_LOCK(ipbmap);
/* block to be freed better be within the mapsize. */ /* 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); IREAD_UNLOCK(ipbmap);
printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n", printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n",
(unsigned long long) blkno, (unsigned long long) blkno,
......
/* /*
* 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 * 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 * 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, ...@@ -766,11 +766,12 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
*/ */
getChild: getChild:
/* update max. number of pages to split */ /* update max. number of pages to split */
if (btstack->nsplit >= 8) { if (BT_STACK_FULL(btstack)) {
/* Something's corrupted, mark filesytem dirty so /* Something's corrupted, mark filesytem dirty so
* chkdsk will fix it. * chkdsk will fix it.
*/ */
jfs_error(sb, "stack overrun in dtSearch!"); jfs_error(sb, "stack overrun in dtSearch!");
BT_STACK_DUMP(btstack);
rc = -EIO; rc = -EIO;
goto out; goto out;
} }
...@@ -3346,6 +3347,12 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack) ...@@ -3346,6 +3347,12 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack)
/* /*
* descend down to leftmost child page * 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 */ /* push (bn, index) of the parent page/entry */
BT_PUSH(btstack, bn, 0); BT_PUSH(btstack, bn, 0);
......
...@@ -113,11 +113,12 @@ typedef struct { ...@@ -113,11 +113,12 @@ typedef struct {
#define addressPXD(pxd)\ #define addressPXD(pxd)\
( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2)) ( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
#define MAXTREEHEIGHT 8
/* pxd list */ /* pxd list */
struct pxdlist { struct pxdlist {
s16 maxnpxd; s16 maxnpxd;
s16 npxd; s16 npxd;
pxd_t pxd[8]; pxd_t pxd[MAXTREEHEIGHT];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment