void ItemList::init_actions() { PasspotPlugin *plugin = dynamic_cast<PasspotPlugin*>(get_plugin().pointer()); assert(NULL != plugin); // add article _new_action = new QAction(plugin->load_icon("passpot/add_item"), tr("添加(&A)"), this); _new_action->setStatusTip(tr("添加新记录")); _new_action->setToolTip(tr("添加新记录")); connect(_new_action, SIGNAL(triggered()), this, SLOT(add_item())); _edit_action = new QAction(plugin->load_icon("passpot/edit_item"), tr("编辑(&E)"), this); _edit_action->setStatusTip(tr("编辑当前记录")); _edit_action->setToolTip(tr("编辑当前记录")); connect(_edit_action, SIGNAL(triggered()), this, SLOT(edit_item())); _move_to_trash_action = new QAction(plugin->load_icon("passpot/move_to_trash"), tr("移动到回收站(&T)"), this); _move_to_trash_action->setStatusTip(tr("将当前记录移动到回收站")); _move_to_trash_action->setToolTip(tr("将当前记录移动到回收站")); connect(_move_to_trash_action, SIGNAL(triggered()), this, SLOT(move_to_trash())); // delete article _delete_action = new QAction(plugin->load_icon("passpot/delete"), tr("删除(&D)"), this); _delete_action->setStatusTip(tr("永久删除当前记录")); _delete_action->setToolTip(tr("永久删除当前记录")); connect(_delete_action, SIGNAL(triggered()), this, SLOT(delete_item())); }
/* * Removes items from the macro list; use purgeOnly to specify which items * to purge. Returns PURGE_NOACTION if nothing was done, PURGE_PURGED if * a matching item was purged, or PURGE_SKIPPED if an item with the correct * name was found but which wasn't allowed to be purged due to purgeOnly. */ static int purge_from_list( int purgeOnly, const char *name ) /***********************************************************/ { ListElem *curElem = macroList; int retcode = PURGE_NOACTION; /*** Try to find the item ***/ while( curElem != NULL ) { if( !strcmp( name, curElem->name ) ) { if( (purgeOnly==PURGE_ALL) || (purgeOnly==PURGE_DEFINE && curElem->type==DEFINE) ) { /*** Found one we're allowed to delete ***/ delete_item( curElem ); retcode = PURGE_PURGED; break; } else { /*** Found one we're not allowed to delete ***/ retcode = PURGE_SKIPPED; break; } } curElem = curElem->next; } return( retcode ); }
void delete_item(cst_item *item) { cst_item *ds, *nds; if (item->n != NULL) { item->n->p = item->p; item->n->u = item->u; /* in trees if this is first daughter */ } if (item->p != NULL) item->p->n = item->n; if (item->u != NULL) item->u->d = item->n; /* when first daughter */ if (item->relation) { if (item->relation->head == item) item->relation->head = item->n; if (item->relation->tail == item) item->relation->tail = item->p; } /* Delete all the daughters of item */ for (ds = item->d; ds; ds=nds) { nds = ds->n; delete_item(ds); } item_unref_contents(item); cst_utt_free(item->relation->utterance, item); }
/* * Get the next define string in the list. Returns NULL if nothing to get. */ char *GetNextDefineMacro( void ) /******************************/ { ListElem *curElem = macroList; char *str; size_t len; while( curElem != NULL ) { if( curElem->type == DEFINE ) { /*** Allocate a buffer to hold it ***/ len = strlen( curElem->name ); /* room for NAME */ if( curElem->value != NULL ) { len++; /* room for = */ len += strlen( curElem->value );/* room for VALUE */ } len++; /* room for '\0' */ str = AllocMem( len ); /*** Fill in the buffer ***/ strcpy( str, curElem->name ); if( curElem->value != NULL ) { strcat( str, "=" ); strcat( str, curElem->value ); } /*** Clean up and go home ***/ delete_item( curElem ); return( str ); } curElem = curElem->next; } return( NULL ); }
static protocol_binary_response_status delete_handler(const void *cookie, const void *key, uint16_t keylen, uint64_t cas) { (void)cookie; protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; if (cas != 0) { struct item *item= get_item(key, keylen); if (item != NULL) { if (item->cas != cas) { release_item(item); return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; } release_item(item); } } if (!delete_item(key, keylen)) { rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; } return rval; }
void main() { int len, pos, *del; plist pl = NULL; del = (int*)malloc(sizeof(int)); pl = init_list(); isEmpty_list(pl); insert_item(pl, 1, 1); insert_item(pl, 2, 3); insert_item(pl, 3, 5); insert_item(pl, 4, 7); insert_item(pl, 5, 9); insert_item(pl, 6, 11); display(pl); len = len_list(pl); printf("link list len: %d\n", len); pos = locate_item(pl, 7); printf("num 7 pos: %d\n", pos); delete_item(pl, 3, del); printf("delete pos 3 num: %d\n", *del); display(pl); printf("link list traverse...\n"); pl = traverse_list(pl); display(pl); destroy_list(pl); getch(); }
int main(){ srand(time(0)); //Creating memory managers mm_t *MM = malloc(sizeof(mm_t)); mm_init(MM,1500,sizeof(node)); mm_t *MM2 = malloc(sizeof(mm_t)); mm_init(MM2,3,sizeof(dl_list)); //Creating Lists dl_list *dl_1 = mm_get(MM2); dl_list *dl_2 = mm_get(MM2); dl_list *dl_3 = mm_get(MM2); dl_list_init(dl_1); dl_list_init(dl_2); dl_list_init(dl_3); int i; for(i = 0; i<500; i++) insert_item(dl_1,i,MM); print_list(dl_1); for(i = 0; i<500; i++) insert_item(dl_2,rand()%500,MM); print_list(dl_2); for(i = 0; i<500; i++) insert_item(dl_3,get_element(dl_1,i)+get_element(dl_2,i),MM); print_list(dl_3); //Deleting items from list 1 for(i = 0; i<100; i++) delete_item(dl_1,get_element(dl_3,i),MM); print_list(dl_1); //Joining lists join_lists(dl_2,dl_1); join_lists(dl_3,dl_2); print_list(dl_3); empty_list(dl_3,MM); //Deallocating and freeing mm_put(MM,dl_1); mm_put(MM,dl_2); mm_put(MM,dl_3); free(MM); free(MM2); return 0; }
void btree_page_data::remove_items( const int item_count, // In: Number of records to remove const w_keystr_t &high) // In: high fence after record removal { // Use this function with caution // A special helper function to remove 'item_count' largest items from the storage // this function is only used by full logging page rebalance restart operation // to recover the source page after a system crash // the caller resets the fence keys on source page which eliminate some // of the records from source page // this function removes the largest 'item_count' items from the page // because they belong to destination page after the rebalance // After the removal, item count changed but no change to ghost count w_assert1(btree_level >= 1); w_assert1(nitems > item_count); // Must have at least one record which is the fency key record w_assert3(_items_are_consistent()); if ((0 == item_count) || (1 == nitems)) // If 1 == nitems, we only have a fence key record return; DBGOUT3( << "btree_page_data::reset_item_count - before deletion item count: " << nitems << ", new high fence key: " << high); int remaining = item_count; char* high_key_p = (char *)high.buffer_as_keystr(); size_t high_key_length = (size_t)high.get_length_as_keystr(); while (0 < remaining) { w_assert1(1 < nitems); // Find the records with key >= new high fence key and delete them int item_index = 1; // Start with index 1 since 0 is for the fence key record uint16_t* key_length;; size_t item_len; int cmp; const int data_offset = sizeof(uint16_t); // To skipover the portion which contains the size of variable data for (int i = item_index; i < nitems; ++i) { key_length = (uint16_t*)item_data(i); item_len = *key_length++; cmp = ::memcmp(high_key_p, item_data(i)+data_offset, (high_key_length<=item_len)? high_key_length : item_len); if ((0 > cmp) || ((0 == cmp) && (high_key_length <= item_len))) { // The item is larger than the new high fence key or the same as high fence key (high fence is ghost) DBGOUT3( << "btree_page_data::reset_item_count - delete record index: " << i); // Delete the item, which changes nitems but no change to nghosts // therefore break out the loop and start the loop again if we have more items to remove delete_item(i); break; } } --remaining; }
int main() { int suc,num_suc; int del_val; int num; node *root; int choice=1,menu_choice; root=(node *)malloc(sizeof(node)); printf("enter the value at the node: "); scanf("%d",&num); printf("\n"); root->data=num; root->lchild=NULL; root->rchild=NULL; while(choice==1) { printf("what do you want to do:\n\n1.>insert a node\n2.>delete a node\n3.>print the tree in inorder\n4.>exit\n\n"); printf("please enter your choice: "); scanf("%d",&menu_choice); printf("\n"); if(menu_choice==1) { insert(root); } else if(menu_choice==2) { del_val=delete_item(root); if(del_val!=0) printf("\n%d has been successfully deleted\n",del_val); } else if(menu_choice==3) { printf("\n"); print_tree(root); printf("NULL\n\n"); } else if(menu_choice==4) exit(-1); printf("enter 1 to go to the main menu or '0' to exit: "); scanf("%d",&choice); printf("\n"); if(choice==0) exit(-1); printf("\n"); } return 0; }
struct item *add_item(struct page *pg, long money, const struct string *desc, const struct string *comment) { struct item *p; if ((p = add_dummy_item(pg)) == NULL) return NULL; if (item_set(p, money, desc, comment) == NULL) { delete_item(p); return NULL; } return p; }
static void move_item(struct btree_page *from, int from_pos, struct btree_page *to, int to_pos) { if (from->height) insert_ptr(to, to_pos, PAGE_KEY(from, from_pos), *PAGE_PTR(from, from_pos)); else insert_data(to, to_pos, PAGE_KEY(from, from_pos), PAGE_DATA(from, from_pos)); delete_item(from, from_pos); }
void delete_items_from_data(struct data *dt) { struct ulist_item *p, *q, *t; for (p = dt->pages.first; p != NULL; p = p->next) { struct page *pg = get_page(p); for (q = pg->items.first; q != NULL; q = t) { struct item *it = get_item(q); t = q->next; if (is_set(it->flag, ITEM_TO_BE_DELETED)) delete_item(it); } if (ulist_is_empty(&pg->items)) add_dummy_item(pg); } }
void list_delete(LIST *list, void (*delete_item)(void *data)) { LIST_ITEM *p, *q; p = list->top; while (p) { q = p->next; if ((delete_item) && (p->data)) { delete_item(p->data); }; free(p); p = q; }; free(list); return; }
static protocol_binary_response_status prepend_handler(const void *cookie, const void *key, uint16_t keylen, const void* val, uint32_t vallen, uint64_t cas, uint64_t *result_cas) { (void)cookie; protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; struct item *item= get_item(key, keylen); struct item *nitem= NULL; if (item == NULL) { rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; } else if (cas != 0 && cas != item->cas) { rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; } else if ((nitem= create_item(key, keylen, NULL, item->size + vallen, item->flags, item->exp)) == NULL) { rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else { memcpy(nitem->data, val, vallen); memcpy(((char*)(nitem->data)) + vallen, item->data, item->size); release_item(item); item= NULL; delete_item(key, keylen); put_item(nitem); *result_cas= nitem->cas; } if (item) release_item(item); if (nitem) release_item(nitem); return rval; }
/* Returns -1 on error, 0 on missing dir, and 1 on present dir. */ static int validate_backup_dir(void) { STRUCT_STAT st; if (do_lstat(backup_dir_buf, &st) < 0) { if (errno == ENOENT) return 0; rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf); return -1; } if (!S_ISDIR(st.st_mode)) { int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE; if (delete_item(backup_dir_buf, st.st_mode, flags) == 0) return 0; return -1; } return 1; }
static protocol_binary_response_status decrement_handler(const void *cookie, const void *key, uint16_t keylen, uint64_t delta, uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) { protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; uint64_t val= initial; item_t *item; (void)cookie; mutex_lock(&storage_lock); item = get_item(key, keylen); if (item != NULL) { if (delta > *(uint64_t*)item->data) val= 0; else val= *(uint64_t*)item->data - delta; expiration= (uint32_t)item->exp; release_item(item); delete_item(key, keylen); } item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration); if (item == 0) { rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else { memcpy(item->data, &val, sizeof(val)); put_item(item); *result= val; *result_cas= item->cas; release_item(item); } mutex_unlock(&storage_lock); return rval; }
void free_data(t_data *data) { int i; i = -1; free_buttons(data->menu->buttons); while (++i < 14) { bunny_free(data->tab[i].name); bunny_delete_clipable(&data->tab[i].front->clipable); delete_item(data->tab[i].item); if (i == 0 || i == 1 || i == 4 || i == 9) bunny_delete_clipable(&data->tab[i].back->clipable); else if (i == 3 || i == 5 || i == 6) { bunny_delete_clipable(&data->tab[i].back->clipable); bunny_delete_clipable(&data->tab[i].middle->clipable); } } }
static protocol_binary_response_status replace_handler(const void *cookie, const void *key, uint16_t keylen, const void* data, uint32_t datalen, uint32_t flags, uint32_t exptime, uint64_t cas, uint64_t *result_cas) { (void)cookie; protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; struct item* item= get_item(key, keylen); if (item == NULL) { rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; } else if (cas == 0 || cas == item->cas) { release_item(item); delete_item(key, keylen); item= create_item(key, keylen, data, datalen, flags, (time_t)exptime); if (item == 0) { rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else { put_item(item); *result_cas= item->cas; release_item(item); } } else { rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; release_item(item); } return rval; }
static protocol_binary_response_status increment_handler(const void *cookie, const void *key, uint16_t keylen, uint64_t delta, uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) { protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; uint64_t val= initial; item_t *item; (void)cookie; mutex_lock(&storage_lock); item = get_item(key, keylen); if (item != NULL) { val= (*(uint64_t*)item->data) + delta; expiration= (uint32_t)item->exp; release_item(item); delete_item(key, keylen); } item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration); if (item == NULL) { rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else { char buffer[1024] = {0}; // FIXME: does this need to be so big ~ajc memcpy(buffer, key, keylen); memcpy(item->data, &val, sizeof(val)); put_item(item); *result= val; *result_cas= item->cas; release_item(item); } mutex_unlock(&storage_lock); return rval; }
static protocol_binary_response_status set_handler(const void *cookie, const void *key, uint16_t keylen, const void* data, uint32_t datalen, uint32_t flags, uint32_t exptime, uint64_t cas, uint64_t *result_cas) { (void)cookie; protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; if (cas != 0) { struct item* item= get_item(key, keylen); if (item != NULL && cas != item->cas) { /* Invalid CAS value */ release_item(item); return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; } } delete_item(key, keylen); struct item* item= create_item(key, keylen, data, datalen, flags, (time_t)exptime); if (item == 0) { rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else { put_item(item); *result_cas= item->cas; release_item(item); } return rval; }
/* * Get the next undefine string in the list. Returns NULL if nothing to get. */ char *GetNextUndefineMacro( void ) /********************************/ { ListElem *curElem = macroList; char *str; size_t len; while( curElem != NULL ) { if( curElem->type == UNDEFINE ) { /*** Copy the macro name ***/ len = strlen( curElem->name ) + 1; /* room for NAME\0 */ str = AllocMem( len ); strcpy( str, curElem->name ); /*** Clean up and go home ***/ delete_item( curElem ); return( str ); } curElem = curElem->next; } return( NULL ); }
static protocol_binary_response_status append_handler(const void *cookie, const void *key, uint16_t keylen, const void* val, uint32_t vallen, uint64_t cas, uint64_t *result_cas) { protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS; item_t *item, *nitem; mutex_lock(&storage_lock); (void)cookie; item= get_item(key, keylen); if (item == NULL) { rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; } else if (cas != 0 && cas != item->cas) { rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; } else if ((nitem= create_item(key, keylen, NULL, item->size + vallen, item->flags, item->exp)) == NULL) { release_item(item); rval= PROTOCOL_BINARY_RESPONSE_ENOMEM; } else { memcpy(nitem->data, item->data, item->size); memcpy(((char*)(nitem->data)) + item->size, val, vallen); release_item(item); delete_item(key, keylen); put_item(nitem); *result_cas= nitem->cas; release_item(nitem); } mutex_unlock(&storage_lock); return rval; }
/* check directory item and try to recover something */ static int verify_directory_item (reiserfs_filsys_t fs, struct buffer_head * bh, int item_num) { struct item_head * ih; struct item_head tmp; char * item; struct reiserfs_de_head * deh; char * name; int name_len; int bad; int i, j; #if 0 int bad_entries; /* how many bad neighboring entries */ int total_entry_len; char * entries, * end; #endif int dirty; int entry_count; int hash_code; int bad_locations; #ifdef DEBUG_VERIFY_DENTRY char * direntries; #endif ih = B_N_PITEM_HEAD (bh, item_num); item = B_I_PITEM (bh,ih); deh = (struct reiserfs_de_head *)item; dirty = 0; bad_locations = 0; entry_count = ih_entry_count (ih); /* check deh_location */ for (i = 0; i < ih_entry_count (ih); i ++) { /* silently fix deh_state */ if (deh [i].deh_state != (1 << DEH_Visible)) { deh [i].deh_state = cpu_to_le16 (1 << DEH_Visible); mark_buffer_dirty (bh); } if (dir_entry_bad_location (deh + i, ih, !i)) mark_de_bad_location (deh + i); } #ifdef DEBUG_VERIFY_DENTRY direntries = getmem (ih_entry_count (ih) * sizeof (int)); printf ("entries with bad locations: "); for (i = 0; i < ih_entry_count (ih); i ++) { if (de_bad_location (deh + i)) printf ("%d ", i); } printf ("\n"); #endif /* DEBUG_VERIFY_DENTRY */ /* find entries names in which have mismatching deh_offset */ for (i = ih_entry_count (ih) - 1; i >= 0; i --) { if (de_bad (deh + i)) /* bad location */ continue; if (i) { if (deh_location (deh + i - 1) < deh_location (deh + i)) mark_de_bad_location (deh + i - 1); } name = name_in_entry (deh + i, i); /* we found a name, but we not always we can get its length as it depends on deh_location of previous entry */ name_len = try_to_get_name_length (ih, deh + i, i); #ifdef DEBUG_VERIFY_DENTRY if (name_len == 0) printf ("trying to find name length for %d-th entry\n", i); #endif /* DEBUG_VERIFY_DENTRY */ if (is_dot (name, name_len)) { if (i != 0) fsck_log ("block %lu: item %d: \".\" is %d-th entry\n", bh->b_blocknr, item_num, i); /* check and fix "." */ if (deh_offset (deh + i) != DOT_OFFSET) { set_deh_offset(&(deh[i]), DOT_OFFSET); mark_buffer_dirty (bh); } /* "." must point to the directory it is in */ if (not_of_one_file (&(deh[i].deh_dir_id), &(ih->ih_key))) { /* endian safe */ fsck_log ("verify_direntry: block %lu, item %H has entry \".\" " "pointing to (%K) instead of (%K)\n", bh->b_blocknr, ih, &(deh[i].deh_dir_id), &(ih->ih_key)); deh[i].deh_dir_id = ih->ih_key.k_dir_id; /* both LE */ deh[i].deh_objectid = ih->ih_key.k_objectid; /* both LE */ mark_buffer_dirty (bh); } } else if (is_dot_dot (name, name_len)) { if (i != 1) fsck_log ("block %lu: item %d: \"..\" is %d-th entry\n", bh->b_blocknr, item_num, i); /* check and fix ".." */ if (deh_offset (deh + i) != DOT_DOT_OFFSET) set_deh_offset(&(deh[i]), DOT_DOT_OFFSET); } else { int min_length, max_length; /* check other name */ if (name_len == 0) { /* we do not know the length of name - we will try to find it */ min_length = 1; max_length = item + ih_item_len (ih) - name; } else /* we kow name length, so we will try only one name length */ min_length = max_length = name_len; for (j = min_length; j <= max_length; j ++) { hash_code = find_hash_in_use (name, j, GET_HASH_VALUE (deh_offset (deh + i)), rs_hash (fs->s_rs)); add_hash_hit (fs, hash_code); if (code2func (hash_code) != 0) { /* deh_offset matches to some hash of the name */ if (!name_len) { fsck_log ("pass0: block %lu, item %H: entry %d. found a name \"%.*s\" " "matching to deh_offset %u. FIXME: should set deh_location " "of previous entry (not ready)\n", bh->b_blocknr, ih, i, j, name, deh_offset (deh + i)); /* FIXME: if next byte is 0 we think that the name is aligned to 8 byte boundary */ if (i) { set_deh_location( &(deh[i - 1]), deh_location (deh + i) + ((name[j] || SB_VERSION (fs) == REISERFS_VERSION_1) ? j : ROUND_UP (j))); mark_de_good_location (deh + i - 1); mark_buffer_dirty (bh); } } break; } } if (j == max_length + 1) { /* deh_offset does not match to anything. it will be deleted for now, but maybe we could just fix a deh_offset if it is in ordeer */ mark_de_bad_offset (deh + i); } } } /* for */ #if 0 /* find entries names in which have mismatching deh_offset */ for (i = 0; i < ih_entry_count (ih); i ++) { if (de_bad (deh + i)) /* bad location */ continue; name = name_in_entry (deh + i, i); /* we found a name, but we not always we can get its length as it depends on deh_location of previous entry */ name_len = try_to_get_name_length (ih, deh + i, i); if (i == 0 && is_dot (name, name_len)) { /* check and fix "." */ if (deh_offset (deh + i) != DOT_OFFSET) { deh[i].deh_offset = cpu_to_le32 (DOT_OFFSET); } /* "." must point to the directory it is in */ if (not_of_one_file (&(deh[i].deh_dir_id), &(ih->ih_key))) { fsck_log ("verify_direntry: block %lu, item %H has entry \".\" " "pointing to (%K) instead of (%K)\n", bh->b_blocknr, ih, &(deh[i].deh_dir_id), &(ih->ih_key)); deh[i].deh_dir_id = ih->ih_key.k_dir_id; /* both 32 bit LE */ deh[i].deh_objectid = ih->ih_key.k_objectid; /* both 32 bit LE */ mark_buffer_dirty (bh); } } else if (i == 1 && is_dot_dot (name, name_len)) { /* check and fix ".." */ if (deh_offset (deh + i) != DOT_DOT_OFFSET) deh[i].deh_offset = cpu_to_le32 (DOT_DOT_OFFSET); } else { int min_length, max_length; /* check other name */ if (name_len == 0) { /* we do not know the length of name - we will try to find it */ min_length = 1; max_length = item + ih_item_len (ih) - name; } else /* we kow name length, so we will try only one name length */ min_length = max_length = name_len; for (j = min_length; j <= max_length; j ++) { hash_code = find_hash_in_use (name, j, GET_HASH_VALUE (deh_offset (deh + i)), rs_hash (fs->s_rs)); add_hash_hit (fs, hash_code); if (code2func (hash_code) != 0) { /* deh_offset matches to some hash of the name */ if (!name_len) { fsck_log ("pass0: block %lu, item %H: entry %d. found a name \"%.*s\" " "matching to deh_offset %u. FIXME: should set deh_location " "of previous entry (not ready)\n", bh->b_blocknr, ih, i, j, name, deh_offset (deh + i)); /* FIXME: if next byte is 0 we think that the name is aligned to 8 byte boundary */ deh[i - 1].deh_location = cpu_to_le16 (deh_location (deh + i) + ((name[j] || SB_VERSION (fs) == REISERFS_VERSION_1) ? j : ROUND_UP (j))); } break; } } if (j == max_length + 1) { /* deh_offset does not match to anything. it will be deleted for now, but maybe we could just fix a deh_offset if it is in ordeer */ mark_de_bad_offset (deh + i); } } } #endif #ifdef DEBUG_VERIFY_DENTRY printf ("entries with mismatching deh_offsets: "); for (i = 0; i < ih_entry_count (ih); i ++) { if (de_bad_offset (deh + i)) printf ("%d ", i); } printf ("\n"); #endif /* DEBUG_VERIFY_DENTRY */ /* correct deh_locations such that code cutting entries will not get screwed up */ { int prev_loc; int loc_fixed; prev_loc = ih_item_len (ih); for (i = 0; i < ih_entry_count (ih); i ++) { loc_fixed = 0; if (de_bad_location (deh + i)) { set_deh_location(&(deh[i]), prev_loc/* - 1*/); mark_buffer_dirty (bh); loc_fixed = 1; } else { if (deh_location (deh + i) >= prev_loc) { set_deh_location(&(deh[i]), prev_loc/* - 1*/); mark_buffer_dirty (bh); loc_fixed = 1; } } prev_loc = deh_location (deh + i); if (i == ih_entry_count (ih) - 1) { /* last entry starts right after an array of dir entry headers */ if (!de_bad (deh + i) && deh_location (deh + i) != (DEH_SIZE * ih_entry_count (ih))) { /* free space in the directory item */ fsck_log ("verify_direntry: block %lu, item %H has free pace\n", bh->b_blocknr, ih); cut_entry (fs, bh, item_num, ih_entry_count (ih), 0); } if (deh_location (deh + i) != (DEH_SIZE * ih_entry_count (ih))) { set_deh_location(&(deh[i]), DEH_SIZE * ih_entry_count (ih)); loc_fixed = 1; mark_buffer_dirty (bh); } } #ifdef DEBUG_VERIFY_DENTRY if (loc_fixed) direntries [i] = 1; #endif } /* for */ #ifdef DEBUG_VERIFY_DENTRY printf ("entries with fixed deh_locations: "); for (i = 0; i < ih_entry_count (ih); i ++) { if (direntries [i]) printf ("%d ", i); } printf ("\n"); #endif /* DEBUG_VERIFY_DENTRY */ } #ifdef DEBUG_VERIFY_DENTRY printf (" N location name\n"); for (i = 0; i < ih_entry_count (ih); i ++) { if (de_bad (deh + i) || (i && de_bad (deh + i - 1)) || /* previous entry marked bad */ (i < ih_entry_count (ih) - 1 && de_bad (deh + i + 1))) { /* next ntry is marked bad */ /* print only entries to be deleted and their nearest neighbors */ printf ("%3d: %8d ", i, deh_location (deh + i)); if (de_bad (deh + i)) printf ("will be deleted\n"); else printf ("\"%.*s\"\n", name_length (ih, deh + i, i), name_in_entry (deh + i, i)); } } #endif bad = 0; tmp = *ih; /* delete entries which are marked bad */ for (i = 0; i < ih_entry_count (ih); i ++) { deh = B_I_DEH (bh, ih) + i; if (de_bad (deh)) { bad ++; if (ih_entry_count (ih) == 1) { delete_item (fs, bh, item_num); break; } else { cut_entry (fs, bh, item_num, i, 1); } i --; } } if (bad == ih_entry_count (&tmp)) { fsck_log ("pass0: block %lu, item %H - all entries were deleted\n", bh->b_blocknr, &tmp); return 0; } deh = B_I_DEH (bh, ih); if (get_offset (&ih->ih_key) != deh_offset (deh)) { fsck_log ("verify_direntry: block %lu, item %H: k_offset and deh_offset %u mismatched\n", bh->b_blocknr, ih, deh_offset (deh)); set_offset (KEY_FORMAT_1, &ih->ih_key, deh_offset (deh)); mark_buffer_dirty (bh); } if (bad) fsck_log ("pass0: block %lu, item %H: %d entries were deleted of \n", bh->b_blocknr, &tmp, bad); return 0; #if 0 /* FIXME: temporary */ if (bad_locations > ih_entry_count (ih) / 2) { fsck_log ("pass0: block %u: item %d (%H) had too bad directory - deleted\n", bh->b_blocknr, item_num, ih); delete_item (fs, bh, item_num); return 0; } if (!dirty) return 0; /* something is broken */ fsck_log ("pass0: block %lu: %d-th item (%H) has %d bad entries..", bh->b_blocknr, item_num, ih, dirty); if (get_offset (&ih->ih_key) == DOT_OFFSET) { /* first item of directory - make sure that "." and ".." are in place */ if (deh_offset (deh) != DOT_OFFSET || name_in_entry (deh, 0)[0] != '.') { set_deh_offset(deh, DOT_OFFSET); name_in_entry (deh, 0)[0] = '.'; } if (deh_offset (deh + 1) != DOT_DOT_OFFSET || name_in_entry (deh + 1, 1)[0] != '.' || name_in_entry (deh + 1, 1)[1] != '.') { set_deh_offset((deh + 1), DOT_DOT_OFFSET); name_in_entry (deh + 1, 1)[0] = '.'; name_in_entry (deh + 1, 1)[1] = '.'; } } end = item + ih_item_len (ih); deh += ih_entry_count (ih); entries = (char *)deh; total_entry_len = ih_item_len (ih) - DEH_SIZE * ih_entry_count (ih); i = ih_entry_count (ih); bad_entries = 0; do { i --; deh --; name_len = prob_name (fs, &entries, total_entry_len, deh_offset (deh)); if (!name_len) { if (!bad_entries) { set_deh_location(deh, entries - item); } else { set_deh_location(deh, deh_location((deh + 1)) + 1 ); } bad_entries ++; /*fsck_log ("verify_directory_item: entry %d: in string \'%s\' there is no substring matching hash %ld\n", i, bad_name (entries, total_entry_len), masked_offset);*/ mark_de_bad (deh); continue; } bad_entries = 0; /*fsck_log ("verify_directory_item: entry %d: found \"%s\" name matching hash %ld\n", i, bad_name (entries, name_len), masked_offset);*/ /* 'entries' points now to the name which match given offset - so, set deh_location */ set_deh_location(deh, entries - item); deh->deh_state = 0; mark_de_visible (deh); entries += name_len; total_entry_len = end - entries; /* skip padding zeros */ while (!*entries) { entries ++; total_entry_len --; } /* 'entries' points now at the place where next (previous) entry should start */ } while ((char *)deh != item); /* fixme: this will not work if all entries are to be deleted */ for (i = 0; i < ih_entry_count (ih); i ++, deh ++) { deh = (struct reiserfs_de_head *)B_I_PITEM (bh, ih) + i; if (de_bad (deh)) { if (ih_entry_count (ih) == 1) { delete_item (fs, bh, i); break; } else { cut_entry (fs, bh, item_num, i); } i --; } /* fsck_log ("verify_directory_item: %d-th entry is to be deleted: " "\"%s\" does not match to hash %lu\n", i, bad_name (name_in_entry (deh, i), name_length (ih, deh, i)), deh_offset (deh)); */ } fsck_log ("%d entries were deleted\n", entry_count - ih_entry_count (ih)); mark_buffer_dirty (bh); return 0; #endif }
void jrb_delete_node(JRB n) { JRB s, p, gp; char ir; if (isint(n)) { fprintf(stderr, "Cannot delete an internal node: 0x%p\n", (void *)n); exit(1); } if (ishead(n)) { fprintf(stderr, "Cannot delete the head of an jrb_tree: 0x%p\n", (void *)n); exit(1); } delete_item(n); /* Delete it from the list */ p = n->parent; /* The only node */ if (isroot(n)) { p->parent = p; free(n); return; } s = sibling(n); /* The only node after deletion */ if (isroot(p)) { s->parent = p->parent; s->parent->parent = s; setroot(s); free(p); free(n); return; } gp = p->parent; /* Set parent to sibling */ s->parent = gp; if (isleft(p)) { gp->flink = s; setleft(s); } else { gp->blink = s; setright(s); } ir = isred(p); free(p); free(n); if (isext(s)) { /* Update proper rext and lext values */ p = lprev(s); if (!ishead(p)) setrext(p, s); p = rprev(s); if (!ishead(p)) setlext(p, s); } else if (isblack(s)) { fprintf(stderr, "DELETION PROB -- sib is black, internal\n"); exit(1); } else { p = lprev(s); if (!ishead(p)) setrext(p, s->flink); p = rprev(s); if (!ishead(p)) setlext(p, s->blink); setblack(s); return; } if (ir) return; /* Recolor */ n = s; p = n->parent; s = sibling(n); while(isblack(p) && isblack(s) && isint(s) && isblack(s->flink) && isblack(s->blink)) { setred(s); n = p; if (isroot(n)) return; p = n->parent; s = sibling(n); } if (isblack(p) && isred(s)) { /* Rotation 2.3b */ single_rotate(p, isright(n)); setred(p); setblack(s); s = sibling(n); } { JRB x, z; char il; if (isext(s)) { fprintf(stderr, "DELETION ERROR: sibling not internal\n"); exit(1); } il = isleft(n); x = il ? s->flink : s->blink ; z = sibling(x); if (isred(z)) { /* Rotation 2.3f */ single_rotate(p, !il); setblack(z); if (isred(p)) setred(s); else setblack(s); setblack(p); } else if (isblack(x)) { /* Recoloring only (2.3c) */ if (isred(s) || isblack(p)) { fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n"); exit(1); } setblack(p); setred(s); return; } else if (isred(p)) { /* 2.3d */ single_rotate(s, il); single_rotate(p, !il); setblack(x); setred(s); return; } else { /* 2.3e */ single_rotate(s, il); single_rotate(p, !il); setblack(x); return; } } }
/* Receive a command from the client and execute it. */ static void handle_command (const int client_id) { int cmd; int err = 0; struct client *cli = &clients[client_id]; if (!get_int(cli->socket, &cmd)) { logit ("Failed to get command from the client"); close (cli->socket); del_client (cli); return; } switch (cmd) { case CMD_QUIT: logit ("Exit request from the client"); close (cli->socket); del_client (cli); server_quit = 1; break; case CMD_LIST_CLEAR: logit ("Clearing the list"); audio_plist_clear (); break; case CMD_LIST_ADD: if (!req_list_add(cli)) err = 1; break; case CMD_PLAY: if (!req_play(cli)) err = 1; break; case CMD_DISCONNECT: logit ("Client disconnected"); close (cli->socket); del_client (cli); break; case CMD_PAUSE: audio_pause (); break; case CMD_UNPAUSE: audio_unpause (); break; case CMD_STOP: audio_stop (); break; case CMD_GET_CTIME: if (!send_data_int(cli, MAX(0, audio_get_time()))) err = 1; break; case CMD_SEEK: if (!req_seek(cli)) err = 1; break; case CMD_JUMP_TO: if (!req_jump_to(cli)) err = 1; break; case CMD_GET_SNAME: if (!send_sname(cli)) err = 1; break; case CMD_GET_STATE: if (!send_data_int(cli, audio_get_state())) err = 1; break; case CMD_GET_BITRATE: if (!send_data_int(cli, sound_info.bitrate)) err = 1; break; case CMD_GET_AVG_BITRATE: if (!send_data_int(cli, sound_info.avg_bitrate)) err = 1; break; case CMD_GET_RATE: if (!send_data_int(cli, sound_info.rate)) err = 1; break; case CMD_GET_CHANNELS: if (!send_data_int(cli, sound_info.channels)) err = 1; break; case CMD_NEXT: audio_next (); break; case CMD_PREV: audio_prev (); break; case CMD_PING: if (!send_int(cli->socket, EV_PONG)) err = 1; break; case CMD_GET_OPTION: if (!send_option(cli)) err = 1; break; case CMD_SET_OPTION: if (!get_set_option(cli)) err = 1; break; case CMD_GET_MIXER: if (!send_data_int(cli, audio_get_mixer())) err = 1; break; case CMD_SET_MIXER: if (!set_mixer(cli)) err = 1; break; case CMD_DELETE: if (!delete_item(cli)) err = 1; break; case CMD_SEND_PLIST_EVENTS: cli->wants_plist_events = 1; logit ("Request for events"); break; case CMD_GET_PLIST: if (!get_client_plist(cli)) err = 1; break; case CMD_SEND_PLIST: if (!req_send_plist(cli)) err = 1; break; case CMD_CAN_SEND_PLIST: cli->can_send_plist = 1; break; case CMD_CLI_PLIST_ADD: case CMD_CLI_PLIST_DEL: case CMD_CLI_PLIST_CLEAR: case CMD_CLI_PLIST_MOVE: if (!plist_sync_cmd(cli, cmd)) err = 1; break; case CMD_LOCK: if (!client_lock(cli)) err = 1; break; case CMD_UNLOCK: if (!client_unlock(cli)) err = 1; break; case CMD_GET_SERIAL: if (!send_serial(cli)) err = 1; break; case CMD_PLIST_GET_SERIAL: if (!req_plist_get_serial(cli)) err = 1; break; case CMD_PLIST_SET_SERIAL: if (!req_plist_set_serial(cli)) err = 1; break; case CMD_GET_TAGS: if (!req_get_tags(cli)) err = 1; break; case CMD_TOGGLE_MIXER_CHANNEL: req_toggle_mixer_channel (); break; case CMD_TOGGLE_SOFTMIXER: req_toggle_softmixer (); break; case CMD_GET_MIXER_CHANNEL_NAME: if (!req_get_mixer_channel_name(cli)) err = 1; break; case CMD_GET_FILE_TAGS: if (!get_file_tags(client_id)) err = 1; break; case CMD_ABORT_TAGS_REQUESTS: if (!abort_tags_requests(client_id)) err = 1; break; case CMD_LIST_MOVE: if (!req_list_move(cli)) err = 1; break; case CMD_TOGGLE_EQUALIZER: req_toggle_equalizer(); break; case CMD_EQUALIZER_REFRESH: req_equalizer_refresh(); break; case CMD_EQUALIZER_PREV: req_equalizer_prev(); break; case CMD_EQUALIZER_NEXT: req_equalizer_next(); break; case CMD_TOGGLE_MAKE_MONO: req_toggle_make_mono(); break; case CMD_QUEUE_ADD: if (!req_queue_add(cli)) err = 1; break; case CMD_QUEUE_DEL: if (!req_queue_del(cli)) err = 1; break; case CMD_QUEUE_CLEAR: logit ("Clearing the queue"); audio_queue_clear (); add_event_all (EV_QUEUE_CLEAR, NULL); break; case CMD_QUEUE_MOVE: if (!req_queue_move(cli)) err = 1; break; case CMD_GET_QUEUE: if (!req_send_queue(cli)) err = 1; break; default: logit ("Bad command (0x%x) from the client", cmd); err = 1; } if (err) { logit ("Closing client connection due to error"); close (cli->socket); del_client (cli); } }
void command_paste(doc *d, char **args, int nargs) { cursor precursor = d->c; doc n; int change = 0; int i, j, nlines, ii, jj; if (nargs != 1) return paste_usage(); n = to_doc(args[0]); lock(d); if (n.size != 1) goto error; nlines = d->l[d->c.line].n; /* take into account subline of cursor to paste */ for (i = 0, ii = 0; i < n.l[0].size; i++, ii++) { item *s = &n.l[0].i[i], *dst; new_item(&d->l[d->c.line], d->c.item+ii); dst = &d->l[d->c.line].i[d->c.item+ii]; for (j = 0, jj = 0; j < s->size; j++, jj++) { switch (s->i[j].t) { case CLEF: if (s->i[j].clef.s + d->c.subline >= nlines) {jj--;continue;} new_vertical_item(dst, jj, CLEF, s->i[j].clef.t, s->i[j].clef.s + d->c.subline, s->i[j].clef.p); break; case ARMATURE:if(s->i[j].armature.s+d->c.subline>=nlines){jj--;continue;} new_vertical_item(dst, jj, ARMATURE, s->i[j].armature.t, s->i[j].armature.s + d->c.subline, s->i[j].armature.p); break; case NOTE: if (s->i[j].note.s + d->c.subline >= nlines){jj--;continue;} new_vertical_item(dst, jj, NOTE, s->i[j].note.duration, s->i[j].note.dots, s->i[j].note.alteration, s->i[j].note.s + d->c.subline, s->i[j].note.p, s->i[j].note.st, s->i[j].note.l, s->i[j].note.m, s->i[j].note.o); break; case SILENCE: if(s->i[j].silence.s+d->c.subline>=nlines){jj--;continue;} new_vertical_item(dst, jj, SILENCE, s->i[j].silence.duration, s->i[j].silence.dots, s->i[j].silence.s + d->c.subline, s->i[j].silence.p); break; case BAR: /* always works */ new_vertical_item(dst, jj, BAR); break; } } if (dst->size == 0) { delete_item(&d->l[d->c.line], d->c.item+ii); ii--; continue; } for (j = 0; j < s->tsize; j++) new_text(dst, s->t[j].t, s->t[j].dx, s->t[j].dy); change = 1; } if (change == 0) goto error; d->dirty = 1; unlock(d); resize(d); new_history(d, precursor); delete_doc(&n); return; error: unlock(d); printf("cannot paste '%s'\n", args[0]); delete_doc(&n); }
/* FIXME: we can improve fixing of broken keys: we can ssfe direct items which go after stat data and have broken keys */ static void pass0_correct_leaf (reiserfs_filsys_t fs, struct buffer_head * bh) { int i, j; struct item_head * ih; __u32 * ind_item; unsigned long unfm_ptr; int dirty = 0; start_again: ih = B_N_PITEM_HEAD (bh, 0); for (i = 0; i < node_item_number (bh); i ++, ih ++) { if (ih->ih_key.k_dir_id == 0 || ih->ih_key.k_objectid == 0) { /* sometimes stat datas get k_objectid==0 or k_dir_id==0 */ if (i == (node_item_number (bh) - 1)) { /* */ if (i == 0) { fsck_log ("block %lu: item %d: (%H) is alone in the block\n", bh->b_blocknr, i, ih); return; } /* delete last item */ delete_item (fs, bh, i - 1); return; } /* there is next item: if it is not stat data - take its k_dir_id and k_objectid. if key order will be still wrong - the changed item will be deleted */ if (!is_stat_data_ih (ih + 1)) { fsck_log ("block %lu: item %d: (%H) fixed to ", bh->b_blocknr, i, ih); ih->ih_key.k_dir_id = (ih + 1)->ih_key.k_dir_id; ih->ih_key.k_objectid = (ih + 1)->ih_key.k_objectid; set_offset (KEY_FORMAT_1, &ih->ih_key, 0); set_type (KEY_FORMAT_1, &ih->ih_key, TYPE_STAT_DATA); fsck_log ("(%H)\n", ih); dirty = 1; } else if (i == 0) { delete_item (fs, bh, i); goto start_again; } } /* this recovers corruptions like the below: 1774 1732 0 0 116262638 1732 1 3 1774 1736 0 0 */ if (i && is_stat_data_ih (ih - 1) && !is_stat_data_ih (ih)) { if (ih->ih_key.k_objectid != (ih - 1)->ih_key.k_objectid || ih->ih_key.k_dir_id != (ih - 1)->ih_key.k_dir_id || get_offset (&ih->ih_key) != 1) { if (is_direntry_ih (ih)) { fsck_log ("block %lu: item %d: no \".\" entry found in " "the first item of a directory\n", bh->b_blocknr, i); } else { fsck_log ("block %lu: item %d: (%H) fixed to ", bh->b_blocknr, i, ih); ih->ih_key.k_dir_id = (ih - 1)->ih_key.k_dir_id; ih->ih_key.k_objectid = (ih - 1)->ih_key.k_objectid; if (ih_item_len (ih - 1) == SD_SIZE) { /* stat data is new, therefore this item is new too */ set_offset (KEY_FORMAT_2, &(ih->ih_key), 1); if (ih_entry_count (ih) != 0xffff) set_type (KEY_FORMAT_2, &(ih->ih_key), TYPE_INDIRECT); else set_type (KEY_FORMAT_2, &(ih->ih_key), TYPE_DIRECT); set_ih_key_format (ih, KEY_FORMAT_2); } else { /* stat data is old, therefore this item is old too */ set_offset (KEY_FORMAT_1, &(ih->ih_key), 1); if (ih_entry_count (ih) != 0xffff) set_type (KEY_FORMAT_1, &(ih->ih_key), TYPE_INDIRECT); else set_type (KEY_FORMAT_1, &(ih->ih_key), TYPE_DIRECT); set_ih_key_format (ih, KEY_FORMAT_1); } fsck_log ("%H\n", ih); dirty = 1; } } } /* FIXME: corruptions like: 56702 66802 1 2 56702 65536 0 0 56702 66803 1 2 do not get recovered (both last items will be deleted) */ /* delete item if it is not in correct order of object items */ if (i && not_of_one_file (&ih->ih_key, &(ih - 1)->ih_key) && !is_stat_data_ih (ih)) { fsck_log ("block %lu: item %d: %H follows non stat item %H - deleted\n", bh->b_blocknr, i, ih, ih - 1); delete_item (fs, bh, i); goto start_again; } if (i && comp_keys (&(ih - 1)->ih_key, &ih->ih_key) != -1) { /* previous item has key not smaller than the key of currect item */ if (is_stat_data_ih (ih - 1) && !is_stat_data_ih (ih)) { /* fix key of stat data such as if it was stat data of that item */ fsck_log ("pass0: block %lu: %d-th item %k is out of order, made a stat data of %d-th (%k)\n", bh->b_blocknr, i - 1, &(ih - 1)->ih_key, i, &ih->ih_key); (ih - 1)->ih_key.k_dir_id = ih->ih_key.k_dir_id; (ih - 1)->ih_key.k_objectid = ih->ih_key.k_objectid; set_offset (KEY_FORMAT_1, &(ih - 1)->ih_key, 0); set_type (KEY_FORMAT_1, &(ih - 1)->ih_key, TYPE_STAT_DATA); dirty = 1; } else { /* ok, we have to delete one of these two - decide which one */ int retval; /* something will be deleted */ dirty = 1; retval = upper_correct (bh, ih - 1, i - 1); switch (retval) { case 0: /* delete upper item */ fsck_log ("pass0: block %lu: %d-th (upper) item (%k) is out of order, deleted\n", bh->b_blocknr, i - 1, &(ih - 1)->ih_key); delete_item (fs, bh, i - 1); goto start_again; case 1: /* delete lower item */ fsck_log ("pass0: block %lu: %d-th (lower) item (%k) is out of order, deleted\n", bh->b_blocknr, i, &ih->ih_key); delete_item (fs, bh, i); goto start_again; default: /* upper item was the first item of a node */ } retval = lower_correct (bh, ih, i); switch (retval) { case 0: /* delete lower item */ fsck_log ("pass0: block %lu: %d-th (lower) item (%k) is out of order, deleted\n", bh->b_blocknr, i, &ih->ih_key); delete_item (fs, bh, i); goto start_again; case 1: /* delete upper item */ fsck_log ("pass0: block %lu: %d-th (upper) item (%k) is out of order, deleted\n", bh->b_blocknr, i - 1, &(ih - 1)->ih_key); delete_item (fs, bh, i - 1); goto start_again; default: /* there wer only two items in a node, so we could not decide what to delete, go and ask user */ } fsck_log ("pass0: which of these items looks better (other will be deleted)?\n" "%H\n%H\n", ih - 1, ih); if (fsck_user_confirmed (fs, "1 or 2?", "1\n", 1)) delete_item (fs, bh, i - 1); else delete_item (fs, bh, i); goto start_again; } } if (is_stat_data_ih (ih) && (ih_item_len (ih) != SD_SIZE && ih_item_len (ih) != SD_V1_SIZE)) { fsck_log ("pass0: block %lu, stat data of wrong length %H - deleted\n", bh, ih); delete_item (fs, bh, i); goto start_again; } dirty += correct_key_format (ih); if (is_stat_data_ih (ih)) { ;/*correct_stat_data (fs, bh, i);*/ } if (is_direntry_ih (ih)) { verify_directory_item (fs, bh, i); continue; } if (!is_indirect_ih (ih)) continue; ind_item = (__u32 *)B_I_PITEM (bh, ih); for (j = 0; j < I_UNFM_NUM (ih); j ++) { unfm_ptr = le32_to_cpu (ind_item [j]); if (!unfm_ptr) continue; if (fsck_mode (fs) == FSCK_ZERO_FILES) { /* FIXME: this is temporary mode of fsck */ ind_item [j] = 0; reiserfs_bitmap_clear_bit (fsck_new_bitmap(fs), unfm_ptr); tmp_zeroed ++; dirty = 1; continue; } if (not_data_block (fs, unfm_ptr) || /* journal area or bitmap or super block */ unfm_ptr >= SB_BLOCK_COUNT (fs)) {/* garbage in pointer */ stats (fs)->wrong_pointers ++; /* fsck_log ("pass0: %d-th pointer (%lu) in item %k (leaf block %lu) is wrong\n", j, unfm_ptr, &ih->ih_key, bh->b_blocknr); */ ind_item [j] = 0; dirty = 1; continue; } #if 0 if (!was_block_used (unfm_ptr)) { /* this will get to a pool of allocable blocks */ ind_item [j] = 0; dirty = 1; stat_wrong_pointer_found (fs); continue; } #endif /* mark block in bitmaps of unformatted nodes */ register_unfm (unfm_ptr); } } /* mark all objectids in use */ ih = B_N_PITEM_HEAD (bh, 0); for (i = 0; i < node_item_number (bh); i ++, ih ++) { mark_objectid_really_used (proper_id_map (fs), le32_to_cpu (ih->ih_key.k_dir_id)); mark_objectid_really_used (proper_id_map (fs), le32_to_cpu (ih->ih_key.k_objectid)); } if (node_item_number (bh) < 1) { /* pass 1 will skip this */ stats(fs)->all_contents_removed ++; fsck_log ("pass0: block %lu got all items deleted\n", bh->b_blocknr); } else { /* pass1 will use this bitmap */ pass0_mark_leaf (bh->b_blocknr); } if (dirty) { stats(fs)->leaves_corrected ++; mark_buffer_dirty (bh); } } static int is_bad_sd (struct item_head * ih, char * item) { struct stat_data * sd = (struct stat_data *)item; if (le32_to_cpu(ih->ih_key.u.k_offset_v1.k_offset) || le32_to_cpu(ih->ih_key.u.k_offset_v1.k_uniqueness)) { reiserfs_warning (stderr, "Bad SD? %H\n", ih); return 1; } if (ih_item_len (ih) == SD_V1_SIZE) { /* looks like old stat data */ if (ih_key_format (ih) != KEY_FORMAT_1) fsck_log ("item %H has wrong format\n", ih); return 0; } if (!S_ISDIR (sd_v2_mode(sd)) && !S_ISREG(sd_v2_mode(sd)) && !S_ISCHR (sd_v2_mode(sd)) && !S_ISBLK(sd_v2_mode(sd)) && !S_ISLNK (sd_v2_mode(sd)) && !S_ISFIFO(sd_v2_mode(sd)) && !S_ISSOCK(sd_v2_mode(sd))) { /*fsck_log ("file %k unexpected mode encountered 0%o\n", &ih->ih_key, sd_v2_mode(sd))*/; } return 0; } int is_bad_directory (struct item_head * ih, char * item, int dev, int blocksize) { int i; char * name; int namelen, entrylen; struct reiserfs_de_head * deh = (struct reiserfs_de_head *)item; __u32 prev_offset = 0; __u16 prev_location = ih_item_len (ih); int min_entry_size = 1;/* we have no way to understand whether the filesystem were created in 3.6 format or converted to it. So, we assume that minimal name length is 1 */ if (ih_item_len (ih) / (DEH_SIZE + min_entry_size) < ih_entry_count (ih)) /* entry count is too big */ return 1; for (i = 0; i < ih_entry_count (ih); i ++, deh ++) { entrylen = entry_length(ih, deh, i); if (entrylen > REISERFS_MAX_NAME_LEN (blocksize)) { return 1; } if (deh_offset (deh) <= prev_offset) { return 1; } prev_offset = deh_offset (deh); if (deh_location(deh) + entrylen != prev_location) { return 1; } prev_location = deh_location (deh); namelen = name_length (ih, deh, i); name = name_in_entry (deh, i); if (!is_properly_hashed (fs, name, namelen, deh_offset (deh))) { return 1; } } return 0; } /* change incorrect block adresses by 0. Do not consider such item as incorrect */ static int is_bad_indirect (struct item_head * ih, char * item, int dev, int blocksize) { int i; int bad = 0; int blocks; if (ih_item_len(ih) % UNFM_P_SIZE) { fsck_log ("is_bad_indirect: indirect item of %H of invalid length\n", ih); return 1; } blocks = SB_BLOCK_COUNT (fs); for (i = 0; i < I_UNFM_NUM (ih); i ++) { __u32 * ind = (__u32 *)item; if (le32_to_cpu (ind[i]) >= blocks) { bad ++; fsck_log ("is_bad_indirect: %d-th pointer of item %H looks bad (%lu)\n", i, ih, le32_to_cpu (ind [i])); continue; } } return bad; }
/* The directory is about to be deleted: if DEL_RECURSE is given, delete all * its contents, otherwise just checks for content. Returns DR_SUCCESS or * DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The * buffer is used for recursion, but returned unchanged.) */ static enum delret delete_dir_contents(char *fname, uint16 flags) { struct file_list *dirlist; enum delret ret; unsigned remainder; void *save_filters; int j, dlen; char *p; if (DEBUG_GTE(DEL, 3)) { rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n", fname, flags); } dlen = strlen(fname); save_filters = push_local_filters(fname, dlen); non_perishable_cnt = 0; dirlist = get_dirlist(fname, dlen, 0); ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS; if (!dirlist->used) goto done; if (!(flags & DEL_RECURSE)) { ret = DR_NOT_EMPTY; goto done; } p = fname + dlen; if (dlen != 1 || *fname != '/') *p++ = '/'; remainder = MAXPATHLEN - (p - fname); /* We do our own recursion, so make delete_item() non-recursive. */ flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE)) | DEL_DIR_IS_EMPTY; for (j = dirlist->used; j--; ) { struct file_struct *fp = dirlist->files[j]; if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) { if (DEBUG_GTE(DEL, 1)) { rprintf(FINFO, "mount point, %s, pins parent directory\n", f_name(fp, NULL)); } ret = DR_NOT_EMPTY; continue; } strlcpy(p, fp->basename, remainder); if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) do_chmod(fname, fp->mode | S_IWUSR); /* Save stack by recursing to ourself directly. */ if (S_ISDIR(fp->mode)) { if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) ret = DR_NOT_EMPTY; } if (delete_item(fname, fp->mode, flags) != DR_SUCCESS) ret = DR_NOT_EMPTY; } fname[dlen] = '\0'; done: flist_free(dirlist); pop_local_filters(save_filters); if (ret == DR_NOT_EMPTY) { rprintf(FINFO, "cannot delete non-empty directory: %s\n", fname); } return ret; }
int btree_delete(btree_t bt, const void *key) { const struct btree_def *def = bt->def; const int halfsize = def->branches / 2; struct btree_page *path[MAX_HEIGHT] = {0}; int slot[MAX_HEIGHT] = {0}; int h; check_btree(bt); /* Trace a path to the item to be deleted */ if (!key) { if (bt->slot[0] < 0) return 1; memcpy(path, bt->path, sizeof(path)); memcpy(slot, bt->slot, sizeof(slot)); } else if (!trace_path(bt, key, path, slot)) { return 1; } /* Select the next item if we're deleting at the cursor */ if (bt->slot[0] == slot[0] && bt->path[0] == path[0]) cursor_next(bt); /* Delete from the leaf node. If it's still full enough, then we don't * need to do anything else. */ delete_item(path[0], slot[0]); if (path[0]->num_children >= halfsize) return 0; /* Trace back up the tree, fixing underfull nodes. If we can fix by * borrowing, do it and we're done. Otherwise, we need to fix by * merging, which may result in another underfull node, and we need * to continue. */ for (h = 1; h <= bt->root->height; h++) { struct btree_page *p = path[h]; struct btree_page *c = path[h - 1]; int s = slot[h]; if (s > 0) { /* Borrow/merge from lower page */ struct btree_page *d = *PAGE_PTR(p, s - 1); if (d->num_children > halfsize) { move_item(d, d->num_children - 1, c, 0); memcpy(PAGE_KEY(p, s), PAGE_KEY(c, 0), def->key_size); return 0; } merge_pages(d, c); delete_item(p, s); free(c); } else { /* Borrow/merge from higher page */ struct btree_page *d = *PAGE_PTR(p, s + 1); if (d->num_children > halfsize) { move_item(d, 0, c, c->num_children); memcpy(PAGE_KEY(p, s + 1), PAGE_KEY(d, 0), def->key_size); return 0; } merge_pages(c, d); delete_item(p, s + 1); free(d); } if (p->num_children >= halfsize) return 0; } /* If the root contains only a single pointer to another page, * shrink the tree. This does not affect the cursor. */ if (bt->root->height && bt->root->num_children == 1) { struct btree_page *old = bt->root; bt->root = *PAGE_PTR(old, 0); free(old); } return 0; }
bool BlockchainTransactions::Delete(const std::string& id) { return delete_item(id); }