JFS: Free sbi memory in error path
[safe/jmp/linux-2.6] / fs / jfs / jfs_txnmgr.c
index f2dc4b9..d945ea7 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kthread.h>
+#include <linux/seq_file.h>
 #include "jfs_incore.h"
 #include "jfs_inode.h"
 #include "jfs_filsys.h"
@@ -829,12 +830,16 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
        /* Only locks on ipimap or ipaimap should reach here */
        /* assert(jfs_ip->fileset == AGGREGATE_I); */
        if (jfs_ip->fileset != AGGREGATE_I) {
-               jfs_err("txLock: trying to lock locked page!");
-               dump_mem("ip", ip, sizeof(struct inode));
-               dump_mem("mp", mp, sizeof(struct metapage));
-               dump_mem("Locker's tblk", tid_to_tblock(tid),
-                        sizeof(struct tblock));
-               dump_mem("Tlock", tlck, sizeof(struct tlock));
+               printk(KERN_ERR "txLock: trying to lock locked page!");
+               print_hex_dump(KERN_ERR, "ip: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              ip, sizeof(*ip), 0);
+               print_hex_dump(KERN_ERR, "mp: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              mp, sizeof(*mp), 0);
+               print_hex_dump(KERN_ERR, "Locker's tblock: ",
+                              DUMP_PREFIX_ADDRESS, 16, 4, tid_to_tblock(tid),
+                              sizeof(struct tblock), 0);
+               print_hex_dump(KERN_ERR, "Tlock: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              tlck, sizeof(*tlck), 0);
                BUG();
        }
        INCREMENT(stattx.waitlock);     /* statistics */
@@ -1285,7 +1290,14 @@ int txCommit(tid_t tid,          /* transaction identifier */
                 * commit the transaction synchronously, so the last iput
                 * will be done by the calling thread (or later)
                 */
-               if (tblk->u.ip->i_state & I_LOCK)
+               /*
+                * I believe this code is no longer needed.  Splitting I_LOCK
+                * into two bits, I_NEW and I_SYNC should prevent this
+                * deadlock as well.  But since I don't have a JFS testload
+                * to verify this, only a trivial s/I_LOCK/I_SYNC/ was done.
+                * Joern
+                */
+               if (tblk->u.ip->i_state & I_SYNC)
                        tblk->xflag &= ~COMMIT_LAZY;
        }
 
@@ -2998,11 +3010,8 @@ int jfs_sync(void *arg)
 }
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG)
-int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
-                     int *eof, void *data)
+static int jfs_txanchor_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
-       off_t begin;
        char *freewait;
        char *freelockwait;
        char *lowlockwait;
@@ -3014,7 +3023,7 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
        lowlockwait =
            waitqueue_active(&TxAnchor.lowlockwait) ? "active" : "empty";
 
-       len += sprintf(buffer,
+       seq_printf(m,
                       "JFS TxAnchor\n"
                       "============\n"
                       "freetid = %d\n"
@@ -3033,31 +3042,27 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
                       TxAnchor.tlocksInUse,
                       jfs_tlocks_low,
                       list_empty(&TxAnchor.unlock_queue) ? "" : "not ");
+       return 0;
+}
 
-       begin = offset;
-       *start = buffer + begin;
-       len -= begin;
-
-       if (len > length)
-               len = length;
-       else
-               *eof = 1;
-
-       if (len < 0)
-               len = 0;
-
-       return len;
+static int jfs_txanchor_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, jfs_txanchor_proc_show, NULL);
 }
+
+const struct file_operations jfs_txanchor_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = jfs_txanchor_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_STATISTICS)
-int jfs_txstats_read(char *buffer, char **start, off_t offset, int length,
-                    int *eof, void *data)
+static int jfs_txstats_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
-       off_t begin;
-
-       len += sprintf(buffer,
+       seq_printf(m,
                       "JFS TxStats\n"
                       "===========\n"
                       "calls to txBegin = %d\n"
@@ -3078,19 +3083,19 @@ int jfs_txstats_read(char *buffer, char **start, off_t offset, int length,
                       TxStat.txBeginAnon_lockslow,
                       TxStat.txLockAlloc,
                       TxStat.txLockAlloc_freelock);
+       return 0;
+}
 
-       begin = offset;
-       *start = buffer + begin;
-       len -= begin;
-
-       if (len > length)
-               len = length;
-       else
-               *eof = 1;
-
-       if (len < 0)
-               len = 0;
-
-       return len;
+static int jfs_txstats_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, jfs_txstats_proc_show, NULL);
 }
+
+const struct file_operations jfs_txstats_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = jfs_txstats_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif