Fixed getting space for making an index non resident
In rare situations there is not enough space in the base inode entry to make an index non resident. The index has to be moved to an extent first. This happens when not using permissions and inserting a file whose name has 60 chars into a directory whose name has 184 chars. (bug reported by Vito Caputo)edge.strict_endians
parent
f219d2e07e
commit
058f850eb3
|
@ -1121,6 +1121,7 @@ static int ntfs_ir_reparent(ntfs_index_context *icx)
|
|||
INDEX_ENTRY *ie;
|
||||
INDEX_BLOCK *ib = NULL;
|
||||
VCN new_ib_vcn;
|
||||
int ix_root_size;
|
||||
int ret = STATUS_ERROR;
|
||||
|
||||
ntfs_log_trace("Entering\n");
|
||||
|
@ -1150,6 +1151,7 @@ static int ntfs_ir_reparent(ntfs_index_context *icx)
|
|||
if (ntfs_ib_write(icx, ib))
|
||||
goto clear_bmp;
|
||||
|
||||
retry :
|
||||
ir = ntfs_ir_lookup(icx->ni, icx->name, icx->name_len, &ctx);
|
||||
if (!ir)
|
||||
goto clear_bmp;
|
||||
|
@ -1164,12 +1166,32 @@ static int ntfs_ir_reparent(ntfs_index_context *icx)
|
|||
ir->index.index_length = cpu_to_le32(le32_to_cpu(ir->index.entries_offset)
|
||||
+ le16_to_cpu(ie->length));
|
||||
ir->index.allocated_size = ir->index.index_length;
|
||||
|
||||
ix_root_size = sizeof(INDEX_ROOT) - sizeof(INDEX_HEADER)
|
||||
+ le32_to_cpu(ir->index.allocated_size);
|
||||
if (ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr,
|
||||
sizeof(INDEX_ROOT) - sizeof(INDEX_HEADER) +
|
||||
le32_to_cpu(ir->index.allocated_size)))
|
||||
ix_root_size)) {
|
||||
/*
|
||||
* When there is no space to build a non-resident
|
||||
* index, we may have to move the root to an extent
|
||||
*/
|
||||
if ((errno == ENOSPC)
|
||||
&& !ctx->al_entry
|
||||
&& !ntfs_inode_add_attrlist(icx->ni)) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
ctx = (ntfs_attr_search_ctx*)NULL;
|
||||
ir = ntfs_ir_lookup(icx->ni, icx->name, icx->name_len,
|
||||
&ctx);
|
||||
if (ir
|
||||
&& !ntfs_attr_record_move_away(ctx, ix_root_size
|
||||
- le32_to_cpu(ctx->attr->value_length))) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
ctx = (ntfs_attr_search_ctx*)NULL;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
/* FIXME: revert index root */
|
||||
goto clear_bmp;
|
||||
}
|
||||
/*
|
||||
* FIXME: do it earlier if we have enough space in IR (should always),
|
||||
* so in error case we wouldn't lose the IB.
|
||||
|
|
Loading…
Reference in New Issue