From c9d40485b45ea325cc9a855f39eb204fb23642a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Mon, 19 Apr 2010 11:10:30 +0200 Subject: [PATCH] fixed a possible index block with no key in --- libntfs-3g/security.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c index 1856a81f..55394adf 100644 --- a/libntfs-3g/security.c +++ b/libntfs-3g/security.c @@ -714,6 +714,7 @@ static le32 entersecurityattr(ntfs_volume *vol, INDEX_ENTRY *entry; INDEX_ENTRY *next; ntfs_index_context *xsii; + int retries; ntfs_attr *na; int olderrno; @@ -758,10 +759,14 @@ static le32 entersecurityattr(ntfs_volume *vol, * All index blocks should be at least half full * so there always is a last entry but one, * except when creating the first entry in index root. - * A simplified version of next(), limited to - * current index node, could be used + * This was however found not to be true : chkdsk + * sometimes deletes all the (unused) keys in the last + * index block without rebalancing the tree. + * When this happens, a new search is restarted from + * the smallest key. */ keyid = const_cpu_to_le32(0); + retries = 0; while (entry) { next = ntfs_index_next(entry,xsii); if (next) { @@ -777,6 +782,20 @@ static le32 entersecurityattr(ntfs_volume *vol, size = le32_to_cpu(psii->datasize); } entry = next; + if (!entry && !keyid && !retries) { + /* search failed, retry from smallest key */ + ntfs_index_ctx_reinit(xsii); + found = !ntfs_index_lookup((char*)&keyid, + sizeof(SII_INDEX_KEY), xsii); + if (!found && (errno != ENOENT)) { + ntfs_log_perror("Index $SII is broken"); + } else { + /* restore errno */ + errno = olderrno; + entry = xsii->entry; + } + retries++; + } } } if (!keyid) {