static int read_bitmaps (struct super_block * s) { int i, bmp, dl ; struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s); SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s); if (SB_AP_BITMAP (s) == 0) return 1; memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs)); /* reiserfs leaves the first 64k unused so that any partition 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, bmp, s->s_blocksize); if(!SB_AP_BITMAP(s)[0]) return 1; for (i = 1, bmp = dl = s->s_blocksize * 8; i < sb_bmap_nr(rs); i ++) { SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp, s->s_blocksize); if (!SB_AP_BITMAP (s)[i]) return 1; bmp += dl; } return 0; }
static int read_super_block (struct super_block * s, int size) { struct buffer_head * bh; struct reiserfs_super_block * rs; int repeat ; repeat = 0 ; bh = bread (s->s_dev, (REISERFS_DISK_OFFSET_IN_BYTES / size), size); if (!bh) { printk("reiserfs_read_super: unable to read superblock on dev %s\n", kdevname(s->s_dev)); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING))) { brelse (bh); printk ("reiserfs_read_super: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev)); return 1; } s->s_blocksize = le16_to_cpu (rs->s_blocksize); s->s_blocksize_bits = 0; while ((1 << s->s_blocksize_bits) != s->s_blocksize) s->s_blocksize_bits ++; if (size != rs->s_blocksize) { brelse (bh); set_blocksize (s->s_dev, s->s_blocksize); bh = reiserfs_bread (s->s_dev, (REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize), s->s_blocksize, &repeat); if (!bh) { printk("reiserfs_read_super: unable to read superblock on dev %s\n", kdevname(s->s_dev)); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) || le16_to_cpu (rs->s_blocksize) != s->s_blocksize) { brelse (bh); printk ("reiserfs_read_super: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev)); return 1; } } /* must check to be sure we haven't pulled an old format super out of the ** old format's log. This is a kludge of a check, but it will work. ** If block we've just read in is inside the journal for that ** super, it can't be valid. */ if (bh->b_blocknr >= rs->s_journal_block && bh->b_blocknr < (rs->s_journal_block + JOURNAL_BLOCK_COUNT)) { brelse(bh) ; printk("super-459: reiserfs_read_super: super found at block %lu is within its own log. It must not be of this format type.\n", bh->b_blocknr) ; return 1 ; } SB_BUFFER_WITH_SB (s) = bh; SB_DISK_SUPER_BLOCK (s) = rs; s->s_op = &reiserfs_sops; return 0; }
static int read_old_bitmaps (struct super_block * s) { int i ; struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s); int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ /* read true bitmap */ SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s); if (SB_AP_BITMAP (s) == 0) return 1; memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs)); for (i = 0; i < sb_bmap_nr(rs); i ++) { SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp1 + i, s->s_blocksize); if (!SB_AP_BITMAP (s)[i]) return 1; } return 0; }
static int read_old_bitmaps (struct super_block * s) { int i, repeat ; struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s); int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ repeat = 0 ; /* read true bitmap */ SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * le16_to_cpu (rs->s_bmap_nr), GFP_KERNEL, s); if (SB_AP_BITMAP (s) == 0) return 1; 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, &repeat); if (!SB_AP_BITMAP (s)[i]) return 1; } return 0; }
static int read_super_block (struct super_block * s, int size, int offset) { struct buffer_head * bh; struct reiserfs_super_block * rs; bh = bread (s->s_dev, offset / size, size); if (!bh) { printk ("read_super_block: " "bread failed (dev %s, block %d, size %d)\n", kdevname (s->s_dev), offset / size, size); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (!is_reiserfs_magic_string (rs)) { printk ("read_super_block: " "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n", kdevname(s->s_dev), bh->b_blocknr, size); brelse (bh); return 1; } // // ok, reiserfs signature (old or new) found in at the given offset // s->s_blocksize = sb_blocksize(rs); s->s_blocksize_bits = 0; while ((1 << s->s_blocksize_bits) != s->s_blocksize) s->s_blocksize_bits ++; brelse (bh); if (s->s_blocksize != size) set_blocksize (s->s_dev, s->s_blocksize); bh = reiserfs_bread (s, offset / s->s_blocksize, s->s_blocksize); if (!bh) { printk("read_super_block: " "bread failed (dev %s, block %d, size %d)\n", kdevname (s->s_dev), offset / size, size); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (!is_reiserfs_magic_string (rs) || sb_blocksize(rs) != s->s_blocksize) { printk ("read_super_block: " "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n", kdevname(s->s_dev), bh->b_blocknr, size); brelse (bh); printk ("read_super_block: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev)); return 1; } /* must check to be sure we haven't pulled an old format super out ** of the old format's log. This is a kludge of a check, but it ** will work. If block we've just read in is inside the ** journal for that super, it can't be valid. */ if (bh->b_blocknr >= sb_journal_block(rs) && bh->b_blocknr < (sb_journal_block(rs) + JOURNAL_BLOCK_COUNT)) { brelse(bh) ; printk("super-459: read_super_block: " "super found at block %lu is within its own log. " "It must not be of this format type.\n", bh->b_blocknr) ; return 1 ; } if ( rs->s_root_block == -1 ) { brelse(bh) ; printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n" "reiserfsck --rebuild-tree and wait for a completion. If that fails\n" "get newer reiserfsprogs package\n", kdevname (s->s_dev)); return 1; } SB_BUFFER_WITH_SB (s) = bh; SB_DISK_SUPER_BLOCK (s) = rs; s->s_op = &reiserfs_sops; /* new format is limited by the 32 bit wide i_blocks field, want to ** be one full block below that. */ s->s_maxbytes = (512LL << 32) - s->s_blocksize ; return 0; }
/* This function fills up the path from the root to the leaf as it descends the tree looking for the key. It uses reiserfs_bread to try to find buffers in the cache given their block number. If it does not find them in the cache it reads them from disk. For each node search_by_key finds using reiserfs_bread it then uses bin_search to look through that node. bin_search will find the position of the block_number of the next node if it is looking through an internal node. If it is looking through a leaf node bin_search will find the position of the item which has key either equal to given key, or which is the maximal key less than the given key. search_by_key returns a path that must be checked for the correctness of the top of the path but need not be checked for the correctness of the bottom of the path */ int search_by_key( struct super_block * p_s_sb, /* Super block. */ struct key * p_s_key, /* Key to search. */ struct path * p_s_search_path,/* This structure was allocated and initialized by the calling function. It is filled up by this function. */ int * p_n_repeat, /* Whether schedule occured. */ int n_stop_level /* How far down the tree to search.*/ ) { dev_t n_dev = p_s_sb->s_dev; int n_repeat, 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; struct buffer_head * p_s_bh; struct path_element * p_s_last_element; int n_retval; int right_neighbor_of_leaf_node; #ifdef CONFIG_REISERFS_CHECK int n_repeat_counter = 0; #endif /* 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. */ pathrelse (p_s_search_path); *p_n_repeat = CARRY_ON; /* With each iteration of this loop we search through the items in the current node, and calculate the next current node(next path element) for the next iteration of this loop.. */ while ( 1 ) { #ifdef CONFIG_REISERFS_CHECK if ( !(++n_repeat_counter % 50000) ) printk ("PAP-5100: search_by_key(pid %u): there were %d searches from the tree_root lokking for key %p\n", current->pid, n_repeat_counter, p_s_key); #endif /* prep path to have another element added to it. */ p_s_last_element = PATH_OFFSET_PELEMENT(p_s_search_path, ++p_s_search_path->path_length); expected_level --; n_repeat = CARRY_ON; /* 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, &n_repeat)) ) { p_s_search_path->path_length --; pathrelse(p_s_search_path); *p_n_repeat |= n_repeat; return IO_ERROR; } *p_n_repeat |= n_repeat; /* It is possible that schedule occured. 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 ( n_repeat != CARRY_ON && (!B_IS_IN_TREE (p_s_bh) || (! key_in_buffer(p_s_search_path, p_s_key, p_s_sb))) ) { pathrelse (p_s_search_path); /* Get the root block number so that we can repeat the search starting from the root. */ n_block_number = SB_ROOT_BLOCK (p_s_sb); expected_level = SB_TREE_HEIGHT (p_s_sb); right_neighbor_of_leaf_node = 0; /* repeat search from the root */ continue; } #ifdef CONFIG_REISERFS_CHECK if ( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb) ) reiserfs_panic(p_s_sb, "PAP-5130: search_by_key: key is not in the buffer"); if ( cur_tb ) { /* print_tb (init_mode, init_item_pos, init_pos_in_item, &init_tb, "5140");*/ reiserfs_panic(p_s_sb, "PAP-5140: search_by_key: schedule occurred in do_balance!"); } #endif // make sure, that the node contents look like a nod of // certain level if (!is_tree_node (p_s_bh, expected_level)) { print_block (stderr, 0, p_s_bh, 3, -1, -1); reiserfs_panic ("vs-5150: search_by_key: expeced level %d", expected_level); pathrelse (p_s_search_path); return IO_ERROR; } /* ok, we have acquired next formatted node in the tree */ n_retval = bin_search (p_s_key, B_N_PITEM_HEAD(p_s_bh, 0), B_NR_ITEMS(p_s_bh), is_leaf_node (p_s_bh) ? IH_SIZE : KEY_SIZE, &(p_s_last_element->pe_position)); if (node_level (p_s_bh) == n_stop_level) return n_retval; /* we are not in the stop level */ if (n_retval == ITEM_FOUND) /* item has been found, so we choose the pointer which is to the right of the found one */ p_s_last_element->pe_position++; /* if item was not found we choose the position which is to the left of the found item. This requires no code, bin_search did it already.*/ /* So we have chosen a position in the current node which is an internal node. Now we calculate child block number by position in the node. */ n_block_number = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position); } }