linux/fs/reiserfs/fix_node.c

/*
 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
 */

#include <linux/time.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "reiserfs.h"
#include <linux/buffer_head.h>

/*
 * To make any changes in the tree we find a node that contains item
 * to be changed/deleted or position in the node we insert a new item
 * to. We call this node S. To do balancing we need to decide what we
 * will shift to left/right neighbor, or to a new node, where new item
 * will be etc. To make this analysis simpler we build virtual
 * node. Virtual node is an array of items, that will replace items of
 * node S. (For instance if we are going to delete an item, virtual
 * node does not contain it). Virtual node keeps information about
 * item sizes and types, mergeability of first and last items, sizes
 * of all entries in directory item. We use this array of items when
 * calculating what we can shift to neighbors and how many nodes we
 * have to have if we do not any shiftings, if we shift to left/right
 * neighbor or to both.
 */

/*
 * Takes item number in virtual node, returns number of item
 * that it has in source buffer
 */
static inline int old_item_num(int new_num, int affected_item_num, int mode)
{}

static void create_virtual_node(struct tree_balance *tb, int h)
{}

/*
 * Using virtual node check, how many items can be
 * shifted to left neighbor
 */
static void check_left(struct tree_balance *tb, int h, int cur_free)
{}

/*
 * Using virtual node check, how many items can be
 * shifted to right neighbor
 */
static void check_right(struct tree_balance *tb, int h, int cur_free)
{}

/*
 * from - number of items, which are shifted to left neighbor entirely
 * to - number of item, which are shifted to right neighbor entirely
 * from_bytes - number of bytes of boundary item (or directory entries)
 *              which are shifted to left neighbor
 * to_bytes - number of bytes of boundary item (or directory entries)
 *            which are shifted to right neighbor
 */
static int get_num_ver(int mode, struct tree_balance *tb, int h,
		       int from, int from_bytes,
		       int to, int to_bytes, short *snum012, int flow)
{}


/*
 * Set parameters for balancing.
 * Performs write of results of analysis of balancing into structure tb,
 * where it will later be used by the functions that actually do the balancing.
 * Parameters:
 *	tb	tree_balance structure;
 *	h	current level of the node;
 *	lnum	number of items from S[h] that must be shifted to L[h];
 *	rnum	number of items from S[h] that must be shifted to R[h];
 *	blk_num	number of blocks that S[h] will be splitted into;
 *	s012	number of items that fall into splitted nodes.
 *	lbytes	number of bytes which flow to the left neighbor from the
 *              item that is not shifted entirely
 *	rbytes	number of bytes which flow to the right neighbor from the
 *              item that is not shifted entirely
 *	s1bytes	number of bytes which flow to the first  new node when
 *              S[0] splits (this number is contained in s012 array)
 */

static void set_parameters(struct tree_balance *tb, int h, int lnum,
			   int rnum, int blk_num, short *s012, int lb, int rb)
{}

/*
 * check if node disappears if we shift tb->lnum[0] items to left
 * neighbor and tb->rnum[0] to the right one.
 */
static int is_leaf_removable(struct tree_balance *tb)
{}

/* check whether L, S, R can be joined in one node */
static int are_leaves_removable(struct tree_balance *tb, int lfree, int rfree)
{}

/* when we do not split item, lnum and rnum are numbers of entire items */
#define SET_PAR_SHIFT_LEFT

#define SET_PAR_SHIFT_RIGHT

static void free_buffers_in_tb(struct tree_balance *tb)
{}

/*
 * Get new buffers for storing new nodes that are created while balancing.
 * Returns:	SCHEDULE_OCCURRED - schedule occurred while the function worked;
 *	        CARRY_ON - schedule didn't occur while the function worked;
 *	        NO_DISK_SPACE - no disk space.
 */
/* The function is NOT SCHEDULE-SAFE! */
static int get_empty_nodes(struct tree_balance *tb, int h)
{}

/*
 * Get free space of the left neighbor, which is stored in the parent
 * node of the left neighbor.
 */
static int get_lfree(struct tree_balance *tb, int h)
{}

/*
 * Get free space of the right neighbor,
 * which is stored in the parent node of the right neighbor.
 */
static int get_rfree(struct tree_balance *tb, int h)
{}

/* Check whether left neighbor is in memory. */
static int is_left_neighbor_in_cache(struct tree_balance *tb, int h)
{}

#define LEFT_PARENTS
#define RIGHT_PARENTS

static void decrement_key(struct cpu_key *key)
{}

/*
 * Calculate far left/right parent of the left/right neighbor of the
 * current node, that is calculate the left/right (FL[h]/FR[h]) neighbor
 * of the parent F[h].
 * Calculate left/right common parent of the current node and L[h]/R[h].
 * Calculate left/right delimiting key position.
 * Returns:	PATH_INCORRECT    - path in the tree is not correct
 *		SCHEDULE_OCCURRED - schedule occurred while the function worked
 *	        CARRY_ON          - schedule didn't occur while the function
 *				    worked
 */
static int get_far_parent(struct tree_balance *tb,
			  int h,
			  struct buffer_head **pfather,
			  struct buffer_head **pcom_father, char c_lr_par)
{}

/*
 * Get parents of neighbors of node in the path(S[path_offset]) and
 * common parents of S[path_offset] and L[path_offset]/R[path_offset]:
 * F[path_offset], FL[path_offset], FR[path_offset], CFL[path_offset],
 * CFR[path_offset].
 * Calculate numbers of left and right delimiting keys position:
 * lkey[path_offset], rkey[path_offset].
 * Returns:	SCHEDULE_OCCURRED - schedule occurred while the function worked
 *	        CARRY_ON - schedule didn't occur while the function worked
 */
static int get_parents(struct tree_balance *tb, int h)
{}

/*
 * it is possible to remove node as result of shiftings to
 * neighbors even when we insert or paste item.
 */
static inline int can_node_be_removed(int mode, int lfree, int sfree, int rfree,
				      struct tree_balance *tb, int h)
{}

/*
 * Check whether current node S[h] is balanced when increasing its size by
 * Inserting or Pasting.
 * Calculate parameters for balancing for current level h.
 * Parameters:
 *	tb	tree_balance structure;
 *	h	current level of the node;
 *	inum	item number in S[h];
 *	mode	i - insert, p - paste;
 * Returns:	1 - schedule occurred;
 *	        0 - balancing for higher levels needed;
 *	       -1 - no balancing for higher levels needed;
 *	       -2 - no disk space.
 */
/* ip means Inserting or Pasting */
static int ip_check_balance(struct tree_balance *tb, int h)
{}

/*
 * Check whether current node S[h] is balanced when Decreasing its size by
 * Deleting or Cutting for INTERNAL node of S+tree.
 * Calculate parameters for balancing for current level h.
 * Parameters:
 *	tb	tree_balance structure;
 *	h	current level of the node;
 *	inum	item number in S[h];
 *	mode	i - insert, p - paste;
 * Returns:	1 - schedule occurred;
 *	        0 - balancing for higher levels needed;
 *	       -1 - no balancing for higher levels needed;
 *	       -2 - no disk space.
 *
 * Note: Items of internal nodes have fixed size, so the balance condition for
 * the internal part of S+tree is as for the B-trees.
 */
static int dc_check_balance_internal(struct tree_balance *tb, int h)
{}

/*
 * Check whether current node S[h] is balanced when Decreasing its size by
 * Deleting or Truncating for LEAF node of S+tree.
 * Calculate parameters for balancing for current level h.
 * Parameters:
 *	tb	tree_balance structure;
 *	h	current level of the node;
 *	inum	item number in S[h];
 *	mode	i - insert, p - paste;
 * Returns:	1 - schedule occurred;
 *	        0 - balancing for higher levels needed;
 *	       -1 - no balancing for higher levels needed;
 *	       -2 - no disk space.
 */
static int dc_check_balance_leaf(struct tree_balance *tb, int h)
{}

/*
 * Check whether current node S[h] is balanced when Decreasing its size by
 * Deleting or Cutting.
 * Calculate parameters for balancing for current level h.
 * Parameters:
 *	tb	tree_balance structure;
 *	h	current level of the node;
 *	inum	item number in S[h];
 *	mode	d - delete, c - cut.
 * Returns:	1 - schedule occurred;
 *	        0 - balancing for higher levels needed;
 *	       -1 - no balancing for higher levels needed;
 *	       -2 - no disk space.
 */
static int dc_check_balance(struct tree_balance *tb, int h)
{}

/*
 * Check whether current node S[h] is balanced.
 * Calculate parameters for balancing for current level h.
 * Parameters:
 *
 *	tb	tree_balance structure:
 *
 *              tb is a large structure that must be read about in the header
 *		file at the same time as this procedure if the reader is
 *		to successfully understand this procedure
 *
 *	h	current level of the node;
 *	inum	item number in S[h];
 *	mode	i - insert, p - paste, d - delete, c - cut.
 * Returns:	1 - schedule occurred;
 *	        0 - balancing for higher levels needed;
 *	       -1 - no balancing for higher levels needed;
 *	       -2 - no disk space.
 */
static int check_balance(int mode,
			 struct tree_balance *tb,
			 int h,
			 int inum,
			 int pos_in_item,
			 struct item_head *ins_ih, const void *data)
{}

/* Check whether parent at the path is the really parent of the current node.*/
static int get_direct_parent(struct tree_balance *tb, int h)
{}

/*
 * Using lnum[h] and rnum[h] we should determine what neighbors
 * of S[h] we
 * need in order to balance S[h], and get them if necessary.
 * Returns:	SCHEDULE_OCCURRED - schedule occurred while the function worked;
 *	        CARRY_ON - schedule didn't occur while the function worked;
 */
static int get_neighbors(struct tree_balance *tb, int h)
{}

static int get_virtual_node_size(struct super_block *sb, struct buffer_head *bh)
{}

/*
 * maybe we should fail balancing we are going to perform when kmalloc
 * fails several times. But now it will loop until kmalloc gets
 * required memory
 */
static int get_mem_for_virtual_node(struct tree_balance *tb)
{}

#ifdef CONFIG_REISERFS_CHECK
static void tb_buffer_sanity_check(struct super_block *sb,
				   struct buffer_head *bh,
				   const char *descr, int level)
{}
#else
static void tb_buffer_sanity_check(struct super_block *sb,
				   struct buffer_head *bh,
				   const char *descr, int level)
{;
}
#endif

static int clear_all_dirty_bits(struct super_block *s, struct buffer_head *bh)
{}

static int wait_tb_buffers_until_unlocked(struct tree_balance *tb)
{}

/*
 * Prepare for balancing, that is
 *	get all necessary parents, and neighbors;
 *	analyze what and where should be moved;
 *	get sufficient number of new nodes;
 * Balancing will start only after all resources will be collected at a time.
 *
 * When ported to SMP kernels, only at the last moment after all needed nodes
 * are collected in cache, will the resources be locked using the usual
 * textbook ordered lock acquisition algorithms.  Note that ensuring that
 * this code neither write locks what it does not need to write lock nor locks
 * out of order will be a pain in the butt that could have been avoided.
 * Grumble grumble. -Hans
 *
 * fix is meant in the sense of render unchanging
 *
 * Latency might be improved by first gathering a list of what buffers
 * are needed and then getting as many of them in parallel as possible? -Hans
 *
 * Parameters:
 *	op_mode	i - insert, d - delete, c - cut (truncate), p - paste (append)
 *	tb	tree_balance structure;
 *	inum	item number in S[h];
 *      pos_in_item - comment this if you can
 *      ins_ih	item head of item being inserted
 *	data	inserted item or data to be pasted
 * Returns:	1 - schedule occurred while the function worked;
 *	        0 - schedule didn't occur while the function worked;
 *             -1 - if no_disk_space
 */

int fix_nodes(int op_mode, struct tree_balance *tb,
	      struct item_head *ins_ih, const void *data)
{}

void unfix_nodes(struct tree_balance *tb)
{}