diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-04-11 23:25:50 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-11 23:25:50 -0700 |
| commit | 7c563ced265e3134a5c5c5b7ca2b31218993a204 (patch) | |
| tree | 4f4523dc349a535e8e6f9e0f4a09db748dbfe053 /include/linux | |
| parent | 8f57688237995959aee38d48a0c92e203dbec676 (diff) | |
[PATCH] reiserfs: logging rework
From: Chris Mason <mason@suse.com>
reiserfs logging rework, making things much faster for small transactions.
metadata buffers are dirtied when they are safe to write, so normal kernel
mechanisms can contribute to log cleaning.
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/reiserfs_fs.h | 29 | ||||
| -rw-r--r-- | include/linux/reiserfs_fs_i.h | 4 | ||||
| -rw-r--r-- | include/linux/reiserfs_fs_sb.h | 70 |
3 files changed, 55 insertions, 48 deletions
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index e4695e7b7ba3..fb0bf2af7fd7 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1702,23 +1702,39 @@ struct reiserfs_journal_header { (((block)<<(JBH_HASH_SHIFT - 6)) ^ ((block) >> 13) ^ ((block) << (JBH_HASH_SHIFT - 12)))) #define journal_hash(t,sb,block) ((t)[_jhashfn((sb),(block)) & JBH_HASH_MASK]) -/* finds n'th buffer with 0 being the start of this commit. Needs to go away, j_ap_blocks has changed -** since I created this. One chunk of code in journal.c needs changing before deleting it -*/ -#define JOURNAL_BUFFER(j,n) ((j)->j_ap_blocks[((j)->j_start + (n)) % JOURNAL_BLOCK_COUNT]) - // We need these to make journal.c code more readable #define journal_find_get_block(s, block) __find_get_block(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize) #define journal_getblk(s, block) __getblk(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize) #define journal_bread(s, block) __bread(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize) +/* +** transaction handle which is passed around for all journal calls +*/ +struct reiserfs_transaction_handle { + struct super_block *t_super ; /* super for this FS when journal_begin was + called. saves calls to reiserfs_get_super + also used by nested transactions to make + sure they are nesting on the right FS + _must_ be first in the handle + */ + int t_refcount; + int t_blocks_logged ; /* number of blocks this writer has logged */ + int t_blocks_allocated ; /* number of blocks this writer allocated */ + unsigned long t_trans_id ; /* sanity check, equals the current trans id */ + void *t_handle_save ; /* save existing current->journal_info */ + int displace_new_blocks:1; /* if new block allocation occurres, that block + should be displaced from others */ +} ; + +int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ; +int reiserfs_flush_old_commits(struct super_block *); void reiserfs_commit_for_inode(struct inode *) ; void reiserfs_update_inode_transaction(struct inode *) ; void reiserfs_wait_on_write_block(struct super_block *s) ; void reiserfs_block_writes(struct reiserfs_transaction_handle *th) ; void reiserfs_allow_writes(struct super_block *s) ; void reiserfs_check_lock_depth(char *caller) ; -void reiserfs_prepare_for_journal(struct super_block *, struct buffer_head *bh, int wait) ; +int reiserfs_prepare_for_journal(struct super_block *, struct buffer_head *bh, int wait) ; void reiserfs_restore_prepared_buffer(struct super_block *, struct buffer_head *bh) ; int journal_init(struct super_block *, const char * j_dev_name, int old_format, unsigned int) ; int journal_release(struct reiserfs_transaction_handle*, struct super_block *) ; @@ -1730,7 +1746,6 @@ int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ; int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr, int searchall, b_blocknr_t *next) ; int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ; -void flush_async_commits(struct super_block *p_s_sb) ; int buffer_journaled(const struct buffer_head *bh) ; int mark_buffer_journal_new(struct buffer_head *bh) ; diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h index 87e1b74e1125..e689a12bcb9b 100644 --- a/include/linux/reiserfs_fs_i.h +++ b/include/linux/reiserfs_fs_i.h @@ -3,6 +3,8 @@ #include <linux/list.h> +struct reiserfs_journal_list; + /** bitmasks for i_flags field in reiserfs-specific part of inode */ typedef enum { /** this says what format of key do all items (but stat data) of @@ -48,7 +50,7 @@ struct reiserfs_inode_info { ** needs to be committed in order for this inode to be properly ** flushed */ unsigned long i_trans_id ; - unsigned long i_trans_index ; + struct reiserfs_journal_list *i_jl; struct inode vfs_inode; }; diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index b848ccd7ed41..e1fe3ebe33c0 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -106,7 +106,6 @@ typedef enum { #define JOURNAL_MAX_CNODE 1500 /* max cnodes to allocate. */ #define JOURNAL_HASH_SIZE 8192 #define JOURNAL_NUM_BITMAPS 5 /* number of copies of the bitmaps to have floating. Must be >= 2 */ -#define JOURNAL_LIST_COUNT 64 /* these are bh_state bit flag offset numbers, for use in the buffer head */ @@ -121,6 +120,7 @@ typedef enum { */ #define BH_JPrepared 20 /* block has been prepared for the log */ #define BH_JRestore_dirty 22 /* restore the dirty bit later */ +#define BH_JTest 23 /* debugging use only */ /* One of these for every block in every transaction ** Each one is in two hash tables. First, a hash of the current transaction, and after journal_end, a @@ -154,26 +154,6 @@ struct reiserfs_list_bitmap { } ; /* -** transaction handle which is passed around for all journal calls -*/ -struct reiserfs_transaction_handle { - struct super_block *t_super ; /* super for this FS when journal_begin was - called. saves calls to reiserfs_get_super - also used by nested transactions to make - sure they are nesting on the right FS - _must_ be first in the handle - */ - int t_refcount; - int t_blocks_logged ; /* number of blocks this writer has logged */ - int t_blocks_allocated ; /* number of blocks this writer allocated */ - unsigned long t_trans_id ; /* sanity check, equals the current trans id */ - void *t_handle_save ; /* save existing current->journal_info */ - int displace_new_blocks:1; /* if new block allocation occurres, that block - should be displaced from others */ - -} ; - -/* ** one of these for each transaction. The most important part here is the j_realblock. ** this list of cnodes is used to hash all the blocks in all the commits, to mark all the ** real buffer heads dirty once all the commits hit the disk, @@ -181,23 +161,25 @@ struct reiserfs_transaction_handle { ** to be overwritten */ struct reiserfs_journal_list { unsigned long j_start ; + unsigned long j_state; unsigned long j_len ; atomic_t j_nonzerolen ; atomic_t j_commit_left ; - atomic_t j_flushing ; - atomic_t j_commit_flushing ; atomic_t j_older_commits_done ; /* all commits older than this on disk*/ + struct semaphore j_commit_lock; unsigned long j_trans_id ; time_t j_timestamp ; struct reiserfs_list_bitmap *j_list_bitmap ; struct buffer_head *j_commit_bh ; /* commit buffer head */ struct reiserfs_journal_cnode *j_realblock ; struct reiserfs_journal_cnode *j_freedlist ; /* list of buffers that were freed during this trans. free each of these on flush */ - wait_queue_head_t j_commit_wait ; /* wait for all the commit blocks to be flushed */ - wait_queue_head_t j_flush_wait ; /* wait for all the real blocks to be flushed */ -} ; + /* time ordered list of all active transactions */ + struct list_head j_list; -struct reiserfs_page_list ; /* defined in reiserfs_fs.h */ + /* time ordered list of all transactions we haven't tried to flush yet */ + struct list_head j_working_list; + int j_refcount; +} ; struct reiserfs_journal { struct buffer_head ** j_ap_blocks ; /* journal blocks on disk */ @@ -220,16 +202,11 @@ struct reiserfs_journal { unsigned long j_last_flush_trans_id ; /* last fully flushed journal timestamp */ struct buffer_head *j_header_bh ; - /* j_flush_pages must be flushed before the current transaction can - ** commit - */ - struct reiserfs_page_list *j_flush_pages ; time_t j_trans_start_time ; /* time this transaction started */ - wait_queue_head_t j_wait ; /* wait journal_end to finish I/O */ - atomic_t j_wlock ; /* lock for j_wait */ + struct semaphore j_lock; + struct semaphore j_flush_sem; wait_queue_head_t j_join_wait ; /* wait for current transaction to finish before starting new one */ atomic_t j_jlock ; /* lock for j_join_wait */ - int j_journal_list_index ; /* journal list number of the current trans */ int j_list_bitmap_index ; /* number of next list bitmap to use */ int j_must_wait ; /* no more journal begins allowed. MUST sleep on j_join_wait */ int j_next_full_flush ; /* next journal_end will flush all journal list */ @@ -246,19 +223,37 @@ struct reiserfs_journal { struct reiserfs_journal_cnode *j_cnode_free_list ; struct reiserfs_journal_cnode *j_cnode_free_orig ; /* orig pointer returned from vmalloc */ + struct reiserfs_journal_list *j_current_jl; int j_free_bitmap_nodes ; int j_used_bitmap_nodes ; + + int j_num_lists; /* total number of active transactions */ + int j_num_work_lists; /* number that need attention from kreiserfsd */ + + /* debugging to make sure things are flushed in order */ + int j_last_flush_id; + + /* debugging to make sure things are committed in order */ + int j_last_commit_id; + struct list_head j_bitmap_nodes ; struct list_head j_dirty_buffers ; spinlock_t j_dirty_buffers_lock ; /* protects j_dirty_buffers */ + + /* list of all active transactions */ + struct list_head j_journal_list; + /* lists that haven't been touched by writeback attempts */ + struct list_head j_working_list; + struct reiserfs_list_bitmap j_list_bitmap[JOURNAL_NUM_BITMAPS] ; /* array of bitmaps to record the deleted blocks */ - struct reiserfs_journal_list j_journal_list[JOURNAL_LIST_COUNT] ; /* array of all the journal lists */ struct reiserfs_journal_cnode *j_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for real buffer heads in current trans */ struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for all the real buffer heads in all the transactions */ struct list_head j_prealloc_list; /* list of inodes which have preallocated blocks */ unsigned long j_max_trans_size ; unsigned long j_max_batch_size ; + + struct work_struct j_work; }; #define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick. magic string to find desc blocks in the journal */ @@ -417,7 +412,6 @@ struct reiserfs_sb_info #define REISERFS_LARGETAIL 0 /* large tails will be created in a session */ #define REISERFS_SMALLTAIL 17 /* small (for files less than block size) tails will be created in a session */ #define REPLAYONLY 3 /* replay journal and return 0. Use by fsck */ -#define REISERFS_NOLOG 4 /* -o nolog: turn journalling off */ #define REISERFS_CONVERT 5 /* -o conv: causes conversion of old format super block to the new format. If not specified - old @@ -473,8 +467,6 @@ struct reiserfs_sb_info void reiserfs_file_buffer (struct buffer_head * bh, int list); extern struct file_system_type reiserfs_fs_type; -int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ; -int flush_old_commits(struct super_block *s, int) ; int reiserfs_resize(struct super_block *, unsigned long) ; #define CARRY_ON 0 @@ -484,8 +476,6 @@ int reiserfs_resize(struct super_block *, unsigned long) ; #define SB_BUFFER_WITH_SB(s) (REISERFS_SB(s)->s_sbh) #define SB_JOURNAL(s) (REISERFS_SB(s)->s_journal) #define SB_JOURNAL_1st_RESERVED_BLOCK(s) (SB_JOURNAL(s)->j_1st_reserved_block) -#define SB_JOURNAL_LIST(s) (SB_JOURNAL(s)->j_journal_list) -#define SB_JOURNAL_LIST_INDEX(s) (SB_JOURNAL(s)->j_journal_list_index) #define SB_JOURNAL_LEN_FREE(s) (SB_JOURNAL(s)->j_journal_len_free) #define SB_AP_BITMAP(s) (REISERFS_SB(s)->s_ap_bitmap) |
