Commit 7c563ced authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent 8f576882
...@@ -30,32 +30,11 @@ struct tree_balance * cur_tb = NULL; /* detects whether more than one ...@@ -30,32 +30,11 @@ struct tree_balance * cur_tb = NULL; /* detects whether more than one
is interrupting do_balance */ is interrupting do_balance */
#endif #endif
/*
* AKPM: The __mark_buffer_dirty() call here will not
* put the buffer on the dirty buffer LRU because we've just
* set BH_Dirty. That's a thinko in reiserfs.
*
* I'm reluctant to "fix" this bug because that would change
* behaviour. Using mark_buffer_dirty() here would make the
* buffer eligible for VM and periodic writeback, which may
* violate ordering constraints. I'll just leave the code
* as-is by removing the __mark_buffer_dirty call altogether.
*
* Chris says this code has "probably never been run" anyway.
* It is due to go away.
*/
inline void do_balance_mark_leaf_dirty (struct tree_balance * tb, inline void do_balance_mark_leaf_dirty (struct tree_balance * tb,
struct buffer_head * bh, int flag) struct buffer_head * bh, int flag)
{ {
if (reiserfs_dont_log(tb->tb_sb)) { journal_mark_dirty(tb->transaction_handle,
if (!test_set_buffer_dirty(bh)) { tb->transaction_handle->t_super, bh) ;
// __mark_buffer_dirty(bh) ;
tb->need_balance_dirty = 1;
}
} else {
journal_mark_dirty(tb->transaction_handle, tb->transaction_handle->t_super, bh) ;
}
} }
#define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty #define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
......
...@@ -2106,9 +2106,9 @@ static void tb_buffer_sanity_check (struct super_block * p_s_sb, ...@@ -2106,9 +2106,9 @@ static void tb_buffer_sanity_check (struct super_block * p_s_sb,
{;} {;}
#endif #endif
static void clear_all_dirty_bits(struct super_block *s, static int clear_all_dirty_bits(struct super_block *s,
struct buffer_head *bh) { struct buffer_head *bh) {
reiserfs_prepare_for_journal(s, bh, 0) ; return reiserfs_prepare_for_journal(s, bh, 0) ;
} }
static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb) static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb)
...@@ -2137,13 +2137,13 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb) ...@@ -2137,13 +2137,13 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb)
p_s_tb->tb_path->path_length - i); p_s_tb->tb_path->path_length - i);
} }
#endif #endif
clear_all_dirty_bits(p_s_tb->tb_sb, if (!clear_all_dirty_bits(p_s_tb->tb_sb,
PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i)) ; PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i)))
{
if ( buffer_locked (PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i)) )
locked = PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i); locked = PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i);
} }
} }
}
for ( i = 0; !locked && i < MAX_HEIGHT && p_s_tb->insert_size[i]; i++ ) { for ( i = 0; !locked && i < MAX_HEIGHT && p_s_tb->insert_size[i]; i++ ) {
...@@ -2151,22 +2151,19 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb) ...@@ -2151,22 +2151,19 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb)
if ( p_s_tb->L[i] ) { if ( p_s_tb->L[i] ) {
tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->L[i], "L", i); tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->L[i], "L", i);
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->L[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->L[i]))
if ( buffer_locked (p_s_tb->L[i]) )
locked = p_s_tb->L[i]; locked = p_s_tb->L[i];
} }
if ( !locked && p_s_tb->FL[i] ) { if ( !locked && p_s_tb->FL[i] ) {
tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FL[i], "FL", i); tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FL[i], "FL", i);
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FL[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FL[i]))
if ( buffer_locked (p_s_tb->FL[i]) )
locked = p_s_tb->FL[i]; locked = p_s_tb->FL[i];
} }
if ( !locked && p_s_tb->CFL[i] ) { if ( !locked && p_s_tb->CFL[i] ) {
tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFL[i], "CFL", i); tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFL[i], "CFL", i);
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFL[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFL[i]))
if ( buffer_locked (p_s_tb->CFL[i]) )
locked = p_s_tb->CFL[i]; locked = p_s_tb->CFL[i];
} }
...@@ -2176,23 +2173,20 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb) ...@@ -2176,23 +2173,20 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb)
if ( p_s_tb->R[i] ) { if ( p_s_tb->R[i] ) {
tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->R[i], "R", i); tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->R[i], "R", i);
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->R[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->R[i]))
if ( buffer_locked (p_s_tb->R[i]) )
locked = p_s_tb->R[i]; locked = p_s_tb->R[i];
} }
if ( !locked && p_s_tb->FR[i] ) { if ( !locked && p_s_tb->FR[i] ) {
tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FR[i], "FR", i); tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FR[i], "FR", i);
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FR[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FR[i]))
if ( buffer_locked (p_s_tb->FR[i]) )
locked = p_s_tb->FR[i]; locked = p_s_tb->FR[i];
} }
if ( !locked && p_s_tb->CFR[i] ) { if ( !locked && p_s_tb->CFR[i] ) {
tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFR[i], "CFR", i); tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFR[i], "CFR", i);
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFR[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFR[i]))
if ( buffer_locked (p_s_tb->CFR[i]) )
locked = p_s_tb->CFR[i]; locked = p_s_tb->CFR[i];
} }
} }
...@@ -2207,12 +2201,10 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb) ...@@ -2207,12 +2201,10 @@ static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb)
*/ */
for ( i = 0; !locked && i < MAX_FEB_SIZE; i++ ) { for ( i = 0; !locked && i < MAX_FEB_SIZE; i++ ) {
if ( p_s_tb->FEB[i] ) { if ( p_s_tb->FEB[i] ) {
clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FEB[i]) ; if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FEB[i]))
if (buffer_locked(p_s_tb->FEB[i])) {
locked = p_s_tb->FEB[i] ; locked = p_s_tb->FEB[i] ;
} }
} }
}
if (locked) { if (locked) {
#ifdef CONFIG_REISERFS_CHECK #ifdef CONFIG_REISERFS_CHECK
......
...@@ -633,7 +633,6 @@ static void balance_internal_when_delete (struct tree_balance * tb, ...@@ -633,7 +633,6 @@ static void balance_internal_when_delete (struct tree_balance * tb,
/* use check_internal if new root is an internal node */ /* use check_internal if new root is an internal node */
check_internal (new_root); check_internal (new_root);
/*&&&&&&&&&&&&&&&&&&&&&&*/ /*&&&&&&&&&&&&&&&&&&&&&&*/
tb->tb_sb->s_dirt = 1;
/* do what is needed for buffer thrown from tree */ /* do what is needed for buffer thrown from tree */
reiserfs_invalidate_buffer(tb, tbSh); reiserfs_invalidate_buffer(tb, tbSh);
...@@ -951,7 +950,6 @@ int balance_internal (struct tree_balance * tb, /* tree_balance structure */ ...@@ -951,7 +950,6 @@ int balance_internal (struct tree_balance * tb, /* tree_balance structure */
PUT_SB_ROOT_BLOCK( tb->tb_sb, tbSh->b_blocknr ); PUT_SB_ROOT_BLOCK( tb->tb_sb, tbSh->b_blocknr );
PUT_SB_TREE_HEIGHT( tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) + 1 ); PUT_SB_TREE_HEIGHT( tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) + 1 );
do_balance_mark_sb_dirty (tb, REISERFS_SB(tb->tb_sb)->s_sbh, 1); do_balance_mark_sb_dirty (tb, REISERFS_SB(tb->tb_sb)->s_sbh, 1);
tb->tb_sb->s_dirt = 1;
} }
if ( tb->blknum[h] == 2 ) { if ( tb->blknum[h] == 2 ) {
......
...@@ -964,7 +964,7 @@ static void init_inode (struct inode * inode, struct path * path) ...@@ -964,7 +964,7 @@ static void init_inode (struct inode * inode, struct path * path)
REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_block = 0;
REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_trans_index = 0; REISERFS_I(inode)->i_jl = NULL;
if (stat_data_v1 (ih)) { if (stat_data_v1 (ih)) {
struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih); struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
...@@ -1621,7 +1621,7 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th, ...@@ -1621,7 +1621,7 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_block = 0;
REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_trans_index = 0; REISERFS_I(inode)->i_jl = 0;
REISERFS_I(inode)->i_attrs = REISERFS_I(inode)->i_attrs =
REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode ); sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode );
......
This diff is collapsed.
...@@ -86,7 +86,6 @@ __u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th) ...@@ -86,7 +86,6 @@ __u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th)
} }
journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s)); journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s));
s->s_dirt = 1;
return unused_objectid; return unused_objectid;
} }
...@@ -105,8 +104,6 @@ void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, ...@@ -105,8 +104,6 @@ void reiserfs_release_objectid (struct reiserfs_transaction_handle *th,
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ; reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s)); journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s));
s->s_dirt = 1;
/* start at the beginning of the objectid map (i = 0) and go to /* start at the beginning of the objectid map (i = 0) and go to
the end of it (i = disk_sb->s_oid_cursize). Linear search is the end of it (i = disk_sb->s_oid_cursize). Linear search is
......
...@@ -87,7 +87,7 @@ static int show_super(struct seq_file *m, struct super_block *sb) ...@@ -87,7 +87,7 @@ static int show_super(struct seq_file *m, struct super_block *sb)
struct reiserfs_sb_info *r = REISERFS_SB(sb); struct reiserfs_sb_info *r = REISERFS_SB(sb);
seq_printf(m, "state: \t%s\n" seq_printf(m, "state: \t%s\n"
"mount options: \t%s%s%s%s%s%s%s%s%s%s%s%s\n" "mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n"
"gen. counter: \t%i\n" "gen. counter: \t%i\n"
"s_kmallocs: \t%i\n" "s_kmallocs: \t%i\n"
"s_disk_reads: \t%i\n" "s_disk_reads: \t%i\n"
...@@ -131,7 +131,6 @@ static int show_super(struct seq_file *m, struct super_block *sb) ...@@ -131,7 +131,6 @@ static int show_super(struct seq_file *m, struct super_block *sb)
reiserfs_test4( sb ) ? "TEST4 " : "", reiserfs_test4( sb ) ? "TEST4 " : "",
have_large_tails( sb ) ? "TAILS " : have_small_tails(sb)?"SMALL_TAILS ":"NO_TAILS ", have_large_tails( sb ) ? "TAILS " : have_small_tails(sb)?"SMALL_TAILS ":"NO_TAILS ",
replay_only( sb ) ? "REPLAY_ONLY " : "", replay_only( sb ) ? "REPLAY_ONLY " : "",
reiserfs_dont_log( sb ) ? "DONT_LOG " : "LOG ",
convert_reiserfs( sb ) ? "CONV " : "", convert_reiserfs( sb ) ? "CONV " : "",
atomic_read( &r -> s_generation_counter ), atomic_read( &r -> s_generation_counter ),
...@@ -370,7 +369,6 @@ static int show_journal(struct seq_file *m, struct super_block *sb) ...@@ -370,7 +369,6 @@ static int show_journal(struct seq_file *m, struct super_block *sb)
"j_first_unflushed_offset: \t%lu\n" "j_first_unflushed_offset: \t%lu\n"
"j_last_flush_trans_id: \t%lu\n" "j_last_flush_trans_id: \t%lu\n"
"j_trans_start_time: \t%li\n" "j_trans_start_time: \t%li\n"
"j_journal_list_index: \t%i\n"
"j_list_bitmap_index: \t%i\n" "j_list_bitmap_index: \t%i\n"
"j_must_wait: \t%i\n" "j_must_wait: \t%i\n"
"j_next_full_flush: \t%i\n" "j_next_full_flush: \t%i\n"
...@@ -416,7 +414,6 @@ static int show_journal(struct seq_file *m, struct super_block *sb) ...@@ -416,7 +414,6 @@ static int show_journal(struct seq_file *m, struct super_block *sb)
JF( j_first_unflushed_offset ), JF( j_first_unflushed_offset ),
JF( j_last_flush_trans_id ), JF( j_last_flush_trans_id ),
JF( j_trans_start_time ), JF( j_trans_start_time ),
JF( j_journal_list_index ),
JF( j_list_bitmap_index ), JF( j_list_bitmap_index ),
JF( j_must_wait ), JF( j_must_wait ),
JF( j_next_full_flush ), JF( j_next_full_flush ),
......
...@@ -59,22 +59,26 @@ static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs) ...@@ -59,22 +59,26 @@ static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs)
static int reiserfs_remount (struct super_block * s, int * flags, char * data); static int reiserfs_remount (struct super_block * s, int * flags, char * data);
static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf); static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
static void reiserfs_write_super (struct super_block * s) static void reiserfs_sync_fs (struct super_block * s)
{ {
int dirty = 0 ;
reiserfs_write_lock(s);
if (!(s->s_flags & MS_RDONLY)) { if (!(s->s_flags & MS_RDONLY)) {
dirty = flush_old_commits(s, 1) ; struct reiserfs_transaction_handle th;
} reiserfs_write_lock(s);
s->s_dirt = dirty; journal_begin(&th, s, 1);
journal_end_sync(&th, s, 1);
reiserfs_flush_old_commits(s);
s->s_dirt = 0;
reiserfs_write_unlock(s); reiserfs_write_unlock(s);
}
} }
static void reiserfs_write_super_lockfs (struct super_block * s) static void reiserfs_write_super(struct super_block *s)
{ {
reiserfs_sync_fs(s);
}
int dirty = 0 ; static void reiserfs_write_super_lockfs (struct super_block * s)
{
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
reiserfs_write_lock(s); reiserfs_write_lock(s);
if (!(s->s_flags & MS_RDONLY)) { if (!(s->s_flags & MS_RDONLY)) {
...@@ -84,7 +88,7 @@ static void reiserfs_write_super_lockfs (struct super_block * s) ...@@ -84,7 +88,7 @@ static void reiserfs_write_super_lockfs (struct super_block * s)
reiserfs_block_writes(&th) ; reiserfs_block_writes(&th) ;
journal_end(&th, s, 1) ; journal_end(&th, s, 1) ;
} }
s->s_dirt = dirty; s->s_dirt = 0;
reiserfs_write_unlock(s); reiserfs_write_unlock(s);
} }
...@@ -805,7 +809,6 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a ...@@ -805,7 +809,6 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ; reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
set_sb_umount_state( rs, REISERFS_SB(s)->s_mount_state ); set_sb_umount_state( rs, REISERFS_SB(s)->s_mount_state );
journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
s->s_dirt = 0;
} else { } else {
/* remount read-write */ /* remount read-write */
if (!(s->s_flags & MS_RDONLY)) if (!(s->s_flags & MS_RDONLY))
...@@ -822,12 +825,12 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a ...@@ -822,12 +825,12 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a
set_sb_umount_state( rs, REISERFS_ERROR_FS ); set_sb_umount_state( rs, REISERFS_ERROR_FS );
/* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */ /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
s->s_dirt = 0;
REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS ; REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS ;
} }
/* this will force a full flush of all journal lists */ /* this will force a full flush of all journal lists */
SB_JOURNAL(s)->j_must_wait = 1 ; SB_JOURNAL(s)->j_must_wait = 1 ;
journal_end(&th, s, 10) ; journal_end(&th, s, 10) ;
s->s_dirt = 0;
if (!( *mount_flags & MS_RDONLY ) ) if (!( *mount_flags & MS_RDONLY ) )
finish_unfinished( s ); finish_unfinished( s );
...@@ -1392,8 +1395,6 @@ static int reiserfs_fill_super (struct super_block * s, void * data, int silent) ...@@ -1392,8 +1395,6 @@ static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
/* look for files which were to be removed in previous session */ /* look for files which were to be removed in previous session */
finish_unfinished (s); finish_unfinished (s);
s->s_dirt = 0;
} else { } else {
if ( old_format_only(s) && !silent) { if ( old_format_only(s) && !silent) {
reiserfs_warning("reiserfs: using 3.5.x disk format\n") ; reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
......
...@@ -1702,23 +1702,39 @@ struct reiserfs_journal_header { ...@@ -1702,23 +1702,39 @@ struct reiserfs_journal_header {
(((block)<<(JBH_HASH_SHIFT - 6)) ^ ((block) >> 13) ^ ((block) << (JBH_HASH_SHIFT - 12)))) (((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]) #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 // 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_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_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) #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_commit_for_inode(struct inode *) ;
void reiserfs_update_inode_transaction(struct inode *) ; void reiserfs_update_inode_transaction(struct inode *) ;
void reiserfs_wait_on_write_block(struct super_block *s) ; void reiserfs_wait_on_write_block(struct super_block *s) ;
void reiserfs_block_writes(struct reiserfs_transaction_handle *th) ; void reiserfs_block_writes(struct reiserfs_transaction_handle *th) ;
void reiserfs_allow_writes(struct super_block *s) ; void reiserfs_allow_writes(struct super_block *s) ;
void reiserfs_check_lock_depth(char *caller) ; 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) ; 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_init(struct super_block *, const char * j_dev_name, int old_format, unsigned int) ;
int journal_release(struct reiserfs_transaction_handle*, struct super_block *) ; 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 ...@@ -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 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 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) ; 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 buffer_journaled(const struct buffer_head *bh) ;
int mark_buffer_journal_new(struct buffer_head *bh) ; int mark_buffer_journal_new(struct buffer_head *bh) ;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <linux/list.h> #include <linux/list.h>
struct reiserfs_journal_list;
/** bitmasks for i_flags field in reiserfs-specific part of inode */ /** bitmasks for i_flags field in reiserfs-specific part of inode */
typedef enum { typedef enum {
/** this says what format of key do all items (but stat data) of /** this says what format of key do all items (but stat data) of
...@@ -48,7 +50,7 @@ struct reiserfs_inode_info { ...@@ -48,7 +50,7 @@ struct reiserfs_inode_info {
** needs to be committed in order for this inode to be properly ** needs to be committed in order for this inode to be properly
** flushed */ ** flushed */
unsigned long i_trans_id ; unsigned long i_trans_id ;
unsigned long i_trans_index ; struct reiserfs_journal_list *i_jl;
struct inode vfs_inode; struct inode vfs_inode;
}; };
......
...@@ -106,7 +106,6 @@ typedef enum { ...@@ -106,7 +106,6 @@ typedef enum {
#define JOURNAL_MAX_CNODE 1500 /* max cnodes to allocate. */ #define JOURNAL_MAX_CNODE 1500 /* max cnodes to allocate. */
#define JOURNAL_HASH_SIZE 8192 #define JOURNAL_HASH_SIZE 8192
#define JOURNAL_NUM_BITMAPS 5 /* number of copies of the bitmaps to have floating. Must be >= 2 */ #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 */ /* these are bh_state bit flag offset numbers, for use in the buffer head */
...@@ -121,6 +120,7 @@ typedef enum { ...@@ -121,6 +120,7 @@ typedef enum {
*/ */
#define BH_JPrepared 20 /* block has been prepared for the log */ #define BH_JPrepared 20 /* block has been prepared for the log */
#define BH_JRestore_dirty 22 /* restore the dirty bit later */ #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 /* 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 ** Each one is in two hash tables. First, a hash of the current transaction, and after journal_end, a
...@@ -153,26 +153,6 @@ struct reiserfs_list_bitmap { ...@@ -153,26 +153,6 @@ struct reiserfs_list_bitmap {
struct reiserfs_bitmap_node **bitmaps ; struct reiserfs_bitmap_node **bitmaps ;
} ; } ;
/*
** 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. ** 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 ** this list of cnodes is used to hash all the blocks in all the commits, to mark all the
...@@ -181,23 +161,25 @@ struct reiserfs_transaction_handle { ...@@ -181,23 +161,25 @@ struct reiserfs_transaction_handle {
** to be overwritten */ ** to be overwritten */
struct reiserfs_journal_list { struct reiserfs_journal_list {
unsigned long j_start ; unsigned long j_start ;
unsigned long j_state;
unsigned long j_len ; unsigned long j_len ;
atomic_t j_nonzerolen ; atomic_t j_nonzerolen ;
atomic_t j_commit_left ; 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*/ atomic_t j_older_commits_done ; /* all commits older than this on disk*/
struct semaphore j_commit_lock;
unsigned long j_trans_id ; unsigned long j_trans_id ;
time_t j_timestamp ; time_t j_timestamp ;
struct reiserfs_list_bitmap *j_list_bitmap ; struct reiserfs_list_bitmap *j_list_bitmap ;
struct buffer_head *j_commit_bh ; /* commit buffer head */ struct buffer_head *j_commit_bh ; /* commit buffer head */
struct reiserfs_journal_cnode *j_realblock ; 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 */ 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 */ /* time ordered list of all active transactions */
wait_queue_head_t j_flush_wait ; /* wait for all the real blocks to be flushed */ 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 reiserfs_journal {
struct buffer_head ** j_ap_blocks ; /* journal blocks on disk */ struct buffer_head ** j_ap_blocks ; /* journal blocks on disk */
...@@ -220,16 +202,11 @@ struct reiserfs_journal { ...@@ -220,16 +202,11 @@ struct reiserfs_journal {
unsigned long j_last_flush_trans_id ; /* last fully flushed journal timestamp */ unsigned long j_last_flush_trans_id ; /* last fully flushed journal timestamp */
struct buffer_head *j_header_bh ; 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 */ time_t j_trans_start_time ; /* time this transaction started */
wait_queue_head_t j_wait ; /* wait journal_end to finish I/O */ struct semaphore j_lock;
atomic_t j_wlock ; /* lock for j_wait */ struct semaphore j_flush_sem;
wait_queue_head_t j_join_wait ; /* wait for current transaction to finish before starting new one */ 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 */ 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_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_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 */ int j_next_full_flush ; /* next journal_end will flush all journal list */
...@@ -246,19 +223,37 @@ struct reiserfs_journal { ...@@ -246,19 +223,37 @@ struct reiserfs_journal {
struct reiserfs_journal_cnode *j_cnode_free_list ; struct reiserfs_journal_cnode *j_cnode_free_list ;
struct reiserfs_journal_cnode *j_cnode_free_orig ; /* orig pointer returned from vmalloc */ 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_free_bitmap_nodes ;
int j_used_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_bitmap_nodes ;
struct list_head j_dirty_buffers ; struct list_head j_dirty_buffers ;
spinlock_t j_dirty_buffers_lock ; /* protects 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_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_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 struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for all the real buffer heads in all
the transactions */ the transactions */
struct list_head j_prealloc_list; /* list of inodes which have preallocated blocks */ struct list_head j_prealloc_list; /* list of inodes which have preallocated blocks */
unsigned long j_max_trans_size ; unsigned long j_max_trans_size ;
unsigned long j_max_batch_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 */ #define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick. magic string to find desc blocks in the journal */
...@@ -417,7 +412,6 @@ struct reiserfs_sb_info ...@@ -417,7 +412,6 @@ struct reiserfs_sb_info
#define REISERFS_LARGETAIL 0 /* large tails will be created in a session */ #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 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 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 #define REISERFS_CONVERT 5 /* -o conv: causes conversion of old
format super block to the new format super block to the new
format. If not specified - old format. If not specified - old
...@@ -473,8 +467,6 @@ struct reiserfs_sb_info ...@@ -473,8 +467,6 @@ struct reiserfs_sb_info
void reiserfs_file_buffer (struct buffer_head * bh, int list); void reiserfs_file_buffer (struct buffer_head * bh, int list);
extern struct file_system_type reiserfs_fs_type; 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) ; int reiserfs_resize(struct super_block *, unsigned long) ;
#define CARRY_ON 0 #define CARRY_ON 0
...@@ -484,8 +476,6 @@ int reiserfs_resize(struct super_block *, unsigned long) ; ...@@ -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_BUFFER_WITH_SB(s) (REISERFS_SB(s)->s_sbh)
#define SB_JOURNAL(s) (REISERFS_SB(s)->s_journal) #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_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_JOURNAL_LEN_FREE(s) (SB_JOURNAL(s)->j_journal_len_free)
#define SB_AP_BITMAP(s) (REISERFS_SB(s)->s_ap_bitmap) #define SB_AP_BITMAP(s) (REISERFS_SB(s)->s_ap_bitmap)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment