static int ntfs_ih_takeout(ntfs_index_context *icx, INDEX_HEADER *ih, INDEX_ENTRY *ie, INDEX_BLOCK *ib) { INDEX_ENTRY *ie_roam; int ret = STATUS_ERROR; ntfs_log_trace("Entering\n"); ie_roam = ntfs_ie_dup_novcn(ie); if (!ie_roam) return STATUS_ERROR; ntfs_ie_delete(ih, ie); if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) ntfs_inode_mark_dirty(icx->actx->ntfs_ino); else if (ntfs_ib_write(icx, ib)) goto out; ntfs_index_ctx_reinit(icx); ret = ntfs_ie_add(icx, ie_roam); out: free(ie_roam); return ret; }
/*static JPA*/ int ntfs_index_rm(ntfs_index_context *icx) { INDEX_HEADER *ih = NULL; int err, ret = STATUS_OK; ntfs_log_trace("Entering\n"); if (!icx || (!icx->ib && !icx->ir) || ntfs_ie_end(icx->entry)) { ntfs_log_error("Invalid arguments.\n"); errno = EINVAL; goto err_out; } if (icx->is_in_root) ih = &icx->ir->index; else ih = &icx->ib->index; if(NULL == ih) { errno = EINVAL; goto err_out; } if (icx->entry->ie_flags & INDEX_ENTRY_NODE) { ret = ntfs_index_rm_node(icx); } else if (icx->is_in_root || !ntfs_ih_one_entry(ih)) { ntfs_ie_delete(ih, icx->entry); if (icx->is_in_root) { err = ntfs_ir_truncate(icx, le32_to_cpu(ih->index_length)); if (err != STATUS_OK) goto err_out; } else if (ntfs_icx_ib_write(icx)) goto err_out; } else { if (ntfs_index_rm_leaf(icx)) goto err_out; } out: return ret; err_out: ret = STATUS_ERROR; goto out; }
static int ntfs_index_rm_node(ntfs_index_context *icx) { int entry_pos, pindex; VCN vcn; INDEX_BLOCK *ib = NULL; INDEX_ENTRY *ie_succ, *ie, *entry = icx->entry; INDEX_HEADER *ih; u32 new_size; int delta, ret = STATUS_ERROR; ntfs_log_trace("Entering\n"); if (!icx->ia_na) { icx->ia_na = ntfs_ia_open(icx, icx->ni); if (!icx->ia_na) return STATUS_ERROR; } ib = ntfs_malloc(icx->block_size); if (!ib) return STATUS_ERROR; ie_succ = ntfs_ie_get_next(icx->entry); entry_pos = icx->parent_pos[icx->pindex]++; pindex = icx->pindex; descend: vcn = ntfs_ie_get_vcn(ie_succ); if (ntfs_ib_read(icx, vcn, ib)) goto out; ie_succ = ntfs_ie_get_first(&ib->index); if (ntfs_icx_parent_inc(icx)) goto out; icx->parent_vcn[icx->pindex] = vcn; icx->parent_pos[icx->pindex] = 0; if ((ib->index.ih_flags & NODE_MASK) == INDEX_NODE) goto descend; if (ntfs_ih_zero_entry(&ib->index)) { errno = EIO; ntfs_log_perror("Empty index block"); goto out; } ie = ntfs_ie_dup(ie_succ); if (!ie) goto out; if (ntfs_ie_add_vcn(&ie)) goto out2; ntfs_ie_set_vcn(ie, ntfs_ie_get_vcn(icx->entry)); if (icx->is_in_root) ih = &icx->ir->index; else ih = &icx->ib->index; delta = le16_to_cpu(ie->length) - le16_to_cpu(icx->entry->length); new_size = le32_to_cpu(ih->index_length) + delta; if (delta > 0) { if (icx->is_in_root) { ret = ntfs_ir_make_space(icx, new_size); if (ret != STATUS_OK) goto out2; ih = &icx->ir->index; entry = ntfs_ie_get_by_pos(ih, entry_pos); } else if (new_size > le32_to_cpu(ih->allocated_size)) { icx->pindex = pindex; ret = ntfs_ib_split(icx, icx->ib); if (ret == STATUS_OK) ret = STATUS_KEEP_SEARCHING; goto out2; } } ntfs_ie_delete(ih, entry); ntfs_ie_insert(ih, ie, entry); if (icx->is_in_root) { if (ntfs_ir_truncate(icx, new_size)) goto out2; } else if (ntfs_icx_ib_write(icx)) goto out2; ntfs_ie_delete(&ib->index, ie_succ); if (ntfs_ih_zero_entry(&ib->index)) { if (ntfs_index_rm_leaf(icx)) goto out2; } else if (ntfs_ib_write(icx, ib)) goto out2; ret = STATUS_OK; out2: free(ie); out: free(ib); return ret; }