#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
+#include <linux/kthread.h>
#include <linux/buffer_head.h> /* for sync_blockdev() */
#include <linux/bio.h>
#include <linux/suspend.h>
#include <linux/delay.h>
+#include <linux/mutex.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
*/
static struct lbuf *log_redrive_list;
static DEFINE_SPINLOCK(log_redrive_lock);
-DECLARE_WAIT_QUEUE_HEAD(jfs_IO_thread_wait);
/*
* log read/write serialization (per log)
*/
-#define LOG_LOCK_INIT(log) init_MUTEX(&(log)->loglock)
-#define LOG_LOCK(log) down(&((log)->loglock))
-#define LOG_UNLOCK(log) up(&((log)->loglock))
+#define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock)
+#define LOG_LOCK(log) mutex_lock(&((log)->loglock))
+#define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock))
/*
*/
static LIST_HEAD(jfs_external_logs);
static struct jfs_log *dummy_log = NULL;
-static DECLARE_MUTEX(jfs_log_sem);
+static DEFINE_MUTEX(jfs_log_mutex);
/*
* forward references
static bio_end_io_t lbmIODone;
static void lbmStartIO(struct lbuf * bp);
static void lmGCwrite(struct jfs_log * log, int cant_block);
-static int lmLogSync(struct jfs_log * log, int nosyncwait);
+static int lmLogSync(struct jfs_log * log, int hard_sync);
* if new sync address is available
* (normally the case if sync() is executed by back-ground
* process).
- * if not, explicitly run jfs_blogsync() to initiate
- * getting of new sync address.
* calculate new value of i_nextsync which determines when
* this code is called again.
*
* PARAMETERS: log - log structure
- * nosyncwait - 1 if called asynchronously
+ * hard_sync - 1 to force all metadata to be written
*
* RETURN: 0
*
* serialization: LOG_LOCK() held on entry/exit
*/
-static int lmLogSync(struct jfs_log * log, int nosyncwait)
+static int lmLogSync(struct jfs_log * log, int hard_sync)
{
int logsize;
int written; /* written since last syncpt */
unsigned long flags;
/* push dirty metapages out to disk */
- list_for_each_entry(sbi, &log->sb_list, log_list) {
- filemap_flush(sbi->ipbmap->i_mapping);
- filemap_flush(sbi->ipimap->i_mapping);
- filemap_flush(sbi->direct_inode->i_mapping);
- }
+ if (hard_sync)
+ list_for_each_entry(sbi, &log->sb_list, log_list) {
+ filemap_fdatawrite(sbi->ipbmap->i_mapping);
+ filemap_fdatawrite(sbi->ipimap->i_mapping);
+ filemap_fdatawrite(sbi->direct_inode->i_mapping);
+ }
+ else
+ list_for_each_entry(sbi, &log->sb_list, log_list) {
+ filemap_flush(sbi->ipbmap->i_mapping);
+ filemap_flush(sbi->ipimap->i_mapping);
+ filemap_flush(sbi->direct_inode->i_mapping);
+ }
/*
* forward syncpt
/* next syncpt trigger = written + more */
log->nextsync = written + more;
- /* return if lmLogSync() from outside of transaction, e.g., sync() */
- if (nosyncwait)
- return lsn;
-
/* if number of bytes written from last sync point is more
* than 1/4 of the log size, stop new transactions from
* starting until all current transactions are completed
*
* FUNCTION: write log SYNCPT record for specified log
*
- * PARAMETERS: log - log structure
+ * PARAMETERS: log - log structure
+ * hard_sync - set to 1 to force metadata to be written
*/
-void jfs_syncpt(struct jfs_log *log)
+void jfs_syncpt(struct jfs_log *log, int hard_sync)
{ LOG_LOCK(log);
- lmLogSync(log, 1);
+ lmLogSync(log, hard_sync);
LOG_UNLOCK(log);
}
if (sbi->mntflag & JFS_INLINELOG)
return open_inline_log(sb);
- down(&jfs_log_sem);
+ mutex_lock(&jfs_log_mutex);
list_for_each_entry(log, &jfs_external_logs, journal_list) {
if (log->bdev->bd_dev == sbi->logdev) {
if (memcmp(log->uuid, sbi->loguuid,
sizeof(log->uuid))) {
jfs_warn("wrong uuid on JFS journal\n");
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
return -EINVAL;
}
/*
* add file system to log active file system list
*/
if ((rc = lmLogFileSystem(log, sbi, 1))) {
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
return rc;
}
goto journal_found;
}
}
- if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) {
- up(&jfs_log_sem);
+ if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) {
+ mutex_unlock(&jfs_log_mutex);
return -ENOMEM;
}
- memset(log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&log->sb_list);
init_waitqueue_head(&log->syncwait);
sbi->log = log;
LOG_UNLOCK(log);
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
return 0;
/*
blkdev_put(bdev);
free: /* free log descriptor */
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
kfree(log);
jfs_warn("lmLogOpen: exit(%d)", rc);
struct jfs_log *log;
int rc;
- if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL)))
+ if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL)))
return -ENOMEM;
- memset(log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&log->sb_list);
init_waitqueue_head(&log->syncwait);
{
int rc;
- down(&jfs_log_sem);
+ mutex_lock(&jfs_log_mutex);
if (!dummy_log) {
- dummy_log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL);
+ dummy_log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL);
if (!dummy_log) {
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
return -ENOMEM;
}
- memset(dummy_log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&dummy_log->sb_list);
init_waitqueue_head(&dummy_log->syncwait);
dummy_log->no_integrity = 1;
if (rc) {
kfree(dummy_log);
dummy_log = NULL;
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
return rc;
}
}
list_add(&JFS_SBI(sb)->log_list, &dummy_log->sb_list);
JFS_SBI(sb)->log = dummy_log;
LOG_UNLOCK(dummy_log);
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
return 0;
}
jfs_info("lmLogClose: log:0x%p", log);
- down(&jfs_log_sem);
+ mutex_lock(&jfs_log_mutex);
LOG_LOCK(log);
list_del(&sbi->log_list);
LOG_UNLOCK(log);
kfree(log);
out:
- up(&jfs_log_sem);
+ mutex_unlock(&jfs_log_mutex);
jfs_info("lmLogClose: exit(%d)", rc);
return rc;
}
log_redrive_list = bp;
spin_unlock_irqrestore(&log_redrive_lock, flags);
- wake_up(&jfs_IO_thread_wait);
+ wake_up_process(jfsIOthread);
}
{
struct lbuf *bp;
- daemonize("jfsIO");
-
- complete(&jfsIOwait);
-
do {
- DECLARE_WAITQUEUE(wq, current);
-
spin_lock_irq(&log_redrive_lock);
while ((bp = log_redrive_list) != 0) {
log_redrive_list = bp->l_redrive_next;
lbmStartIO(bp);
spin_lock_irq(&log_redrive_lock);
}
+ spin_unlock_irq(&log_redrive_lock);
+
if (freezing(current)) {
- spin_unlock_irq(&log_redrive_lock);
refrigerator();
} else {
- add_wait_queue(&jfs_IO_thread_wait, &wq);
set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(&log_redrive_lock);
schedule();
current->state = TASK_RUNNING;
- remove_wait_queue(&jfs_IO_thread_wait, &wq);
}
- } while (!jfs_stop_threads);
+ } while (!kthread_should_stop());
jfs_info("jfsIOWait being killed!");
- complete_and_exit(&jfsIOwait, 0);
+ return 0;
}
/*