X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjbd%2Fjournal.c;h=7f96b5cb67816109e38a51b79a6ee80364e48c5d;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=cb9d794cc58823c7da43ebee60e522df474a23b4;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index cb9d794cc..7f96b5cb6 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -33,9 +33,11 @@ #include #include #include +#include +#include + #include #include -#include EXPORT_SYMBOL(journal_start); EXPORT_SYMBOL(journal_restart); @@ -55,7 +57,6 @@ EXPORT_SYMBOL(journal_sync_buffer); #endif EXPORT_SYMBOL(journal_flush); EXPORT_SYMBOL(journal_revoke); -EXPORT_SYMBOL(journal_callback_set); EXPORT_SYMBOL(journal_init_dev); EXPORT_SYMBOL(journal_init_inode); @@ -66,7 +67,6 @@ EXPORT_SYMBOL(journal_set_features); EXPORT_SYMBOL(journal_create); EXPORT_SYMBOL(journal_load); EXPORT_SYMBOL(journal_destroy); -EXPORT_SYMBOL(journal_recover); EXPORT_SYMBOL(journal_update_superblock); EXPORT_SYMBOL(journal_abort); EXPORT_SYMBOL(journal_errno); @@ -79,10 +79,10 @@ EXPORT_SYMBOL(journal_wipe); EXPORT_SYMBOL(journal_blocks_per_page); EXPORT_SYMBOL(journal_invalidatepage); EXPORT_SYMBOL(journal_try_to_free_buffers); -EXPORT_SYMBOL(journal_bmap); EXPORT_SYMBOL(journal_force_commit); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); +static void __journal_abort_soft (journal_t *journal, int errno); /* * Helper function used to manage commit timeouts @@ -95,16 +95,6 @@ static void commit_timeout(unsigned long __data) wake_up_process(p); } -/* Static check for data structure consistency. There's no code - * invoked --- we'll just get a linker failure if things aren't right. - */ -void __journal_internal_check(void) -{ - extern void journal_bad_superblock_size(void); - if (sizeof(struct journal_superblock_s) != 1024) - journal_bad_superblock_size(); -} - /* * kjournald: The main thread function used to manage a logging device * journal. @@ -121,24 +111,17 @@ void __journal_internal_check(void) * known as checkpointing, and this thread is responsible for that job. */ -journal_t *current_journal; // AKPM: debug - -int kjournald(void *arg) +static int kjournald(void *arg) { - journal_t *journal = (journal_t *) arg; + journal_t *journal = arg; transaction_t *transaction; - struct timer_list timer; - - current_journal = journal; - daemonize("kjournald"); - - /* Set up an interval timer which can be used to trigger a - commit wakeup after the commit interval expires */ - init_timer(&timer); - timer.data = (unsigned long) current; - timer.function = commit_timeout; - journal->j_commit_timer = &timer; + /* + * Set up an interval timer which can be used to trigger a commit wakeup + * after the commit interval expires + */ + setup_timer(&journal->j_commit_timer, commit_timeout, + (unsigned long)current); /* Record that the journal thread is running */ journal->j_task = current; @@ -153,20 +136,23 @@ int kjournald(void *arg) spin_lock(&journal->j_state_lock); loop: + if (journal->j_flags & JFS_UNMOUNT) + goto end_loop; + jbd_debug(1, "commit_sequence=%d, commit_request=%d\n", journal->j_commit_sequence, journal->j_commit_request); if (journal->j_commit_sequence != journal->j_commit_request) { jbd_debug(1, "OK, requests differ\n"); spin_unlock(&journal->j_state_lock); - del_timer_sync(journal->j_commit_timer); + del_timer_sync(&journal->j_commit_timer); journal_commit_transaction(journal); spin_lock(&journal->j_state_lock); - goto end_loop; + goto loop; } wake_up(&journal->j_wait_done_commit); - if (current->flags & PF_FREEZE) { + if (freezing(current)) { /* * The simpler the better. Flushing journal isn't a * good idea, because that depends on threads that may @@ -174,7 +160,7 @@ loop: */ jbd_debug(1, "Now suspending kjournald\n"); spin_unlock(&journal->j_state_lock); - refrigerator(PF_FREEZE); + refrigerator(); spin_lock(&journal->j_state_lock); } else { /* @@ -192,6 +178,8 @@ loop: if (transaction && time_after_eq(jiffies, transaction->t_expires)) should_sleep = 0; + if (journal->j_flags & JFS_UNMOUNT) + should_sleep = 0; if (should_sleep) { spin_unlock(&journal->j_state_lock); schedule(); @@ -210,12 +198,11 @@ loop: journal->j_commit_request = transaction->t_tid; jbd_debug(1, "woke because of timeout\n"); } -end_loop: - if (!(journal->j_flags & JFS_UNMOUNT)) - goto loop; + goto loop; +end_loop: spin_unlock(&journal->j_state_lock); - del_timer_sync(journal->j_commit_timer); + del_timer_sync(&journal->j_commit_timer); journal->j_task = NULL; wake_up(&journal->j_wait_done_commit); jbd_debug(1, "Journal thread exiting.\n"); @@ -224,7 +211,7 @@ end_loop: static void journal_start_thread(journal_t *journal) { - kernel_thread(kjournald, journal, CLONE_VM|CLONE_FS|CLONE_FILES); + kthread_run(kjournald, journal, "kjournald"); wait_event(journal->j_wait_done_commit, journal->j_task != 0); } @@ -671,8 +658,8 @@ static journal_t * journal_init_common (void) init_waitqueue_head(&journal->j_wait_checkpoint); init_waitqueue_head(&journal->j_wait_commit); init_waitqueue_head(&journal->j_wait_updates); - init_MUTEX(&journal->j_barrier); - init_MUTEX(&journal->j_checkpoint_sem); + mutex_init(&journal->j_barrier); + mutex_init(&journal->j_checkpoint_mutex); spin_lock_init(&journal->j_revoke_lock); spin_lock_init(&journal->j_list_lock); spin_lock_init(&journal->j_state_lock); @@ -721,6 +708,7 @@ journal_t * journal_init_dev(struct block_device *bdev, { journal_t *journal = journal_init_common(); struct buffer_head *bh; + int n; if (!journal) return NULL; @@ -736,6 +724,17 @@ journal_t * journal_init_dev(struct block_device *bdev, journal->j_sb_buffer = bh; journal->j_superblock = (journal_superblock_t *)bh->b_data; + /* journal descriptor can store up to n blocks -bzzz */ + n = journal->j_blocksize / sizeof(journal_block_tag_t); + journal->j_wbufsize = n; + journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); + if (!journal->j_wbuf) { + printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", + __FUNCTION__); + kfree(journal); + journal = NULL; + } + return journal; } @@ -752,6 +751,7 @@ journal_t * journal_init_inode (struct inode *inode) struct buffer_head *bh; journal_t *journal = journal_init_common(); int err; + int n; unsigned long blocknr; if (!journal) @@ -768,6 +768,17 @@ journal_t * journal_init_inode (struct inode *inode) journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits; journal->j_blocksize = inode->i_sb->s_blocksize; + /* journal descriptor can store up to n blocks -bzzz */ + n = journal->j_blocksize / sizeof(journal_block_tag_t); + journal->j_wbufsize = n; + journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); + if (!journal->j_wbuf) { + printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", + __FUNCTION__); + kfree(journal); + return NULL; + } + err = journal_bmap(journal, 0, &blocknr); /* If that failed, give up */ if (err) { @@ -945,7 +956,7 @@ void journal_update_superblock(journal_t *journal, int wait) if (wait) sync_dirty_buffer(bh); else - ll_rw_block(WRITE, 1, &bh); + ll_rw_block(SWRITE, 1, &bh); out: /* If we have just flushed the log (by marking s_start==0), then @@ -1141,12 +1152,17 @@ void journal_destroy(journal_t *journal) iput(journal->j_inode); if (journal->j_revoke) journal_destroy_revoke(journal); + kfree(journal->j_wbuf); kfree(journal); } /** *int journal_check_used_features () - Check if features specified are used. + * @journal: Journal to check. + * @compat: bitmask of compatible features + * @ro: bitmask of features that force read-only mount + * @incompat: bitmask of incompatible features * * Check whether the journal uses all of a given set of * features. Return true (non-zero) if it does. @@ -1174,6 +1190,10 @@ int journal_check_used_features (journal_t *journal, unsigned long compat, /** * int journal_check_available_features() - Check feature set in journalling layer + * @journal: Journal to check. + * @compat: bitmask of compatible features + * @ro: bitmask of features that force read-only mount + * @incompat: bitmask of incompatible features * * Check whether the journaling code supports the use of * all of a given set of features on this journal. Return true @@ -1206,6 +1226,10 @@ int journal_check_available_features (journal_t *journal, unsigned long compat, /** * int journal_set_features () - Mark a given journal feature in the superblock + * @journal: Journal to act on. + * @compat: bitmask of compatible features + * @ro: bitmask of features that force read-only mount + * @incompat: bitmask of incompatible features * * Mark a given journal feature as present on the * superblock. Returns true if the requested features could be set. @@ -1238,6 +1262,7 @@ int journal_set_features (journal_t *journal, unsigned long compat, /** * int journal_update_format () - Update on-disk journal structure. + * @journal: Journal to act on. * * Given an initialised but unloaded journal struct, poke about in the * on-disk structure to update it to the most recent supported version. @@ -1401,7 +1426,7 @@ int journal_wipe(journal_t *journal, int write) * device this journal is present. */ -const char *journal_dev_name(journal_t *journal, char *buffer) +static const char *journal_dev_name(journal_t *journal, char *buffer) { struct block_device *bdev; @@ -1447,7 +1472,7 @@ void __journal_abort_hard(journal_t *journal) /* Soft abort: record the abort error status in the journal superblock, * but don't do any other IO. */ -void __journal_abort_soft (journal_t *journal, int errno) +static void __journal_abort_soft (journal_t *journal, int errno) { if (journal->j_flags & JFS_ABORT) return; @@ -1538,6 +1563,7 @@ int journal_errno(journal_t *journal) /** * int journal_clear_err () - clears the journal's error state + * @journal: journal to act on. * * An error must be cleared or Acked to take a FS out of readonly * mode. @@ -1557,6 +1583,7 @@ int journal_clear_err(journal_t *journal) /** * void journal_ack_err() - Ack journal err. + * @journal: journal to act on. * * An error must be cleared or Acked to take a FS out of readonly * mode. @@ -1575,14 +1602,10 @@ int journal_blocks_per_page(struct inode *inode) } /* - * Simple support for retying memory allocations. Introduced to help to + * Simple support for retrying memory allocations. Introduced to help to * debug different VM deadlock avoidance strategies. */ -/* - * Simple support for retying memory allocations. Introduced to help to - * debug different VM deadlock avoidance strategies. - */ -void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry) +void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) { return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); } @@ -1767,6 +1790,7 @@ static void __journal_remove_journal_head(struct buffer_head *bh) if (jh->b_transaction == NULL && jh->b_next_transaction == NULL && jh->b_cp_transaction == NULL) { + J_ASSERT_JH(jh, jh->b_jlist == BJ_None); J_ASSERT_BH(bh, buffer_jbd(bh)); J_ASSERT_BH(bh, jh2bh(jh) == bh); BUFFER_TRACE(bh, "remove journal_head"); @@ -1843,7 +1867,7 @@ EXPORT_SYMBOL(journal_enable_debug); static struct proc_dir_entry *proc_jbd_debug; -int read_jbd_debug(char *page, char **start, off_t off, +static int read_jbd_debug(char *page, char **start, off_t off, int count, int *eof, void *data) { int ret; @@ -1853,7 +1877,7 @@ int read_jbd_debug(char *page, char **start, off_t off, return ret; } -int write_jbd_debug(struct file *file, const char __user *buffer, +static int write_jbd_debug(struct file *file, const char __user *buffer, unsigned long count, void *data) { char buf[32]; @@ -1942,6 +1966,14 @@ static int __init journal_init(void) { int ret; +/* Static check for data structure consistency. There's no code + * invoked --- we'll just get a linker failure if things aren't right. + */ + extern void journal_bad_superblock_size(void); + if (sizeof(struct journal_superblock_s) != 1024) + journal_bad_superblock_size(); + + ret = journal_init_caches(); if (ret != 0) journal_destroy_caches();