ifneq ($(KERNELRELEASE),)
# kbuild part
-EXTRA_CFLAGS += -Werror -DDUMP -DDEBUG_REF=1
+EXTRA_CFLAGS += -Werror -DDUMP -DDEBUG_REF=1 -DDEBUG_IOLOCK=1
obj-m += lafs.o
lafs-y := super.o io.o roll.o dir.o inode.o index.o block.o file.o link.o dir-avl.o \
/* the list counted a reference. Now we hold it */
list_del_init(&b->lru);
- if (!test_bit(B_Index, &b->flags))
+ if (!test_bit(B_Index, &b->flags)) {
if (test_and_set_bit(B_IOLock, &b->flags)) {
/* someone else is invalidating this block,
* so I can just skip it. Better drop the ref.
spin_unlock(&fs->lock);
putref(b, MKREF(leaf));
goto retry;
- }
+ } else
+ set_iolock_info(b);
+ }
}
spin_unlock(&fs->lock);
if (b && test_bit(B_Index, &b->flags))
static DECLARE_WAIT_QUEUE_HEAD(block_wait); /* need more of these later FIXME */
void
-lafs_iolock_block(struct block *b)
+_lafs_iolock_block(struct block *b)
{
if (test_and_set_bit(B_IOLock, &b->flags)) {
DEFINE_WAIT(wq);
+#ifdef DEBUG_IOLOCK
+ printk("iolock wait for %s:%d: %s\n",
+ b->iolock_file, b->iolock_line,
+ strblk(b));
+#endif
for (;;) {
prepare_to_wait(&block_wait, &wq, TASK_UNINTERRUPTIBLE);
if (test_and_set_bit(B_IOLock, &b->flags))
struct indexblock *lafs_leaf_find(struct inode *inode, u32 addr,
int adopt, u32 *next, int async, REFARG);
u32 lafs_leaf_next(struct indexblock *ib, u32 start);
-void lafs_iolock_block(struct block *b);
+#ifdef DEBUG_IOLOCK
+#define set_iolock_info(b) do { (b)->iolock_file = __FILE__; (b)->iolock_line = __LINE__; } while (0)
+#else
+#define set_iolock_info(b) do {} while(0)
+#endif
+#define lafs_iolock_block(b) do { _lafs_iolock_block(b); set_iolock_info(b); } while(0)
+
+void _lafs_iolock_block(struct block *b);
void lafs_iounlock_block(struct block *b, int bit);
void lafs_super_write(struct fs *fs, int dev, u64 addr, char *buf, int size);
#if DEBUG_REF
struct ref {int cnt; char *name; } holders[16];
#endif
+#if DEBUG_IOLOCK
+ /* More debugging */
+ char *iolock_file;
+ int iolock_line;
+#endif
};
struct datablock {
struct block b;