diff -rup linux/Documentation/Configure.help linux.patched/Documentation/Configure.help --- linux/Documentation/Configure.help Sun Sep 23 20:52:38 2001 +++ linux.patched/Documentation/Configure.help Thu Oct 11 14:42:15 2001 @@ -11846,6 +11846,15 @@ CONFIG_REISERFS_CHECK report, say yes and you might get a useful error message. Almost everyone should say no. +Publish some reiserfs-specific info under /proc/fs/reiserfs +CONFIG_REISERFS_PROC_INFO + Create under /proc/fs/reiserfs hierarchy of files, displaying + various ReiserFS statistics and internal data on the expense of + making your kernel or module slightly larger (+8K). This also increases + amount of kernel memory required for each mount. Almost everyone + but ReiserFS developers and people fine-tuning reiserfs or tracing + problems should say NO. + Second extended fs support CONFIG_EXT2_FS This is the de facto standard Linux file system (method to organize diff -rup linux/fs/Config.in linux.patched/fs/Config.in --- linux/fs/Config.in Tue Jul 3 01:03:04 2001 +++ linux.patched/fs/Config.in Thu Oct 11 14:42:15 2001 @@ -10,6 +10,7 @@ tristate 'Kernel automounter version 4 s dep_tristate 'Reiserfs support' CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL +dep_mbool ' Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'ADFS file system support' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL diff -rup linux/fs/reiserfs/Makefile linux.patched/fs/reiserfs/Makefile --- linux/fs/reiserfs/Makefile Mon Jan 15 23:42:32 2001 +++ linux.patched/fs/reiserfs/Makefile Thu Oct 11 14:42:15 2001 @@ -9,7 +9,7 @@ O_TARGET := reiserfs.o obj-y := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o super.o prints.o objectid.o \ -lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o tail_conversion.o version.o item_ops.o ioctl.o +lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o tail_conversion.o version.o item_ops.o ioctl.o procfs.o obj-m := $(O_TARGET) diff -rup linux/fs/reiserfs/bitmap.c linux.patched/fs/reiserfs/bitmap.c --- linux/fs/reiserfs/bitmap.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/bitmap.c Thu Oct 11 14:42:15 2001 @@ -117,6 +117,8 @@ void reiserfs_free_block (struct reiserf reiserfs_panic (s, "vs-4070: reiserfs_free_block: can not free such block"); #endif + PROC_INFO_INC( s, free_block ); + rs = SB_DISK_SUPER_BLOCK (s); sbh = SB_BUFFER_WITH_SB (s); apbh = SB_AP_BITMAP (s); @@ -158,10 +160,14 @@ static int find_forward (struct super_bl unsigned long block_to_try = 0; unsigned long next_block_to_try = 0 ; - for (i = *bmap_nr; i < SB_BMAP_NR (s); i ++, *offset = 0) { + PROC_INFO_INC( s, find_forward.call ); + + for (i = *bmap_nr; i < SB_BMAP_NR (s); i ++, *offset = 0, + PROC_INFO_INC( s, find_forward.bmap )) { /* get corresponding bitmap block */ bh = SB_AP_BITMAP (s)[i]; if (buffer_locked (bh)) { + PROC_INFO_INC( s, find_forward.wait ); __wait_on_buffer (bh); } retry: @@ -196,17 +202,21 @@ retry: int new_i ; get_bit_address (s, next_block_to_try, &new_i, offset); + PROC_INFO_INC( s, find_forward.in_journal_hint ); + /* block is not in this bitmap. reset i and continue ** we only reset i if new_i is in a later bitmap. */ if (new_i > i) { i = (new_i - 1 ); /* i gets incremented by the for loop */ + PROC_INFO_INC( s, find_forward.in_journal_out ); continue ; } } else { /* no suggestion was made, just try the next block */ *offset = j+1 ; } + PROC_INFO_INC( s, find_forward.retry ); goto retry ; } } diff -rup linux/fs/reiserfs/buffer2.c linux.patched/fs/reiserfs/buffer2.c --- linux/fs/reiserfs/buffer2.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/buffer2.c Thu Oct 11 14:42:15 2001 @@ -16,6 +16,7 @@ #include #include #include +#include /* * wait_buffer_until_released @@ -63,9 +64,16 @@ void wait_buffer_until_released (struct block. */ /* The function is NOT SCHEDULE-SAFE! */ -struct buffer_head * reiserfs_bread (kdev_t n_dev, int n_block, int n_size) +struct buffer_head * reiserfs_bread (struct super_block *super, int n_block, int n_size) { - return bread (n_dev, n_block, n_size); + struct buffer_head *result; + PROC_EXP( unsigned int ctx_switches = kstat.context_swtch ); + + result = bread (super -> s_dev, n_block, n_size); + PROC_INFO_INC( super, breads ); + PROC_EXP( if( kstat.context_swtch != ctx_switches ) + PROC_INFO_INC( super, bread_miss ) ); + return result; } /* This function looks for a buffer which contains a given block. If diff -rup linux/fs/reiserfs/do_balan.c linux.patched/fs/reiserfs/do_balan.c --- linux/fs/reiserfs/do_balan.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/do_balan.c Thu Oct 11 14:42:15 2001 @@ -366,6 +366,9 @@ static int balance_leaf (struct tree_bal tb->insert_size [0]); } #endif + + PROC_INFO_INC( tb -> tb_sb, balance_at[ 0 ] ); + /* Make balance in case insert_size[0] < 0 */ if ( tb->insert_size[0] < 0 ) return balance_leaf_when_delete (tb, flag); diff -rup linux/fs/reiserfs/fix_node.c linux.patched/fs/reiserfs/fix_node.c --- linux/fs/reiserfs/fix_node.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/fix_node.c Thu Oct 11 14:42:15 2001 @@ -625,6 +625,11 @@ static void set_parameters (struct tree_ tb->lbytes = lb; tb->rbytes = rb; } + PROC_INFO_ADD( tb -> tb_sb, lnum[ h ], lnum ); + PROC_INFO_ADD( tb -> tb_sb, rnum[ h ], rnum ); + + PROC_INFO_ADD( tb -> tb_sb, lbytes[ h ], lb ); + PROC_INFO_ADD( tb -> tb_sb, rbytes[ h ], rb ); } @@ -721,6 +726,7 @@ static int are_leaves_removable (struct if (MAX_CHILD_SIZE (S0) + vn->vn_size <= rfree + lfree + ih_size) { set_parameters (tb, 0, -1, -1, -1, NULL, -1, -1); + PROC_INFO_INC( tb -> tb_sb, leaves_removable ); return 1; } return 0; @@ -1274,6 +1280,7 @@ static inline int can_node_be_removed (i return NO_BALANCING_NEEDED; } } + PROC_INFO_INC( tb -> tb_sb, can_node_be_removed[ h ] ); return !NO_BALANCING_NEEDED; } @@ -2027,8 +2034,11 @@ static int get_neighbors( struct buffer_head * p_s_bh; + PROC_INFO_INC( p_s_sb, get_neighbors[ n_h ] ); + if ( p_s_tb->lnum[n_h] ) { /* We need left neighbor to balance S[n_h]. */ + PROC_INFO_INC( p_s_sb, need_l_neighbor[ n_h ] ); p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset); #ifdef CONFIG_REISERFS_CHECK @@ -2038,11 +2048,12 @@ static int get_neighbors( n_child_position = ( p_s_bh == p_s_tb->FL[n_h] ) ? p_s_tb->lkey[n_h] : B_NR_ITEMS (p_s_tb->FL[n_h]); n_son_number = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position); - p_s_bh = reiserfs_bread(p_s_sb->s_dev, n_son_number, p_s_sb->s_blocksize); + p_s_bh = reiserfs_bread(p_s_sb, n_son_number, p_s_sb->s_blocksize); if (!p_s_bh) return IO_ERROR; if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) { decrement_bcount(p_s_bh); + PROC_INFO_INC( p_s_sb, get_neighbors_restart[ n_h ] ); return REPEAT_SEARCH; } @@ -2063,6 +2074,7 @@ static int get_neighbors( if ( p_s_tb->rnum[n_h] ) { /* We need right neighbor to balance S[n_path_offset]. */ + PROC_INFO_INC( p_s_sb, need_r_neighbor[ n_h ] ); p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset); #ifdef CONFIG_REISERFS_CHECK @@ -2072,11 +2084,12 @@ static int get_neighbors( n_child_position = ( p_s_bh == p_s_tb->FR[n_h] ) ? p_s_tb->rkey[n_h] + 1 : 0; n_son_number = B_N_CHILD_NUM(p_s_tb->FR[n_h], n_child_position); - p_s_bh = reiserfs_bread(p_s_sb->s_dev, n_son_number, p_s_sb->s_blocksize); + p_s_bh = reiserfs_bread(p_s_sb, n_son_number, p_s_sb->s_blocksize); if (!p_s_bh) return IO_ERROR; if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) { decrement_bcount(p_s_bh); + PROC_INFO_INC( p_s_sb, get_neighbors_restart[ n_h ] ); return REPEAT_SEARCH; } decrement_bcount(p_s_tb->R[n_h]); @@ -2426,6 +2439,8 @@ int fix_nodes (int n_op_mode, int wait_tb_buffers_run = 0 ; int windex ; struct buffer_head * p_s_tbS0 = PATH_PLAST_BUFFER(p_s_tb->tb_path); + + ++ p_s_tb -> tb_sb -> u.reiserfs_sb.s_fix_nodes; n_pos_in_item = p_s_tb->tb_path->pos_in_item; diff -rup linux/fs/reiserfs/ibalance.c linux.patched/fs/reiserfs/ibalance.c --- linux/fs/reiserfs/ibalance.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/ibalance.c Thu Oct 11 14:42:15 2001 @@ -815,6 +815,8 @@ int balance_internal (struct tree_balanc reiserfs_panic (tb->tb_sb, "balance_internal", "h (%d) can not be < 1 on internal level", h); #endif /* CONFIG_REISERFS_CHECK */ + PROC_INFO_INC( tb -> tb_sb, balance_at[ h ] ); + order = ( tbSh ) ? PATH_H_POSITION (tb->tb_path, h + 1)/*tb->S[h]->b_item_order*/ : 0; /* Using insert_size[h] calculate the number insert_num of items diff -rup linux/fs/reiserfs/journal.c linux.patched/fs/reiserfs/journal.c --- linux/fs/reiserfs/journal.c Sun Sep 23 20:49:45 2001 +++ linux.patched/fs/reiserfs/journal.c Thu Oct 11 14:42:15 2001 @@ -520,12 +520,14 @@ int reiserfs_in_journal(struct super_blo return 0 ; } + PROC_INFO_INC( p_s_sb, journal.in_journal ); /* If we aren't doing a search_all, this is a metablock, and it will be logged before use. ** if we crash before the transaction that freed it commits, this transaction won't ** have committed either, and the block will never be written */ if (search_all) { for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) { + PROC_INFO_INC( p_s_sb, journal.in_journal_bitmap ); jb = SB_JOURNAL(p_s_sb)->j_list_bitmap + i ; if (jb->journal_list && jb->bitmaps[bmap_nr] && test_bit(bit_nr, jb->bitmaps[bmap_nr]->data)) { @@ -548,6 +550,7 @@ int reiserfs_in_journal(struct super_blo return 1; } + PROC_INFO_INC( p_s_sb, journal.in_journal_reusable ); /* safe for reuse */ return 0 ; } @@ -568,7 +571,9 @@ inline void insert_journal_hash(struct r /* lock the current transaction */ inline static void lock_journal(struct super_block *p_s_sb) { + PROC_INFO_INC( p_s_sb, journal.lock_journal ); while(atomic_read(&(SB_JOURNAL(p_s_sb)->j_wlock)) > 0) { + PROC_INFO_INC( p_s_sb, journal.lock_journal_wait ); sleep_on(&(SB_JOURNAL(p_s_sb)->j_wait)) ; } atomic_set(&(SB_JOURNAL(p_s_sb)->j_wlock), 1) ; @@ -2015,6 +2020,7 @@ static int do_journal_begin_r(struct rei th->t_super = p_s_sb ; /* others will check this for the don't log flag */ return 0 ; } + PROC_INFO_INC( p_s_sb, journal.journal_being ); relock: lock_journal(p_s_sb) ; @@ -2022,6 +2028,7 @@ relock: if (test_bit(WRITERS_BLOCKED, &SB_JOURNAL(p_s_sb)->j_state)) { unlock_journal(p_s_sb) ; reiserfs_wait_on_write_block(p_s_sb) ; + PROC_INFO_INC( p_s_sb, journal.journal_relock_writers ); goto relock ; } @@ -2060,6 +2067,7 @@ relock: sleep_on(&(SB_JOURNAL(p_s_sb)->j_join_wait)) ; } } + PROC_INFO_INC( p_s_sb, journal.journal_relock_wcount ); goto relock ; } @@ -2106,6 +2114,7 @@ int journal_mark_dirty(struct reiserfs_t int count_already_incd = 0 ; int prepared = 0 ; + PROC_INFO_INC( p_s_sb, journal.mark_dirty ); if (reiserfs_dont_log(th->t_super)) { mark_buffer_dirty(bh) ; return 0 ; @@ -2120,6 +2129,7 @@ int journal_mark_dirty(struct reiserfs_t prepared = test_and_clear_bit(BH_JPrepared, &bh->b_state) ; /* already in this transaction, we are done */ if (buffer_journaled(bh)) { + PROC_INFO_INC( p_s_sb, journal.mark_dirty_already ); return 0 ; } @@ -2149,6 +2159,7 @@ int journal_mark_dirty(struct reiserfs_t if (buffer_journal_dirty(bh)) { count_already_incd = 1 ; + PROC_INFO_INC( p_s_sb, journal.mark_dirty_notjournal ); mark_buffer_notjournal_dirty(bh) ; } @@ -2609,6 +2620,7 @@ int journal_mark_freed(struct reiserfs_t void reiserfs_restore_prepared_buffer(struct super_block *p_s_sb, struct buffer_head *bh) { + PROC_INFO_INC( p_s_sb, journal.restore_prepared ); if (reiserfs_dont_log (p_s_sb)) return; @@ -2630,6 +2642,7 @@ void reiserfs_prepare_for_journal(struct struct buffer_head *bh, int wait) { int retry_count = 0 ; + PROC_INFO_INC( p_s_sb, journal.prepare ); if (reiserfs_dont_log (p_s_sb)) return; @@ -2649,6 +2662,7 @@ void reiserfs_prepare_for_journal(struct #endif wait_on_buffer(bh) ; } + PROC_INFO_INC( p_s_sb, journal.prepare_retry ); retry_count++ ; } } diff -rup linux/fs/reiserfs/namei.c linux.patched/fs/reiserfs/namei.c --- linux/fs/reiserfs/namei.c Sat Sep 15 01:16:08 2001 +++ linux.patched/fs/reiserfs/namei.c Thu Oct 11 14:42:15 2001 @@ -485,6 +485,9 @@ static int reiserfs_add_entry (struct re deh->deh_offset = cpu_to_le32 (SET_GENERATION_NUMBER (deh_offset (deh), gen_number)); set_cpu_key_k_offset (&entry_key, le32_to_cpu (deh->deh_offset)); + /* update max-hash-collisions counter in reiserfs_sb_info */ + PROC_INFO_MAX( th -> t_super, max_hash_collisions, gen_number ); + if (gen_number != 0) { /* we need to re-search for the insertion point */ if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) { reiserfs_warning ("vs-7032: reiserfs_add_entry: " diff -rup linux/fs/reiserfs/objectid.c linux.patched/fs/reiserfs/objectid.c --- linux/fs/reiserfs/objectid.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/objectid.c Thu Oct 11 14:42:15 2001 @@ -149,9 +149,11 @@ void reiserfs_release_objectid (struct r return; } - if (rs->s_oid_cursize == rs->s_oid_maxsize) + if (rs->s_oid_cursize == rs->s_oid_maxsize) { /* objectid map must be expanded, but there is no space */ + PROC_INFO_INC( s, leaked_oid ); return; + } /* expand the objectid map*/ memmove (map + i + 3, map + i + 1, diff -rup linux/fs/reiserfs/prints.c linux.patched/fs/reiserfs/prints.c --- linux/fs/reiserfs/prints.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/prints.c Thu Oct 11 14:42:15 2001 @@ -527,7 +527,7 @@ static int print_super_block (struct buf printk ("Filesystem state %s\n", (le16_to_cpu (rs->s_state) == REISERFS_VALID_FS) ? "VALID" : "ERROR"); printk ("Hash function \"%s\"\n", le16_to_cpu (rs->s_hash_function_code) == TEA_HASH ? "tea" : - ((le16_to_cpu (rs->s_hash_function_code) == YURA_HASH) ? "rupasov" : "unknown")); + ( le16_to_cpu (rs->s_hash_function_code) == YURA_HASH ? "rupasov" : (le16_to_cpu (rs->s_hash_function_code) == R5_HASH ? "r5" : "unknown"))); #if 0 __u32 s_journal_trans_max ; /* max number of blocks in a transaction. */ Only in linux.patched/fs/reiserfs: procfs.c diff -rup linux/fs/reiserfs/stree.c linux.patched/fs/reiserfs/stree.c --- linux/fs/reiserfs/stree.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/stree.c Thu Oct 11 14:42:15 2001 @@ -671,7 +671,6 @@ int search_by_key (struct super_block * stop at leaf level - set to DISK_LEAF_NODE_LEVEL */ ) { - kdev_t n_dev = p_s_sb->s_dev; int n_block_number = SB_ROOT_BLOCK (p_s_sb), expected_level = SB_TREE_HEIGHT (p_s_sb), n_block_size = p_s_sb->s_blocksize; @@ -684,7 +683,9 @@ int search_by_key (struct super_block * #ifdef CONFIG_REISERFS_CHECK int n_repeat_counter = 0; #endif - + + PROC_INFO_INC( p_s_sb, search_by_key ); + /* As we add each node to a path we increase its count. This means that we must be careful to release all nodes in a path before we either discard the path struct or re-use the path struct, as we do here. */ @@ -719,17 +720,24 @@ int search_by_key (struct super_block * /* Read the next tree node, and set the last element in the path to have a pointer to it. */ if ( ! (p_s_bh = p_s_last_element->pe_buffer = - reiserfs_bread(n_dev, n_block_number, n_block_size)) ) { + reiserfs_bread(p_s_sb, n_block_number, n_block_size)) ) { p_s_search_path->path_length --; pathrelse(p_s_search_path); return IO_ERROR; } + if( fs_changed (fs_gen, p_s_sb) ) { + PROC_INFO_INC( p_s_sb, search_by_key_fs_changed ); + PROC_INFO_INC( p_s_sb, sbk_fs_changed[ expected_level - 1 ] ); + } + /* It is possible that schedule occurred. We must check whether the key to search is still in the tree rooted from the current buffer. If not then repeat search from the root. */ if ( fs_changed (fs_gen, p_s_sb) && (!B_IS_IN_TREE (p_s_bh) || !key_in_buffer(p_s_search_path, p_s_key, p_s_sb)) ) { + PROC_INFO_INC( p_s_sb, search_by_key_restarted ); + PROC_INFO_INC( p_s_sb, sbk_restarted[ expected_level - 1 ] ); decrement_counters_in_path(p_s_search_path); /* Get the root block number so that we can repeat the search @@ -764,6 +772,8 @@ int search_by_key (struct super_block * /* ok, we have acquired next formatted node in the tree */ n_node_level = B_LEVEL (p_s_bh); + + PROC_INFO_BH_STAT( p_s_sb, p_s_bh, n_node_level - 1 ); #ifdef CONFIG_REISERFS_CHECK diff -rup linux/fs/reiserfs/super.c linux.patched/fs/reiserfs/super.c --- linux/fs/reiserfs/super.c Sat Sep 8 23:05:32 2001 +++ linux.patched/fs/reiserfs/super.c Thu Oct 11 14:44:03 2001 @@ -110,10 +110,18 @@ void reiserfs_put_super (struct super_bl print_statistics (s); if (s->u.reiserfs_sb.s_kmallocs != 0) { - reiserfs_warning ("vs-2004: reiserfs_put_super: aloocated memory left %d\n", + reiserfs_warning ("vs-2004: reiserfs_put_super: allocated memory left %d\n", s->u.reiserfs_sb.s_kmallocs); } + reiserfs_proc_unregister( s, "journal" ); + reiserfs_proc_unregister( s, "oidmap" ); + reiserfs_proc_unregister( s, "on-disk-super" ); + reiserfs_proc_unregister( s, "bitmap" ); + reiserfs_proc_unregister( s, "per-level" ); + reiserfs_proc_unregister( s, "super" ); + reiserfs_proc_unregister( s, "version" ); + reiserfs_proc_info_done( s ); return; } @@ -296,11 +304,11 @@ static int read_bitmaps (struct super_bl labeling scheme currently used will have enough space. Then we need one block for the super. -Hans */ bmp = (REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ - SB_AP_BITMAP (s)[0] = reiserfs_bread (s->s_dev, bmp, s->s_blocksize); + SB_AP_BITMAP (s)[0] = reiserfs_bread (s, bmp, s->s_blocksize); if(!SB_AP_BITMAP(s)[0]) return 1; for (i = 1, bmp = dl = rs->s_blocksize * 8; i < le16_to_cpu (rs->s_bmap_nr); i ++) { - SB_AP_BITMAP (s)[i] = reiserfs_bread (s->s_dev, bmp, s->s_blocksize); + SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp, s->s_blocksize); if (!SB_AP_BITMAP (s)[i]) return 1; bmp += dl; @@ -323,7 +331,7 @@ static int read_old_bitmaps (struct supe memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * le16_to_cpu (rs->s_bmap_nr)); for (i = 0; i < le16_to_cpu (rs->s_bmap_nr); i ++) { - SB_AP_BITMAP (s)[i] = reiserfs_bread (s->s_dev, bmp1 + i, s->s_blocksize); + SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp1 + i, s->s_blocksize); if (!SB_AP_BITMAP (s)[i]) return 1; } @@ -596,7 +604,6 @@ int function2code (hashf_t func) return 0; } - // // a portion of this function, particularly the VFS interface portion, // was derived from minix or ext2's analog and evolved as the @@ -749,6 +756,14 @@ struct super_block * reiserfs_read_super } } + reiserfs_proc_info_init( s ); + reiserfs_proc_register( s, "version", reiserfs_version_in_proc ); + reiserfs_proc_register( s, "super", reiserfs_super_in_proc ); + reiserfs_proc_register( s, "per-level", reiserfs_per_level_in_proc ); + reiserfs_proc_register( s, "bitmap", reiserfs_bitmap_in_proc ); + reiserfs_proc_register( s, "on-disk-super", reiserfs_on_disk_super_in_proc ); + reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc ); + reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc ); init_waitqueue_head (&(s->u.reiserfs_sb.s_wait)); printk("%s\n", reiserfs_get_version_string()) ; @@ -798,21 +813,20 @@ int reiserfs_statfs (struct super_block static DECLARE_FSTYPE_DEV(reiserfs_fs_type,"reiserfs",reiserfs_read_super); -// -// this is exactly what 2.3.99-pre9's init_ext2_fs is -// static int __init init_reiserfs_fs (void) { + reiserfs_proc_info_global_init(); + reiserfs_proc_register_global( "version", + reiserfs_global_version_in_proc ); return register_filesystem(&reiserfs_fs_type); } EXPORT_NO_SYMBOLS; -// -// this is exactly what 2.3.99-pre9's init_ext2_fs is -// static void __exit exit_reiserfs_fs(void) { + reiserfs_proc_unregister_global( "version" ); + reiserfs_proc_info_global_done(); unregister_filesystem(&reiserfs_fs_type); } diff -rup linux/include/linux/reiserfs_fs.h linux.patched/include/linux/reiserfs_fs.h --- linux/include/linux/reiserfs_fs.h Sat Sep 8 23:05:32 2001 +++ linux.patched/include/linux/reiserfs_fs.h Thu Oct 11 14:42:15 2001 @@ -17,6 +17,7 @@ #ifdef __KERNEL__ #include #include +#include #endif /* @@ -1817,6 +1818,67 @@ int read_old_super_block (struct super_b struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent); int reiserfs_statfs (struct super_block * s, struct statfs * buf); +/* procfs.c */ + +#if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO ) +#define REISERFS_PROC_INFO +#else +#undef REISERFS_PROC_INFO +#endif + +int reiserfs_proc_info_init( struct super_block *sb ); +int reiserfs_proc_info_done( struct super_block *sb ); +struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb, + char *name, read_proc_t *func ); +void reiserfs_proc_unregister( struct super_block *sb, const char *name ); +struct proc_dir_entry *reiserfs_proc_register_global( char *name, + read_proc_t *func ); +void reiserfs_proc_unregister_global( const char *name ); +int reiserfs_proc_info_global_init( void ); +int reiserfs_proc_info_global_done( void ); +int reiserfs_proc_tail( int len, char *buffer, char **start, + off_t offset, int count, int *eof ); +int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_version_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_super_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); +int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset, + int count, int *eof, void *data ); + +#if defined( REISERFS_PROC_INFO ) + +#define PROC_EXP( e ) e + +#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#define __PINFO( sb ) ( sb ) -> u.reiserfs_sb.s_proc_info_data +#define PROC_INFO_MAX( sb, field, value ) \ + __PINFO( sb ).field = \ + MAX( ( sb ) -> u.reiserfs_sb.s_proc_info_data.field, value ) +#define PROC_INFO_INC( sb, field ) ( ++ ( __PINFO( sb ).field ) ) +#define PROC_INFO_ADD( sb, field, val ) ( __PINFO( sb ).field += ( val ) ) +#define PROC_INFO_BH_STAT( sb, bh, level ) \ + PROC_INFO_INC( sb, sbk_read_at[ ( level ) ] ); \ + PROC_INFO_ADD( sb, free_at[ ( level ) ], B_FREE_SPACE( bh ) ); \ + PROC_INFO_ADD( sb, items_at[ ( level ) ], B_NR_ITEMS( bh ) ) +#else +#define PROC_EXP( e ) +#define VOID_V ( ( void ) 0 ) +#define PROC_INFO_MAX( sb, field, value ) VOID_V +#define PROC_INFO_INC( sb, field ) VOID_V +#define PROC_INFO_ADD( sb, field, val ) VOID_V +#define PROC_INFO_BH_STAT( p_s_sb, p_s_bh, n_node_level ) VOID_V +#endif + /* dir.c */ extern struct inode_operations reiserfs_dir_inode_operations; extern struct file_operations reiserfs_dir_operations; @@ -1838,7 +1900,8 @@ int get_new_buffer (struct reiserfs_tran /* buffer2.c */ struct buffer_head * reiserfs_getblk (kdev_t n_dev, int n_block, int n_size); void wait_buffer_until_released (struct buffer_head * bh); -struct buffer_head * reiserfs_bread (kdev_t n_dev, int n_block, int n_size); +struct buffer_head * reiserfs_bread (struct super_block *super, int n_block, + int n_size); /* fix_nodes.c */ diff -rup linux/include/linux/reiserfs_fs_sb.h linux.patched/include/linux/reiserfs_fs_sb.h --- linux/include/linux/reiserfs_fs_sb.h Sun Sep 23 21:31:02 2001 +++ linux.patched/include/linux/reiserfs_fs_sb.h Thu Oct 11 14:42:15 2001 @@ -264,6 +264,74 @@ struct reiserfs_journal { typedef __u32 (*hashf_t) (const char *, int); +struct proc_dir_entry; + +#if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO ) +typedef unsigned long int stat_cnt_t; +typedef struct reiserfs_proc_info_data +{ + spinlock_t lock; + int exiting; + int max_hash_collisions; + + stat_cnt_t breads; + stat_cnt_t bread_miss; + stat_cnt_t search_by_key; + stat_cnt_t search_by_key_fs_changed; + stat_cnt_t search_by_key_restarted; + + stat_cnt_t leaked_oid; + stat_cnt_t leaves_removable; + + /* balances per level. Use explicit 5 as MAX_HEIGHT is not visible yet. */ + stat_cnt_t balance_at[ 5 ]; /* XXX */ + /* sbk == search_by_key */ + stat_cnt_t sbk_read_at[ 5 ]; /* XXX */ + stat_cnt_t sbk_fs_changed[ 5 ]; + stat_cnt_t sbk_restarted[ 5 ]; + stat_cnt_t items_at[ 5 ]; /* XXX */ + stat_cnt_t free_at[ 5 ]; /* XXX */ + stat_cnt_t can_node_be_removed[ 5 ]; /* XXX */ + long int lnum[ 5 ]; /* XXX */ + long int rnum[ 5 ]; /* XXX */ + long int lbytes[ 5 ]; /* XXX */ + long int rbytes[ 5 ]; /* XXX */ + stat_cnt_t get_neighbors[ 5 ]; + stat_cnt_t get_neighbors_restart[ 5 ]; + stat_cnt_t need_l_neighbor[ 5 ]; + stat_cnt_t need_r_neighbor[ 5 ]; + + stat_cnt_t free_block; + struct __find_forward_stats { + stat_cnt_t call; + stat_cnt_t wait; + stat_cnt_t bmap; + stat_cnt_t retry; + stat_cnt_t in_journal_hint; + stat_cnt_t in_journal_out; + } find_forward; + struct __journal_stats { + stat_cnt_t in_journal; + stat_cnt_t in_journal_bitmap; + stat_cnt_t in_journal_reusable; + stat_cnt_t lock_journal; + stat_cnt_t lock_journal_wait; + stat_cnt_t journal_being; + stat_cnt_t journal_relock_writers; + stat_cnt_t journal_relock_wcount; + stat_cnt_t mark_dirty; + stat_cnt_t mark_dirty_already; + stat_cnt_t mark_dirty_notjournal; + stat_cnt_t restore_prepared; + stat_cnt_t prepare; + stat_cnt_t prepare_retry; + } journal; +} reiserfs_proc_info_data_t; +#else +typedef struct reiserfs_proc_info_data +{} reiserfs_proc_info_data_t; +#endif + /* reiserfs union of in-core super block data */ struct reiserfs_sb_info { @@ -302,6 +370,8 @@ struct reiserfs_sb_info int s_bmaps_without_search; int s_direct2indirect; int s_indirect2direct; + reiserfs_proc_info_data_t s_proc_info_data; + struct proc_dir_entry *procdir; };