vserver 1.9.5.x5
[linux-2.6.git] / fs / jfs / super.c
index 72ae538..45b372d 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/parser.h>
 #include <linux/completion.h>
 #include <linux/vfs.h>
+#include <linux/moduleparam.h>
 #include <asm/uaccess.h>
 
 #include "jfs_incore.h"
@@ -44,15 +45,20 @@ static struct super_operations jfs_super_operations;
 static struct export_operations jfs_export_operations;
 static struct file_system_type jfs_fs_type;
 
+#define MAX_COMMIT_THREADS 64
+static int commit_threads = 0;
+module_param(commit_threads, int, 0);
+MODULE_PARM_DESC(commit_threads, "Number of commit threads");
+
 int jfs_stop_threads;
 static pid_t jfsIOthread;
-static pid_t jfsCommitThread;
+static pid_t jfsCommitThread[MAX_COMMIT_THREADS];
 static pid_t jfsSyncThread;
 DECLARE_COMPLETION(jfsIOwait);
 
 #ifdef CONFIG_JFS_DEBUG
 int jfsloglevel = JFS_LOGLEVEL_WARN;
-MODULE_PARM(jfsloglevel, "i");
+module_param(jfsloglevel, int, 0644);
 MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)");
 #endif
 
@@ -71,11 +77,13 @@ extern int jfs_sync(void *);
 extern void jfs_read_inode(struct inode *inode);
 extern void jfs_dirty_inode(struct inode *inode);
 extern void jfs_delete_inode(struct inode *inode);
-extern void jfs_write_inode(struct inode *inode, int wait);
+extern int jfs_write_inode(struct inode *inode, int wait);
 
 extern struct dentry *jfs_get_parent(struct dentry *dentry);
 extern int jfs_extendfs(struct super_block *, s64, int);
 
+extern struct dentry_operations jfs_ci_dentry_operations;
+
 #ifdef PROC_FS_JFS             /* see jfs_debug.h */
 extern void jfs_proc_init(void);
 extern void jfs_proc_clean(void);
@@ -135,10 +143,13 @@ static void jfs_destroy_inode(struct inode *inode)
 {
        struct jfs_inode_info *ji = JFS_IP(inode);
 
+       spin_lock_irq(&ji->ag_lock);
        if (ji->active_ag != -1) {
                struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
                atomic_dec(&bmap->db_active[ji->active_ag]);
+               ji->active_ag = -1;
        }
+       spin_unlock_irq(&ji->ag_lock);
 
 #ifdef CONFIG_JFS_POSIX_ACL
        if (ji->i_acl != JFS_ACL_NOT_CACHED) {
@@ -392,6 +403,10 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        }
        sbi->flag = flag;
 
+#ifdef CONFIG_JFS_POSIX_ACL
+       sb->s_flags |= MS_POSIXACL;
+#endif
+
        if (newLVSize) {
                printk(KERN_ERR "resize option for remount only\n");
                return -EINVAL;
@@ -416,7 +431,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
                goto out_kfree;
        }
        if (sb->s_flags & MS_RDONLY)
-               sbi->log = 0;
+               sbi->log = NULL;
        else {
                rc = jfs_mount_rw(sb, 0);
                if (rc) {
@@ -437,6 +452,9 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        if (!sb->s_root)
                goto out_no_root;
 
+       if (sbi->mntflag & JFS_OS2)
+               sb->s_root->d_op = &jfs_ci_dentry_operations;
+
        /* logical blocks are represented by 40 bits in pxd_t, etc. */
        sb->s_maxbytes = ((u64) sb->s_blocksize) << 40;
 #if BITS_PER_LONG == 32
@@ -446,7 +464,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
         */
        sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);
 #endif
-
+       sb->s_time_gran = 1;
        return 0;
 
 out_no_root:
@@ -553,6 +571,7 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
                init_rwsem(&jfs_ip->rdwrlock);
                init_MUTEX(&jfs_ip->commit_sem);
                init_rwsem(&jfs_ip->xattr_sem);
+               spin_lock_init(&jfs_ip->ag_lock);
                jfs_ip->active_ag = -1;
 #ifdef CONFIG_JFS_POSIX_ACL
                jfs_ip->i_acl = JFS_ACL_NOT_CACHED;
@@ -564,6 +583,7 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
 
 static int __init init_jfs_fs(void)
 {
+       int i;
        int rc;
 
        jfs_inode_cachep =
@@ -593,21 +613,32 @@ static int __init init_jfs_fs(void)
        /*
         * I/O completion thread (endio)
         */
-       jfsIOthread = kernel_thread(jfsIOWait, 0, CLONE_KERNEL);
+       jfsIOthread = kernel_thread(jfsIOWait, NULL, CLONE_KERNEL);
        if (jfsIOthread < 0) {
                jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread);
                goto end_txmngr;
        }
        wait_for_completion(&jfsIOwait);        /* Wait until thread starts */
 
-       jfsCommitThread = kernel_thread(jfs_lazycommit, 0, CLONE_KERNEL);
-       if (jfsCommitThread < 0) {
-               jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsCommitThread);
-               goto kill_iotask;
+       if (commit_threads < 1)
+               commit_threads = num_online_cpus();
+       else if (commit_threads > MAX_COMMIT_THREADS)
+               commit_threads = MAX_COMMIT_THREADS;
+
+       for (i = 0; i < commit_threads; i++) {
+               jfsCommitThread[i] = kernel_thread(jfs_lazycommit, NULL,
+                                                  CLONE_KERNEL);
+               if (jfsCommitThread[i] < 0) {
+                       jfs_err("init_jfs_fs: fork failed w/rc = %d",
+                               jfsCommitThread[i]);
+                       commit_threads = i;
+                       goto kill_committask;
+               }
+               /* Wait until thread starts */
+               wait_for_completion(&jfsIOwait);
        }
-       wait_for_completion(&jfsIOwait);        /* Wait until thread starts */
 
-       jfsSyncThread = kernel_thread(jfs_sync, 0, CLONE_KERNEL);
+       jfsSyncThread = kernel_thread(jfs_sync, NULL, CLONE_KERNEL);
        if (jfsSyncThread < 0) {
                jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread);
                goto kill_committask;
@@ -622,10 +653,10 @@ static int __init init_jfs_fs(void)
 
 kill_committask:
        jfs_stop_threads = 1;
-       wake_up(&jfs_commit_thread_wait);
-       wait_for_completion(&jfsIOwait);        /* Wait for thread exit */
-kill_iotask:
-       jfs_stop_threads = 1;
+       wake_up_all(&jfs_commit_thread_wait);
+       for (i = 0; i < commit_threads; i++)
+               wait_for_completion(&jfsIOwait);
+
        wake_up(&jfs_IO_thread_wait);
        wait_for_completion(&jfsIOwait);        /* Wait for thread exit */
 end_txmngr:
@@ -639,6 +670,8 @@ free_slab:
 
 static void __exit exit_jfs_fs(void)
 {
+       int i;
+
        jfs_info("exit_jfs_fs called");
 
        jfs_stop_threads = 1;
@@ -646,8 +679,9 @@ static void __exit exit_jfs_fs(void)
        metapage_exit();
        wake_up(&jfs_IO_thread_wait);
        wait_for_completion(&jfsIOwait);        /* Wait until IO thread exits */
-       wake_up(&jfs_commit_thread_wait);
-       wait_for_completion(&jfsIOwait);        /* Wait until Commit thread exits */
+       wake_up_all(&jfs_commit_thread_wait);
+       for (i = 0; i < commit_threads; i++)
+               wait_for_completion(&jfsIOwait);
        wake_up(&jfs_sync_thread_wait);
        wait_for_completion(&jfsIOwait);        /* Wait until Sync thread exits */
 #ifdef PROC_FS_JFS