diff -urN 2.2.14pre12-set_blocksize/fs/buffer.c 2.2.14pre12-set_blocksize-debug/fs/buffer.c --- 2.2.14pre12-set_blocksize/fs/buffer.c Sun Dec 12 17:25:18 1999 +++ 2.2.14pre12-set_blocksize-debug/fs/buffer.c Thu Dec 16 18:07:23 1999 @@ -555,6 +555,22 @@ return next; } +static void fill_stack_trace_hash(struct buffer_head * bh) +{ + unsigned long *stack; + extern char *get_options(char *str, int *ints); + int i, j; + + stack = (unsigned long *) &stack; + for (j = i = 0; j < 300 && i < BH_TRACE_SIZE; j++) + { + unsigned long x = *++stack; + if (x > (unsigned long) &get_options && + x < (unsigned long) &vsprintf) + bh->b_trace_hash[i++] = x; + } +} + /* * Why like this, I hear you say... The reason is race-conditions. * As we don't lock buffers (unless we are reading them, that is), @@ -568,6 +584,7 @@ bh = find_buffer(dev,block,size); if (bh) bh->b_count++; + fill_stack_trace_hash(bh); return bh; } @@ -641,6 +658,18 @@ } } +static void show_stack_trace(struct buffer_head * bh) +{ + int i; + + printk("creation\n"); + for (i = 0; i < BH_TRACE_SIZE; i++) + printk("[<%08lu>]\n", bh->b_trace[i]); + printk("last reference\n"); + for (i = 0; i < BH_TRACE_SIZE; i++) + printk("[<%08lu>]\n", bh->b_trace_hash[i]); +} + void set_blocksize(kdev_t dev, int size) { extern int *blksize_size[]; @@ -697,6 +726,7 @@ "b_count %d, dev %s, block %lu, from %p\n", bh->b_count, bdevname(bh->b_dev), bh->b_blocknr, __builtin_return_address(0)); + show_stack_trace(bh); } if (slept) goto again; @@ -734,6 +764,22 @@ unlock_buffer(bh); } +static void fill_stack_trace(struct buffer_head * bh) +{ + unsigned long *stack; + extern char *get_options(char *str, int *ints); + int i, j; + + stack = (unsigned long *) &stack; + for (j = i = 0; j < 300 && i < BH_TRACE_SIZE; j++) + { + unsigned long x = *++stack; + if (x > (unsigned long) &get_options && + x < (unsigned long) &vsprintf) + bh->b_trace[i++] = x; + } +} + /* * Ok, this is getblk, and it isn't very clear, again to hinder * race-conditions. Most of the code is seldom used, (ie repeating), @@ -770,6 +816,7 @@ */ init_buffer(bh, dev, block, end_buffer_io_sync, NULL); bh->b_state=0; + fill_stack_trace(bh); insert_into_queues(bh); return bh; diff -urN 2.2.14pre12-set_blocksize/include/linux/fs.h 2.2.14pre12-set_blocksize-debug/include/linux/fs.h --- 2.2.14pre12-set_blocksize/include/linux/fs.h Sun Dec 12 17:45:06 1999 +++ 2.2.14pre12-set_blocksize-debug/include/linux/fs.h Thu Dec 16 18:07:34 1999 @@ -222,6 +222,9 @@ */ void (*b_end_io)(struct buffer_head *bh, int uptodate); void *b_dev_id; +#define BH_TRACE_SIZE 15 + unsigned long b_trace[BH_TRACE_SIZE]; + unsigned long b_trace_hash[BH_TRACE_SIZE]; }; typedef void (bh_end_io_t)(struct buffer_head *bh, int uptodate);