Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/ntfstools
In directory usw-pr-cvs1:/tmp/cvs-serv1263/ntfstools
Modified Files:
mkntfs.c
Log Message:
And some more mkntfs + some updates to layout.h concerning directories and
alignment requirements.
Index: mkntfs.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/mkntfs.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -U2 -r1.12 -r1.13
--- mkntfs.c 2001/06/05 23:45:47 1.12
+++ mkntfs.c 2001/06/06 22:55:49 1.13
@@ -86,4 +86,6 @@
run_list *rl = NULL, *rl_mft = NULL, *rl_mftmirr = NULL, *rl_logfile = NULL;
run_list *rl_boot = NULL, *rl_bad = NULL;
+INDEX_ALLOCATION *index = NULL;
+unsigned int index_size;
struct {
@@ -1891,5 +1893,6 @@
int upgrade_to_large_index(MFT_RECORD *m, const char *name,
__u32 name_len, const IGNORE_CASE_BOOL ic,
- const uchar_t *upcase, const __u32 upcase_len)
+ const uchar_t *upcase, const __u32 upcase_len,
+ INDEX_ALLOCATION **index, __u32 **index_size)
{
attr_search_context ctx;
@@ -2020,14 +2023,96 @@
__post_read_mst_fixup((NTFS_RECORD*)ia_val, index_block_size);
// Revert index root from index allocation.
+ free(ia_val);
+ return err;
}
- free(ia_val);
- return err;
+ *index = ia_val;
+ *index_size = index_block_size;
+ return 0;
}
-/* Return 0 on success or -errno on error. */
-int insert_file_link_in_dir(MFT_RECORD *parent_dir, FILE_NAME *file_name,
- __u32 file_name_size)
+/*
+ * Create space of @size bytes at position @pos inside the index block @index.
+ *
+ * Return 0 on success or -errno on error.
+ */
+int make_room_for_index_entry_in_index_block(INDEX_BLOCK *index,
+ INDEX_ENTRY *pos, __u32 size)
{
- return -ENOTSUP;
+ __u32 biu;
+
+ if (!size)
+ return 0;
+#ifdef DEBUG
+ /*
+ * Rigorous consistency checks. Always return -EINVAL even if more
+ * appropriate codes exist for simplicity of parsing the return value.
+ */
+ if (size != (size + 7 & ~7)) {
+ Eprintf("make_room_for_index_entry_in_index_block() received "
+ "non 8-byte aligned size.\n");
+ return -EINVAL;
+ }
+ if (!index || !pos)
+ return -EINVAL;
+ if ((char*)pos < (char*)index || (char*)pos + size < (char*)index ||
+ (char*)pos > (char*)index + sizeof(INDEX_BLOCK) -
+ sizeof(INDEX_HEADER) +
+ le32_to_cpu(index->index.allocated_size) ||
+ (char*)pos + size > (char*)index + sizeof(INDEX_BLOCK) -
+ sizeof(INDEX_HEADER) +
+ le32_to_cpu(index->index.allocated_size))
+ return -EINVAL;
+ /* The - sizeof(INDEX_ENTRY_HEADER) is for the index terminator. */
+ if ((char*)pos - (char*)index > le32_to_cpu(index->index.index_length)
+ - sizeof(INDEX_ENTRY_HEADER))
+ return -EINVAL;
+#endif
+ biu = le32_to_cpu(index->index.index_length);
+ /* Do we have enough space? */
+ if (biu + size > le32_to_cpu(index->index.allocated_size))
+ return -ENOSPC;
+ /* Move everything after pos to pos + size. */
+ memmove((char*)pos + size, (char*)pos, biu - ((char*)pos -
+ (char*)&index->index));
+ /* Update index block. */
+ index->index.index_length = cpu_to_le32(biu + size);
+ return 0;
+}
+
+/*
+ * Insert the fully completed FILE_NAME_ATTR @file_name which is inside
+ * the file with mft reference @file_ref into the index (allocation) block
+ * @index of the parent directory with mft reference @parent_ref and mft
+ * record @parent_dir.
+ *
+ * Return 0 on success or -errno on error.
+ */
+int insert_file_link_in_dir_index(INDEX_BLOCK *index, MFT_REF parent_ref,
+ MFT_RECORD *parent_dir, MFT_REF file_ref,
+ FILE_NAME_ATTR *file_name, __u32 file_name_size)
+{
+ int err;
+ INDEX_ENTRY *ie;
+
+ /*
+ * Lookup dir entry @file_name in dir @index to determine correct
+ * insertion location.
+ */
+ while (/**/) {
+ //..
+ };
+ err = make_room_for_index_entry_in_index_block(index, ie,
+ file_name_size);
+ if (err) {
+ //..
+ }
+ /* Create entry in place and copy file name attribute value. */
+ ie->indexed_file = file_ref;
+ ie->length = cpu_to_le16();
+ ie->key_length = cpu_to_le16(file_name_size);
+ ie->flags = ;
+ ie->reserved = cpu_to_le16(0);
+ memcpy((char*)&ie->key.file_name, (char*)file_name, file_name_size);
+ return 0;
}
@@ -2532,7 +2617,9 @@
opt.upcase_len, $FILE_NAME, COLLATION_FILE_NAME,
opt.index_block_size);
- if (!err)
+ if (!err) {
err = upgrade_to_large_index(m, "$I30", 4, IGNORE_CASE,
- opt.upcase, opt.upcase_len);
+ opt.upcase, opt.upcase_len, &index,
+ &index_size);
+ }
if (!err) {
memset(&ctx, 0, sizeof(ctx));
@@ -2543,5 +2630,6 @@
err_exit("BUG: $FILE_NAME attribute not found.\n");
a = ctx.attr;
- err = insert_file_link_in_dir(m, (FILE_NAME*)((char*)a +
+ err = insert_file_link_in_dir_index(index, root_ref,
+ m, root_ref, (FILE_NAME_ATTR*)((char*)a +
le16_to_cpu(a->value_offset)),
le32_to_cpu(a->value_length));
|