📄 lbalance.c
字号:
if ( body ) { if (!I_IS_DIRECTORY_ITEM(ih)) { //if (mem_mode == REISERFS_USER_MEM) { //memset (bh->b_data + unmoved_loc - paste_size, 0, zeros_number); //copy_from_user (bh->b_data + unmoved_loc - paste_size + zeros_number, body, paste_size - zeros_number); //} else { if (!pos_in_item) { /* shift data to right */ memmove (bh->b_data + get_ih_location (ih) + paste_size, bh->b_data + get_ih_location (ih), get_ih_item_len (ih)); /* paste data in the head of item */ memset (bh->b_data + get_ih_location (ih), 0, zeros_number); memcpy (bh->b_data + get_ih_location (ih) + zeros_number, body, paste_size - zeros_number); } else { memset (bh->b_data + unmoved_loc - paste_size, 0, zeros_number); memcpy (bh->b_data + unmoved_loc - paste_size + zeros_number, body, paste_size - zeros_number); } } } } else memset(bh->b_data + unmoved_loc - paste_size,'\0',paste_size); set_ih_item_len (ih, get_ih_item_len (ih) + paste_size); /* change free space */ set_blkh_free_space (blkh, get_blkh_free_space (blkh) - paste_size); mark_buffer_dirty(bh) ; if (bi->bi_parent) { struct disk_child * dc; dc = B_N_CHILD (bi->bi_parent, bi->bi_position); set_dc_child_size (dc, get_dc_child_size (dc) + paste_size); mark_buffer_dirty(bi->bi_parent); } if (is_a_leaf(bh->b_data, bh->b_size) != THE_LEAF) reiserfs_panic ("leaf_paste_in_buffer: bad leaf %lu: %b", bh->b_blocknr, bh);}/* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item does not have free space, so it moves DEHs and remaining records as necessary. Return value is size of removed part of directory item in bytes. */static int leaf_cut_entries (struct buffer_head * bh, struct item_head * ih, int from, int del_count){ char * item; struct reiserfs_de_head * deh; int prev_record_offset; /* offset of record, that is (from-1)th */ char * prev_record; /* */ int cut_records_len; /* length of all removed records */ int i; int entry_count; /* first byte of item */ item = B_I_PITEM (bh, ih); /* entry head array */ deh = B_I_DEH (bh, ih); entry_count = get_ih_entry_count (ih); if (del_count == 0) { int shift; int last_location; last_location = get_deh_location (deh + entry_count - 1); shift = last_location - DEH_SIZE * entry_count; memmove (deh + entry_count, item + last_location, get_ih_item_len (ih) - last_location); for (i = 0; i < entry_count; i ++) set_deh_location (&deh[i], get_deh_location (&deh[i]) - shift); return shift; } /* first byte of remaining entries, those are BEFORE cut entries (prev_record) and length of all removed records (cut_records_len) */ prev_record_offset = (from ? get_deh_location (&deh[from - 1]) : get_ih_item_len (ih)); cut_records_len = prev_record_offset/*from_record*/ - get_deh_location (&deh[from + del_count - 1]); prev_record = item + prev_record_offset; /* adjust locations of remaining entries */ for (i = get_ih_entry_count (ih) - 1; i > from + del_count - 1; i --) { set_deh_location (deh + i, get_deh_location (deh + i) - (DEH_SIZE * del_count)); } for (i = 0; i < from; i ++) { set_deh_location (deh + i, get_deh_location (deh + i) - (DEH_SIZE * del_count + cut_records_len)); } set_ih_entry_count (ih, get_ih_entry_count (ih) - del_count); /* shift entry head array and entries those are AFTER removed entries */ memmove ((char *)(deh + from), deh + from + del_count, prev_record - cut_records_len - (char *)(deh + from + del_count)); /* shift records, those are BEFORE removed entries */ memmove (prev_record - cut_records_len - DEH_SIZE * del_count, prev_record, item + get_ih_item_len (ih) - prev_record); return DEH_SIZE * del_count + cut_records_len;}/* when cut item is part of regular file pos_in_item - first byte that must be cut cut_size - number of bytes to be cut beginning from pos_in_item when cut item is part of directory pos_in_item - number of first deleted entry cut_size - count of deleted entries */void leaf_cut_from_buffer (reiserfs_filsys_t * fs, struct buffer_info * bi, int cut_item_num, int pos_in_item, int cut_size){ int nr; struct buffer_head * bh = bi->bi_bh; struct block_head * blkh; struct item_head * ih; int last_loc, unmoved_loc; int i; blkh = B_BLK_HEAD (bh); nr = get_blkh_nr_items (blkh); /* item head of truncated item */ ih = B_N_PITEM_HEAD (bh, cut_item_num); if (I_IS_DIRECTORY_ITEM (ih)) { /* first cut entry ()*/ cut_size = leaf_cut_entries (bh, ih, pos_in_item, cut_size); if (pos_in_item == 0) { /* change item key by key of first entry in the item */ set_key_offset_v1 (&ih->ih_key, get_deh_offset (B_I_DEH (bh, ih))); /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE);*/ } } else { /* item is direct or indirect */ /* shift item body to left if cut is from the head of item */ if (pos_in_item == 0) { memmove (bh->b_data + get_ih_location (ih), bh->b_data + get_ih_location (ih) + cut_size, get_ih_item_len (ih) - cut_size); /* change key of item */ if (I_IS_DIRECT_ITEM(ih)) { //ih->ih_key.k_offset += cut_size; set_offset (key_format (&ih->ih_key), &ih->ih_key, get_offset (&ih->ih_key) + cut_size); } else { //ih->ih_key.k_offset += (cut_size / UNFM_P_SIZE) * bh->b_size; set_offset (key_format (&ih->ih_key), &ih->ih_key, get_offset (&ih->ih_key) + (cut_size / UNFM_P_SIZE) * bh->b_size); } } } /* location of the last item */ last_loc = get_ih_location (&ih[nr - cut_item_num - 1]); /* location of the item, which is remaining at the same place */ unmoved_loc = cut_item_num ? get_ih_location (ih-1) : bh->b_size; /* shift */ memmove (bh->b_data + last_loc + cut_size, bh->b_data + last_loc, unmoved_loc - last_loc - cut_size); /* change item length */ set_ih_item_len (ih, get_ih_item_len (ih) - cut_size); if (I_IS_INDIRECT_ITEM(ih)) { if (pos_in_item) //ih->u.ih_free_space = 0; set_ih_free_space (ih, 0); } /* change locations */ for (i = cut_item_num; i < nr; i ++) { set_ih_location (&ih[i-cut_item_num], get_ih_location (&ih[i-cut_item_num]) + cut_size); } /* size, free space */ set_blkh_free_space (blkh, get_blkh_free_space (blkh) + cut_size); mark_buffer_dirty(bh); if (bi->bi_parent) { struct disk_child * dc; dc = B_N_CHILD (bi->bi_parent, bi->bi_position); set_dc_child_size (dc, get_dc_child_size (dc) - cut_size); mark_buffer_dirty(bi->bi_parent); } if (is_a_leaf(bh->b_data, bh->b_size) != THE_LEAF && is_a_leaf(bh->b_data, bh->b_size) != HAS_IH_ARRAY) reiserfs_panic ("leaf_cut_from_buffer: bad leaf %lu: %b", bh->b_blocknr, bh);}/* delete del_num items from buffer starting from the first'th item */static void leaf_delete_items_entirely (reiserfs_filsys_t * fs, struct buffer_info * bi, int first, int del_num){ struct buffer_head * bh = bi->bi_bh; int nr; int i, j; int last_loc, last_removed_loc; struct block_head * blkh; struct item_head * ih; if (del_num == 0) return; blkh = B_BLK_HEAD (bh); nr = get_blkh_nr_items (blkh); if (first == 0 && del_num == nr) { /* this does not work */ make_empty_node (bi); mark_buffer_dirty(bh); return; } ih = B_N_PITEM_HEAD (bh, first); /* location of unmovable item */ j = (first == 0) ? bh->b_size : get_ih_location (ih-1); /* delete items */ last_loc = get_ih_location (&ih[nr - 1 - first]); last_removed_loc = get_ih_location (&ih[del_num-1]); memmove (bh->b_data + last_loc + j - last_removed_loc, bh->b_data + last_loc, last_removed_loc - last_loc); /* delete item headers */ memmove (ih, ih + del_num, (nr - first - del_num) * IH_SIZE); /* change item location */ for (i = first; i < nr - del_num; i ++) { set_ih_location (&ih[i-first], get_ih_location (&ih[i-first]) + j - last_removed_loc); } /* sizes, item number */ set_blkh_nr_items (blkh, get_blkh_nr_items (blkh)/*nr*/ - del_num); set_blkh_free_space (blkh, get_blkh_free_space (blkh) + j - last_removed_loc + IH_SIZE * del_num); mark_buffer_dirty(bh); if (bi->bi_parent) { struct disk_child * dc; dc = B_N_CHILD (bi->bi_parent, bi->bi_position); set_dc_child_size (dc, get_dc_child_size (dc) - (j - last_removed_loc + IH_SIZE * del_num)); mark_buffer_dirty(bi->bi_parent); } if (is_a_leaf(bh->b_data, bh->b_size) != THE_LEAF && is_a_leaf(bh->b_data, bh->b_size) != HAS_IH_ARRAY) reiserfs_panic ("leaf_delete_items_entirely: bad leaf %lu: %b", bh->b_blocknr, bh);}/* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */void leaf_paste_entries (struct buffer_head * bh, int item_num, int before, int new_entry_count, struct reiserfs_de_head * new_dehs, const char * records, int paste_size){ struct item_head * ih; char * item; struct reiserfs_de_head * deh; char * insert_point; int i, old_entry_num; if (new_entry_count == 0) return; ih = B_N_PITEM_HEAD(bh, item_num); /* first byte of dest item */ item = B_I_PITEM (bh, ih); /* entry head array */ deh = B_I_DEH (bh, ih); /* new records will be pasted at this point */ insert_point = item + (before ? get_deh_location (&deh[before - 1]) : (get_ih_item_len (ih) - paste_size)); /* adjust locations of records that will be AFTER new records */ for (i = get_ih_entry_count (ih) - 1; i >= before; i --) set_deh_location (deh + i, get_deh_location (deh + i) + DEH_SIZE * new_entry_count); /* adjust locations of records that will be BEFORE new records */ for (i = 0; i < before; i ++) set_deh_location (deh + i, get_deh_location (deh + i) + paste_size); old_entry_num = get_ih_entry_count (ih); //I_ENTRY_COUNT(ih) += new_entry_count; set_ih_entry_count (ih, old_entry_num + new_entry_count); /* prepare space for pasted records */ memmove (insert_point + paste_size, insert_point, item + (get_ih_item_len (ih) - paste_size) - insert_point); /* copy new records */ memcpy (insert_point + DEH_SIZE * new_entry_count, records, paste_size - DEH_SIZE * new_entry_count); /* prepare space for new entry heads */ deh += before; memmove ((char *)(deh + new_entry_count), deh, insert_point - (char *)deh); /* copy new entry heads */ memcpy (deh, new_dehs, DEH_SIZE * new_entry_count); /* set locations of new records */ for (i = 0; i < new_entry_count; i ++) set_deh_location (deh + i, get_deh_location (deh + i) + (- get_deh_location (&new_dehs[new_entry_count - 1]) + insert_point + DEH_SIZE * new_entry_count - item)); /* change item key if neccessary (when we paste before 0-th entry */ if (!before) set_key_offset_v1 (&ih->ih_key, get_deh_offset (new_dehs));}/* wrappers for operations on one separated node */void delete_item (reiserfs_filsys_t * fs, struct buffer_head * bh, int item_num){ struct buffer_info bi; bi.bi_bh = bh; bi.bi_parent = 0; bi.bi_position = 0; leaf_delete_items_entirely (fs, &bi, item_num, 1);}void cut_entry (reiserfs_filsys_t * fs, struct buffer_head * bh, int item_num, int entry_num, int del_count){ struct buffer_info bi; bi.bi_bh = bh; bi.bi_parent = 0; bi.bi_position = 0; leaf_cut_from_buffer (fs, &bi, item_num, entry_num, del_count);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -