Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include "reiserfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * copy copy_count entries from source directory item to dest buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * (creating new item if needed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 				  struct buffer_head *source, int last_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 				  int item_num, int from, int copy_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 	struct buffer_head *dest = dest_bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 	 * either the number of target item, or if we must create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 	 * new item, the number of the item we will create it next to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 	int item_num_in_dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	struct reiserfs_de_head *deh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 	int copy_records_len;	/* length of all records in item to be copied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	char *records;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	ih = item_head(source, item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	 * length of all record to be copied and first byte of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	 * the last of them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	deh = B_I_DEH(source, ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	if (copy_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 		copy_records_len = (from ? deh_location(&deh[from - 1]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 				    ih_item_len(ih)) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 		    deh_location(&deh[from + copy_count - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 		records =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 		    source->b_data + ih_location(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 		    deh_location(&deh[from + copy_count - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		copy_records_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 		records = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	/* when copy last to first, dest buffer can contain 0 items */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	item_num_in_dest =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	    (last_first ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	     LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 							       - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	 * if there are no items in dest or the first/last item in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	 * dest is not item of the same directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	if ((item_num_in_dest == -1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	    (last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	    (last_first == LAST_TO_FIRST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	     && comp_short_le_keys /*COMP_SHORT_KEYS */ (&ih->ih_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 							 leaf_key(dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 								  item_num_in_dest))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 		/* create new item in dest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 		struct item_head new_ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		/* form item header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 		memcpy(&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		put_ih_version(&new_ih, KEY_FORMAT_3_5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		/* calculate item len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 		put_ih_item_len(&new_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 				DEH_SIZE * copy_count + copy_records_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		put_ih_entry_count(&new_ih, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 		if (last_first == LAST_TO_FIRST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 			/* form key by the following way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 			if (from < ih_entry_count(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 				set_le_ih_k_offset(&new_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 						   deh_offset(&deh[from]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 				 * no entries will be copied to this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 				 * item in this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 				set_le_ih_k_offset(&new_ih, U32_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 				 * this item is not yet valid, but we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 				 * want I_IS_DIRECTORY_ITEM to return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 				 * for it, so we -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 			set_le_key_k_type(KEY_FORMAT_3_5, &new_ih.ih_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 					  TYPE_DIRENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		/* insert item into dest buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		leaf_insert_into_buf(dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 				     (last_first ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 				      LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 				     &new_ih, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		/* prepare space for entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		leaf_paste_in_buffer(dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 				     (last_first ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 				      FIRST_TO_LAST) ? (B_NR_ITEMS(dest) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 							1) : 0, MAX_US_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 				     DEH_SIZE * copy_count + copy_records_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 				     records, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	item_num_in_dest =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	    (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	leaf_paste_entries(dest_bi, item_num_in_dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 			   (last_first ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 			    FIRST_TO_LAST) ? ih_entry_count(item_head(dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 									  item_num_in_dest))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 			   : 0, copy_count, deh + from, records,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 			   DEH_SIZE * copy_count + copy_records_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * Copy the first (if last_first == FIRST_TO_LAST) or last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  * (last_first == LAST_TO_FIRST) item or part of it or nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * (see the return 0 below) from SOURCE to the end (if last_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)  * or beginning (!last_first) of the DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) /* returns 1 if anything was copied, else 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 				   struct buffer_head *src, int last_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 				   int bytes_or_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	struct buffer_head *dest = dest_bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	/* number of items in the source and destination buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	int dest_nr_item, src_nr_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	struct item_head *dih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	dest_nr_item = B_NR_ITEMS(dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	 * if ( DEST is empty or first item of SOURCE and last item of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	 * DEST are the items of different objects or of different types )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	 * then there is no need to treat this item differently from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	 * other items that we copy, so we return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	if (last_first == FIRST_TO_LAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		ih = item_head(src, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		dih = item_head(dest, dest_nr_item - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		/* there is nothing to merge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		if (!dest_nr_item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		    || (!op_is_left_mergeable(&ih->ih_key, src->b_size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		RFALSE(!ih_item_len(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		       "vs-10010: item can not have empty length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		if (is_direntry_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 			if (bytes_or_entries == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 				/* copy all entries to dest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 				bytes_or_entries = ih_entry_count(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 			leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 					      bytes_or_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		 * copy part of the body of the first item of SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		 * to the end of the body of the last item of the DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		 * part defined by 'bytes_or_entries'; if bytes_or_entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		 * == -1 copy whole body; don't create new item header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		if (bytes_or_entries == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 			bytes_or_entries = ih_item_len(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) #ifdef CONFIG_REISERFS_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			if (bytes_or_entries == ih_item_len(ih)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			    && is_indirect_le_ih(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 				if (get_ih_free_space(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 					reiserfs_panic(sb_from_bi(dest_bi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 						       "vs-10020",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 						       "last unformatted node "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 						       "must be filled "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 						       "entirely (%h)", ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		 * merge first item (or its part) of src buffer with the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		 * item of dest buffer. Both are of the same file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		leaf_paste_in_buffer(dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 				     dest_nr_item - 1, ih_item_len(dih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 				     bytes_or_entries, ih_item_body(src, ih), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		if (is_indirect_le_ih(dih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 			RFALSE(get_ih_free_space(dih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 			       "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 			       ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 			if (bytes_or_entries == ih_item_len(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 				set_ih_free_space(dih, get_ih_free_space(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	/* copy boundary item to right (last_first == LAST_TO_FIRST) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	 * (DEST is empty or last item of SOURCE and first item of DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	 * are the items of different object or of different types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	src_nr_item = B_NR_ITEMS(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	ih = item_head(src, src_nr_item - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	dih = item_head(dest, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	if (!dest_nr_item || !op_is_left_mergeable(&dih->ih_key, src->b_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	if (is_direntry_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		 * bytes_or_entries = entries number in last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		 * item body of SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		if (bytes_or_entries == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			bytes_or_entries = ih_entry_count(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 				      src_nr_item - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 				      ih_entry_count(ih) - bytes_or_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 				      bytes_or_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	 * copy part of the body of the last item of SOURCE to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	 * begin of the body of the first item of the DEST; part defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	 * by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	 * change first item key of the DEST; don't create new item header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	       "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	       ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	if (bytes_or_entries == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		/* bytes_or_entries = length of last item body of SOURCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		bytes_or_entries = ih_item_len(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		RFALSE(le_ih_k_offset(dih) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		       le_ih_k_offset(ih) + op_bytes_number(ih, src->b_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		       "vs-10050: items %h and %h do not match", ih, dih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		/* change first item key of the DEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		set_le_ih_k_offset(dih, le_ih_k_offset(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		/* item becomes non-mergeable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		/* or mergeable if left item was */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		set_le_ih_k_type(dih, le_ih_k_type(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		/* merge to right only part of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		RFALSE(ih_item_len(ih) <= bytes_or_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		       "vs-10060: no so much bytes %lu (needed %lu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		       (unsigned long)ih_item_len(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		       (unsigned long)bytes_or_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		/* change first item key of the DEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		if (is_direct_le_ih(dih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			RFALSE(le_ih_k_offset(dih) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			       (unsigned long)bytes_or_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 			       "vs-10070: dih %h, bytes_or_entries(%d)", dih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			       bytes_or_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			set_le_ih_k_offset(dih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 					   le_ih_k_offset(dih) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 					   bytes_or_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			RFALSE(le_ih_k_offset(dih) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			       (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			       "vs-10080: dih %h, bytes_or_entries(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			       dih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			       (bytes_or_entries / UNFM_P_SIZE) * dest->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 			set_le_ih_k_offset(dih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 					   le_ih_k_offset(dih) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 					   ((bytes_or_entries / UNFM_P_SIZE) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 					    dest->b_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	leaf_paste_in_buffer(dest_bi, 0, 0, bytes_or_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 			     ih_item_body(src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 				       ih) + ih_item_len(ih) - bytes_or_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 			     0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)  * copy cpy_mun items from buffer src to buffer dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)  * last_first == FIRST_TO_LAST means, that we copy cpy_num items beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)  *                             from first-th item in src to tail of dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307)  * last_first == LAST_TO_FIRST means, that we copy cpy_num items beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)  *                             from first-th item in src to head of dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 				     struct buffer_head *src, int last_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 				     int first, int cpy_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	struct buffer_head *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	int nr, free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	int dest_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	int last_loc, last_inserted_loc, location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	struct block_head *blkh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	RFALSE(last_first != LAST_TO_FIRST && last_first != FIRST_TO_LAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	       "vs-10090: bad last_first parameter %d", last_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	RFALSE(B_NR_ITEMS(src) - first < cpy_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	       "vs-10100: too few items in source %d, required %d from %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	       B_NR_ITEMS(src), cpy_num, first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	RFALSE(cpy_num < 0, "vs-10110: can not copy negative amount of items");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	RFALSE(!dest_bi, "vs-10120: can not copy negative amount of items");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	dest = dest_bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	RFALSE(!dest, "vs-10130: can not copy negative amount of items");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	if (cpy_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	blkh = B_BLK_HEAD(dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	nr = blkh_nr_item(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	free_space = blkh_free_space(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	 * we will insert items before 0-th or nr-th item in dest buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	 * It depends of last_first parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	/* location of head of first new item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	ih = item_head(dest, dest_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	RFALSE(blkh_free_space(blkh) < cpy_num * IH_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	       "vs-10140: not enough free space for headers %d (needed %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	       B_FREE_SPACE(dest), cpy_num * IH_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	/* prepare space for headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	/* copy item headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	memcpy(ih, item_head(src, first), cpy_num * IH_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	free_space -= (IH_SIZE * cpy_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	set_blkh_free_space(blkh, free_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	/* location of unmovable item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	j = location = (dest_before == 0) ? dest->b_size : ih_location(ih - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	for (i = dest_before; i < nr + cpy_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		location -= ih_item_len(ih + i - dest_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		put_ih_location(ih + i - dest_before, location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	/* prepare space for items */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	last_loc = ih_location(&ih[nr + cpy_num - 1 - dest_before]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	last_inserted_loc = ih_location(&ih[cpy_num - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	/* check free space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	RFALSE(free_space < j - last_inserted_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	       "vs-10150: not enough free space for items %d (needed %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	       free_space, j - last_inserted_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	memmove(dest->b_data + last_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		dest->b_data + last_loc + j - last_inserted_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		last_inserted_loc - last_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	/* copy items */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	memcpy(dest->b_data + last_inserted_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	       item_body(src, (first + cpy_num - 1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	       j - last_inserted_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	/* sizes, item number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	set_blkh_nr_item(blkh, nr + cpy_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	set_blkh_free_space(blkh, free_space - (j - last_inserted_loc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	do_balance_mark_leaf_dirty(dest_bi->tb, dest, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	if (dest_bi->bi_parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		struct disk_child *t_dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		RFALSE(dc_block_number(t_dc) != dest->b_blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		       "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		       (long unsigned)dest->b_blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		       (long unsigned)dc_block_number(t_dc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		put_dc_size(t_dc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			    dc_size(t_dc) + (j - last_inserted_loc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 					     IH_SIZE * cpy_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 					       0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411)  * This function splits the (liquid) item into two items (useful when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)  * shifting part of an item into another node.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) static void leaf_item_bottle(struct buffer_info *dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 			     struct buffer_head *src, int last_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			     int item_num, int cpy_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	struct buffer_head *dest = dest_bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	RFALSE(cpy_bytes == -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	       "vs-10170: bytes == - 1 means: do not split item");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (last_first == FIRST_TO_LAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		 * if ( if item in position item_num in buffer SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		 * is directory item )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		ih = item_head(src, item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		if (is_direntry_le_ih(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 					      item_num, 0, cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			struct item_head n_ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			 * copy part of the body of the item number 'item_num'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 			 * of SOURCE to the end of the DEST part defined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			 * 'cpy_bytes'; create new item header; change old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			 * item_header (????); n_ih = new item_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			memcpy(&n_ih, ih, IH_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 			put_ih_item_len(&n_ih, cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			if (is_indirect_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 				RFALSE(cpy_bytes == ih_item_len(ih)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 				       && get_ih_free_space(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 				       "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 				       (long unsigned)get_ih_free_space(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 				set_ih_free_space(&n_ih, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			RFALSE(op_is_left_mergeable(&ih->ih_key, src->b_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			       "vs-10190: bad mergeability of item %h", ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 			n_ih.ih_version = ih->ih_version;	/* JDM Endian safe, both le */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			leaf_insert_into_buf(dest_bi, B_NR_ITEMS(dest), &n_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 					     item_body(src, item_num), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		 * if ( if item in position item_num in buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		 * SOURCE is directory item )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		ih = item_head(src, item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		if (is_direntry_le_ih(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 					      item_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 					      ih_entry_count(ih) - cpy_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 					      cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			struct item_head n_ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 			 * copy part of the body of the item number 'item_num'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			 * of SOURCE to the begin of the DEST part defined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			 * 'cpy_bytes'; create new item header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			 * n_ih = new item_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			memcpy(&n_ih.ih_key, &ih->ih_key, KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			/* Endian safe, both le */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			n_ih.ih_version = ih->ih_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			if (is_direct_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				set_le_ih_k_offset(&n_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 						   le_ih_k_offset(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 						   ih_item_len(ih) - cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				set_le_ih_k_type(&n_ih, TYPE_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 				set_ih_free_space(&n_ih, MAX_US_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 				/* indirect item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 				RFALSE(!cpy_bytes && get_ih_free_space(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 				       "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 				set_le_ih_k_offset(&n_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 						   le_ih_k_offset(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 						   (ih_item_len(ih) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 						    cpy_bytes) / UNFM_P_SIZE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 						   dest->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 				set_le_ih_k_type(&n_ih, TYPE_INDIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 				set_ih_free_space(&n_ih, get_ih_free_space(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			/* set item length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			put_ih_item_len(&n_ih, cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 			/* Endian safe, both le */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 			n_ih.ih_version = ih->ih_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			leaf_insert_into_buf(dest_bi, 0, &n_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 					     item_body(src, item_num) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 						ih_item_len(ih) - cpy_bytes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  * If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)  * to DEST.  If cpy_bytes not equal to minus one than copy cpy_num-1 whole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)  * items from SOURCE to DEST.  From last item copy cpy_num bytes for regular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519)  * item and cpy_num directory entries for directory item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 			   int last_first, int cpy_num, int cpy_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	struct buffer_head *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	int pos, i, src_nr_item, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	dest = dest_bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	RFALSE(!dest || !src, "vs-10210: !dest || !src");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	RFALSE(last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	       "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	RFALSE(B_NR_ITEMS(src) < cpy_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	       "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	       cpy_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	RFALSE(cpy_num < 0, "vs-10240: cpy_num < 0 (%d)", cpy_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	if (cpy_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (last_first == FIRST_TO_LAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		/* copy items to left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		if (cpy_num == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			bytes = cpy_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			bytes = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		 * copy the first item or it part or nothing to the end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		 * the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		cpy_num -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		if (cpy_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		pos += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		if (cpy_bytes == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 			 * copy first cpy_num items starting from position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			 * 'pos' of SOURCE to end of DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 						 pos, cpy_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			 * copy first cpy_num-1 items starting from position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 			 * 'pos-1' of the SOURCE to the end of the DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 			leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 						 pos, cpy_num - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 			 * copy part of the item which number is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 			 * cpy_num+pos-1 to the end of the DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 			leaf_item_bottle(dest_bi, src, FIRST_TO_LAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 					 cpy_num + pos - 1, cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		/* copy items to right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		src_nr_item = B_NR_ITEMS(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		if (cpy_num == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 			bytes = cpy_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 			bytes = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		 * copy the last item or it part or nothing to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		 * begin of the DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		 * (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		cpy_num -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		if (cpy_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		pos = src_nr_item - cpy_num - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		if (cpy_bytes == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			 * starting from position 'pos' copy last cpy_num
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 			 * items of SOURCE to begin of DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 						 pos, cpy_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			 * copy last cpy_num-1 items starting from position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 			 * 'pos+1' of the SOURCE to the begin of the DEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 						 pos + 1, cpy_num - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 			 * copy part of the item which number is pos to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			 * the begin of the DEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 					 cpy_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  * there are types of coping: from S[0] to L[0], from S[0] to R[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)  * from R[0] to L[0]. for each of these we have to define parent and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)  * positions of destination and source buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 				       struct buffer_info *dest_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 				       struct buffer_info *src_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 				       int *first_last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				       struct buffer_head *Snew)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	memset(dest_bi, 0, sizeof(struct buffer_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	memset(src_bi, 0, sizeof(struct buffer_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	/* define dest, src, dest parent, dest position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	switch (shift_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	case LEAF_FROM_S_TO_L:	/* it is used in leaf_shift_left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		src_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		/* src->b_item_order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		dest_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		dest_bi->bi_bh = tb->L[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		dest_bi->bi_parent = tb->FL[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		dest_bi->bi_position = get_left_neighbor_position(tb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		*first_last = FIRST_TO_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	case LEAF_FROM_S_TO_R:	/* it is used in leaf_shift_right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		src_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		dest_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		dest_bi->bi_bh = tb->R[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		dest_bi->bi_parent = tb->FR[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		dest_bi->bi_position = get_right_neighbor_position(tb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		*first_last = LAST_TO_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	case LEAF_FROM_R_TO_L:	/* it is used in balance_leaf_when_delete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		src_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		src_bi->bi_bh = tb->R[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		src_bi->bi_parent = tb->FR[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		src_bi->bi_position = get_right_neighbor_position(tb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		dest_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		dest_bi->bi_bh = tb->L[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		dest_bi->bi_parent = tb->FL[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		dest_bi->bi_position = get_left_neighbor_position(tb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		*first_last = FIRST_TO_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	case LEAF_FROM_L_TO_R:	/* it is used in balance_leaf_when_delete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		src_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		src_bi->bi_bh = tb->L[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		src_bi->bi_parent = tb->FL[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		src_bi->bi_position = get_left_neighbor_position(tb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		dest_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		dest_bi->bi_bh = tb->R[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		dest_bi->bi_parent = tb->FR[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		dest_bi->bi_position = get_right_neighbor_position(tb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		*first_last = LAST_TO_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	case LEAF_FROM_S_TO_SNEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		src_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		dest_bi->tb = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		dest_bi->bi_bh = Snew;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		dest_bi->bi_parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		dest_bi->bi_position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		*first_last = LAST_TO_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		reiserfs_panic(sb_from_bi(src_bi), "vs-10250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 			       "shift type is unknown (%d)", shift_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	RFALSE(!src_bi->bi_bh || !dest_bi->bi_bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	       "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	       shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)  * copy mov_num items and mov_bytes of the (mov_num-1)th item to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713)  * neighbor. Delete them from source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		    int mov_bytes, struct buffer_head *Snew)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	int ret_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	struct buffer_info dest_bi, src_bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	int first_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 				   &first_last, Snew);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	ret_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	    leaf_copy_items(&dest_bi, src_bi.bi_bh, first_last, mov_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			    mov_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	leaf_delete_items(&src_bi, first_last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			  (first_last ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			   FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 						 mov_num), mov_num, mov_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	return ret_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738)  * Shift shift_num items (and shift_bytes of last shifted item if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739)  * shift_bytes != -1) from S[0] to L[0] and replace the delimiting key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	 * move shift_num (and shift_bytes bytes) items from S[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	 * to left neighbor L[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (shift_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		/* number of items in S[0] == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		if (B_NR_ITEMS(S0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			RFALSE(shift_bytes != -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			       "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			       shift_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) #ifdef CONFIG_REISERFS_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 				print_cur_tb("vs-10275");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 				reiserfs_panic(tb->tb_sb, "vs-10275",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 					       "balance condition corrupted "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					       "(%c)", tb->tb_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			if (PATH_H_POSITION(tb->tb_path, 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 				replace_key(tb, tb->CFL[0], tb->lkey[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 					    PATH_H_PPARENT(tb->tb_path, 0), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			/* replace lkey in CFL[0] by 0-th key from S[0]; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			replace_key(tb, tb->CFL[0], tb->lkey[0], S0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			RFALSE((shift_bytes != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				!(is_direntry_le_ih(item_head(S0, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 				  && !ih_entry_count(item_head(S0, 0)))) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			       (!op_is_left_mergeable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 				(leaf_key(S0, 0), S0->b_size)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			       "vs-10280: item must be mergeable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) /* CLEANING STOPPED HERE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791)  * Shift shift_num (shift_bytes) items from S[0] to the right neighbor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792)  * and replace the delimiting key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	int ret_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	 * move shift_num (and shift_bytes) items from S[0] to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	 * right neighbor R[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	ret_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	    leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	/* replace rkey in CFR[0] by the 0-th key from R[0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	if (shift_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	return ret_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) static void leaf_delete_items_entirely(struct buffer_info *bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 				       int first, int del_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)  * If del_bytes == -1, starting from position 'first' delete del_num
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)  * items in whole in buffer CUR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819)  *   If not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820)  *   If last_first == 0. Starting from position 'first' delete del_num-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821)  *   items in whole. Delete part of body of the first item. Part defined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822)  *   del_bytes. Don't delete first item header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823)  *   If last_first == 1. Starting from position 'first+1' delete del_num-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824)  *   items in whole. Delete part of body of the last item . Part defined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825)  *   del_bytes. Don't delete last item header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		       int first, int del_num, int del_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	int item_amount = B_NR_ITEMS(bh = cur_bi->bi_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	RFALSE(!bh, "10155: bh is not defined");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	RFALSE(del_num < 0, "10160: del_num can not be < 0. del_num==%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	       del_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	RFALSE(first < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	       || first + del_num > item_amount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	       "10165: invalid number of first item to be deleted (%d) or "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	       "no so much items (%d) to delete (only %d)", first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	       first + del_num, item_amount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	if (del_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	if (first == 0 && del_num == item_amount && del_bytes == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		make_empty_node(cur_bi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		do_balance_mark_leaf_dirty(cur_bi->tb, bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (del_bytes == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		/* delete del_num items beginning from item in position first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		leaf_delete_items_entirely(cur_bi, first, del_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		if (last_first == FIRST_TO_LAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			 * delete del_num-1 items beginning from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			 * item in position first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			leaf_delete_items_entirely(cur_bi, first, del_num - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			 * delete the part of the first item of the bh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			 * do not delete item header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			 * delete del_num-1 items beginning from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			 * item in position first+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			leaf_delete_items_entirely(cur_bi, first + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 						   del_num - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			ih = item_head(bh, B_NR_ITEMS(bh) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 			if (is_direntry_le_ih(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 				/* the last item is directory  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 				 * len = numbers of directory entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 				 * in this item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 				len = ih_entry_count(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 				/* len = body len of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 				len = ih_item_len(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			 * delete the part of the last item of the bh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			 * do not delete item header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 					     len - del_bytes, del_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) /* insert item into the leaf node in position before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) void leaf_insert_into_buf(struct buffer_info *bi, int before,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			  struct item_head * const inserted_item_ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			  const char * const inserted_item_body,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			  int zeros_number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	struct buffer_head *bh = bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	int nr, free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct block_head *blkh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	int last_loc, unmoved_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	char *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	blkh = B_BLK_HEAD(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	nr = blkh_nr_item(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	free_space = blkh_free_space(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	/* check free space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	RFALSE(free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	       "vs-10170: not enough free space in block %z, new item %h",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	       bh, inserted_item_ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	RFALSE(zeros_number > ih_item_len(inserted_item_ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	       "vs-10172: zero number == %d, item length == %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	       zeros_number, ih_item_len(inserted_item_ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	/* get item new item must be inserted before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	ih = item_head(bh, before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	/* prepare space for the body of new item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	last_loc = nr ? ih_location(&ih[nr - before - 1]) : bh->b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	unmoved_loc = before ? ih_location(ih - 1) : bh->b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	memmove(bh->b_data + last_loc - ih_item_len(inserted_item_ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		bh->b_data + last_loc, unmoved_loc - last_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	memset(to, 0, zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	to += zeros_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	/* copy body to prepared space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	if (inserted_item_body)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		memmove(to, inserted_item_body,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 			ih_item_len(inserted_item_ih) - zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	/* insert item header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	memmove(ih + 1, ih, IH_SIZE * (nr - before));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	memmove(ih, inserted_item_ih, IH_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	/* change locations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	for (i = before; i < nr + 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		unmoved_loc -= ih_item_len(&ih[i - before]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		put_ih_location(&ih[i - before], unmoved_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	/* sizes, free space, item number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	set_blkh_free_space(blkh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			    free_space - (IH_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 					  ih_item_len(inserted_item_ih)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	do_balance_mark_leaf_dirty(bi->tb, bh, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (bi->bi_parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		struct disk_child *t_dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		put_dc_size(t_dc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			    dc_size(t_dc) + (IH_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 					     ih_item_len(inserted_item_ih)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975)  * paste paste_size bytes to affected_item_num-th item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976)  * When item is a directory, this only prepare space for new entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			  int pos_in_item, int paste_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			  const char *body, int zeros_number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	struct buffer_head *bh = bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	int nr, free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	struct block_head *blkh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	int last_loc, unmoved_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	blkh = B_BLK_HEAD(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	nr = blkh_nr_item(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	free_space = blkh_free_space(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	/* check free space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	RFALSE(free_space < paste_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	       "vs-10175: not enough free space: needed %d, available %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	       paste_size, free_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) #ifdef CONFIG_REISERFS_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (zeros_number > paste_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		struct super_block *sb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		if (bi && bi->tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 			sb = bi->tb->tb_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		print_cur_tb("10177");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		reiserfs_panic(sb, "vs-10177",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 			       "zeros_number == %d, paste_size == %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 			       zeros_number, paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) #endif				/* CONFIG_REISERFS_CHECK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	/* item to be appended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	ih = item_head(bh, affected_item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	last_loc = ih_location(&ih[nr - affected_item_num - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	unmoved_loc = affected_item_num ? ih_location(ih - 1) : bh->b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	/* prepare space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		unmoved_loc - last_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	/* change locations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	for (i = affected_item_num; i < nr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		put_ih_location(&ih[i - affected_item_num],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 				ih_location(&ih[i - affected_item_num]) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 				paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (body) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		if (!is_direntry_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 			if (!pos_in_item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 				/* shift data to right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 				memmove(bh->b_data + ih_location(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 					paste_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 					bh->b_data + ih_location(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 					ih_item_len(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 				/* paste data in the head of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 				memset(bh->b_data + ih_location(ih), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 				       zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 				memcpy(bh->b_data + ih_location(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 				       zeros_number, body,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 				       paste_size - zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 				memset(bh->b_data + unmoved_loc - paste_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 				       zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 				memcpy(bh->b_data + unmoved_loc - paste_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 				       zeros_number, body,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 				       paste_size - zeros_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	put_ih_item_len(ih, ih_item_len(ih) + paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	/* change free space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	set_blkh_free_space(blkh, free_space - paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	do_balance_mark_leaf_dirty(bi->tb, bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	if (bi->bi_parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		struct disk_child *t_dc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		    B_N_CHILD(bi->bi_parent, bi->bi_position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		put_dc_size(t_dc, dc_size(t_dc) + paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)  * cuts DEL_COUNT entries beginning from FROM-th entry. Directory item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)  * does not have free space, so it moves DEHs and remaining records as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)  * necessary. Return value is size of removed part of directory item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)  * in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static int leaf_cut_entries(struct buffer_head *bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			    struct item_head *ih, int from, int del_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	char *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	struct reiserfs_de_head *deh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	int prev_record_offset;	/* offset of record, that is (from-1)th */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	char *prev_record;	/* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	int cut_records_len;	/* length of all removed records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	 * make sure that item is directory and there are enough entries to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	 * remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	RFALSE(ih_entry_count(ih) < from + del_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	       "10185: item contains not enough entries: entry_count = %d, from = %d, to delete = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	       ih_entry_count(ih), from, del_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	if (del_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	/* first byte of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	item = bh->b_data + ih_location(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	/* entry head array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	deh = B_I_DEH(bh, ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	 * first byte of remaining entries, those are BEFORE cut entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	 * (prev_record) and length of all removed records (cut_records_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	prev_record_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	    (from ? deh_location(&deh[from - 1]) : ih_item_len(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	cut_records_len = prev_record_offset /*from_record */  -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	    deh_location(&deh[from + del_count - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	prev_record = item + prev_record_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	/* adjust locations of remaining entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	for (i = ih_entry_count(ih) - 1; i > from + del_count - 1; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		put_deh_location(&deh[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 				 deh_location(&deh[i]) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				 (DEH_SIZE * del_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	for (i = 0; i < from; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		put_deh_location(&deh[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 				 deh_location(&deh[i]) - (DEH_SIZE * del_count +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 							  cut_records_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	put_ih_entry_count(ih, ih_entry_count(ih) - del_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	/* shift entry head array and entries those are AFTER removed entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	memmove((char *)(deh + from),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		deh + from + del_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		prev_record - cut_records_len - (char *)(deh + from +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 							 del_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	/* shift records, those are BEFORE removed entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	memmove(prev_record - cut_records_len - DEH_SIZE * del_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		prev_record, item + ih_item_len(ih) - prev_record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	return DEH_SIZE * del_count + cut_records_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  * when cut item is part of regular file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  *      pos_in_item - first byte that must be cut
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  *      cut_size - number of bytes to be cut beginning from pos_in_item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * when cut item is part of directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  *      pos_in_item - number of first deleted entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  *      cut_size - count of deleted entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			  int pos_in_item, int cut_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	struct buffer_head *bh = bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	struct block_head *blkh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	int last_loc, unmoved_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	blkh = B_BLK_HEAD(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	nr = blkh_nr_item(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	/* item head of truncated item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	ih = item_head(bh, cut_item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	if (is_direntry_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		/* first cut entry () */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		cut_size = leaf_cut_entries(bh, ih, pos_in_item, cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		if (pos_in_item == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			/* change key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			RFALSE(cut_item_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			       "when 0-th enrty of item is cut, that item must be first in the node, not %d-th",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			       cut_item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			/* change item key by key of first entry in the item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 			set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		/* item is direct or indirect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		RFALSE(is_statdata_le_ih(ih), "10195: item is stat data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		RFALSE(pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		       "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		       (long unsigned)pos_in_item, (long unsigned)cut_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		       (long unsigned)ih_item_len(ih));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		/* shift item body to left if cut is from the head of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		if (pos_in_item == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 			memmove(bh->b_data + ih_location(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 				bh->b_data + ih_location(ih) + cut_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 				ih_item_len(ih) - cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			/* change key of item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			if (is_direct_le_ih(ih))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 				set_le_ih_k_offset(ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 						   le_ih_k_offset(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 						   cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 				set_le_ih_k_offset(ih,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 						   le_ih_k_offset(ih) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 						   (cut_size / UNFM_P_SIZE) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 						   bh->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 				RFALSE(ih_item_len(ih) == cut_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 				       && get_ih_free_space(ih),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 				       "10205: invalid ih_free_space (%h)", ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	/* location of the last item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	last_loc = ih_location(&ih[nr - cut_item_num - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	/* location of the item, which is remaining at the same place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	unmoved_loc = cut_item_num ? ih_location(ih - 1) : bh->b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	/* shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		unmoved_loc - last_loc - cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	/* change item length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	put_ih_item_len(ih, ih_item_len(ih) - cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (is_indirect_le_ih(ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		if (pos_in_item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			set_ih_free_space(ih, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	/* change locations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	for (i = cut_item_num; i < nr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		put_ih_location(&ih[i - cut_item_num],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 				ih_location(&ih[i - cut_item_num]) + cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	/* size, free space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	set_blkh_free_space(blkh, blkh_free_space(blkh) + cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	do_balance_mark_leaf_dirty(bi->tb, bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	if (bi->bi_parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		struct disk_child *t_dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		put_dc_size(t_dc, dc_size(t_dc) - cut_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) /* delete del_num items from buffer starting from the first'th item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static void leaf_delete_items_entirely(struct buffer_info *bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 				       int first, int del_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	struct buffer_head *bh = bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	int last_loc, last_removed_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	struct block_head *blkh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	RFALSE(bh == NULL, "10210: buffer is 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	RFALSE(del_num < 0, "10215: del_num less than 0 (%d)", del_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	if (del_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	blkh = B_BLK_HEAD(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	nr = blkh_nr_item(blkh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	RFALSE(first < 0 || first + del_num > nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	       "10220: first=%d, number=%d, there is %d items", first, del_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	       nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	if (first == 0 && del_num == nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		/* this does not work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		make_empty_node(bi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		do_balance_mark_leaf_dirty(bi->tb, bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	ih = item_head(bh, first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	/* location of unmovable item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	j = (first == 0) ? bh->b_size : ih_location(ih - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	/* delete items */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	last_loc = ih_location(&ih[nr - 1 - first]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	last_removed_loc = ih_location(&ih[del_num - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	memmove(bh->b_data + last_loc + j - last_removed_loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		bh->b_data + last_loc, last_removed_loc - last_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	/* delete item headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	/* change item location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	for (i = first; i < nr - del_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		put_ih_location(&ih[i - first],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 				ih_location(&ih[i - first]) + (j -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 								 last_removed_loc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	/* sizes, item number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	set_blkh_nr_item(blkh, blkh_nr_item(blkh) - del_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	set_blkh_free_space(blkh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 			    blkh_free_space(blkh) + (j - last_removed_loc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 						     IH_SIZE * del_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	do_balance_mark_leaf_dirty(bi->tb, bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	if (bi->bi_parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		struct disk_child *t_dc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		    B_N_CHILD(bi->bi_parent, bi->bi_position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		put_dc_size(t_dc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 			    dc_size(t_dc) - (j - last_removed_loc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 					     IH_SIZE * del_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)  * paste new_entry_count entries (new_dehs, records) into position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)  * before to item_num-th item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) void leaf_paste_entries(struct buffer_info *bi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 			int item_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 			int before,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 			int new_entry_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 			struct reiserfs_de_head *new_dehs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 			const char *records, int paste_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	struct item_head *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	char *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	struct reiserfs_de_head *deh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	char *insert_point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	struct buffer_head *bh = bi->bi_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	if (new_entry_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	ih = item_head(bh, item_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	 * make sure, that item is directory, and there are enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	 * records in it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	RFALSE(ih_entry_count(ih) < before,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	       "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	       ih_entry_count(ih), before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	/* first byte of dest item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	item = bh->b_data + ih_location(ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	/* entry head array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	deh = B_I_DEH(bh, ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	/* new records will be pasted at this point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	insert_point =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	    item +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	    (before ? deh_location(&deh[before - 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	     : (ih_item_len(ih) - paste_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	/* adjust locations of records that will be AFTER new records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	for (i = ih_entry_count(ih) - 1; i >= before; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		put_deh_location(&deh[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 				 deh_location(&deh[i]) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 				 (DEH_SIZE * new_entry_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	/* adjust locations of records that will be BEFORE new records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	for (i = 0; i < before; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		put_deh_location(&deh[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 				 deh_location(&deh[i]) + paste_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	put_ih_entry_count(ih, ih_entry_count(ih) + new_entry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	/* prepare space for pasted records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	memmove(insert_point + paste_size, insert_point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		item + (ih_item_len(ih) - paste_size) - insert_point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	/* copy new records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	memcpy(insert_point + DEH_SIZE * new_entry_count, records,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	       paste_size - DEH_SIZE * new_entry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	/* prepare space for new entry heads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	deh += before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	memmove((char *)(deh + new_entry_count), deh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		insert_point - (char *)deh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	/* copy new entry heads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	deh = (struct reiserfs_de_head *)((char *)deh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	memcpy(deh, new_dehs, DEH_SIZE * new_entry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	/* set locations of new records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	for (i = 0; i < new_entry_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		put_deh_location(&deh[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 				 deh_location(&deh[i]) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 				 (-deh_location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 				  (&new_dehs[new_entry_count - 1]) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 				  insert_point + DEH_SIZE * new_entry_count -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 				  item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	/* change item key if necessary (when we paste before 0-th entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	if (!before) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		set_le_ih_k_offset(ih, deh_offset(new_dehs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) #ifdef CONFIG_REISERFS_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		int prev, next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		/* check record locations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		deh = B_I_DEH(bh, ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		for (i = 0; i < ih_entry_count(ih); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 			next =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			    (i <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 			     ih_entry_count(ih) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 			     1) ? deh_location(&deh[i + 1]) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 			prev = (i != 0) ? deh_location(&deh[i - 1]) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 			if (prev && prev <= deh_location(&deh[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 				reiserfs_error(sb_from_bi(bi), "vs-10240",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 					       "directory item (%h) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 					       "corrupted (prev %a, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 					       "cur(%d) %a)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 					       ih, deh + i - 1, i, deh + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 			if (next && next >= deh_location(&deh[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 				reiserfs_error(sb_from_bi(bi), "vs-10250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 					       "directory item (%h) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 					       "corrupted (cur(%d) %a, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 					       "next %a)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 					       ih, i, deh + i, deh + i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }