[syslinux:master] ntfs: fix bug in parse_data_run()

syslinux-bot for Paulo Alcantara pcacjr at gmail.com
Sat Dec 17 21:19:24 PST 2011


Commit-ID:  f1ce35d08a51708f1ad4d6b833df32199f366f94
Gitweb:     http://www.syslinux.org/commit/f1ce35d08a51708f1ad4d6b833df32199f366f94
Author:     Paulo Alcantara <pcacjr at gmail.com>
AuthorDate: Thu, 28 Jul 2011 00:11:28 +0000
Committer:  Paulo Alcantara <pcacjr at gmail.com>
CommitDate: Sun, 11 Sep 2011 04:09:57 +0000

ntfs: fix bug in parse_data_run()

parse_data_run() used to get the wrong value of VCNs starting at LCN,
so it was only getting the value 1 and the NTFS driver didn't look at
the other VCNs.

Now, everything seems to work, except the readdir() function :-P

Signed-off-by: Paulo Alcantara <pcacjr at gmail.com>

---
 core/fs/ntfs/ntfs.c |   67 ++++++-----------------------
 core/fs/ntfs/ntfs.h |  119 ++++++++++++++++++++++++++++-----------------------
 2 files changed, 79 insertions(+), 107 deletions(-)

diff --git a/core/fs/ntfs/ntfs.c b/core/fs/ntfs/ntfs.c
index e1ba3e1..b9eca4c 100644
--- a/core/fs/ntfs/ntfs.c
+++ b/core/fs/ntfs/ntfs.c
@@ -82,13 +82,12 @@ static int fixups_writeback(struct fs_info *fs, NTFS_RECORD *nrec)
     /* make it to point to the last two bytes of the RECORD's first sector */
     block = (uint16_t *)((uint8_t *)nrec + SECTOR_SIZE(fs) - 2);
 
-    while (usa_count) {
+    while (usa_count--) {
         if (*block != usa_no)
             goto out;
 
         *block = *usa++;
         block = (uint16_t *)((uint8_t *)block + SECTOR_SIZE(fs));
-        usa_count--;
     }
 
     return 0;
@@ -214,32 +213,11 @@ out:
     return false;
 }
 
-enum {
-    MAP_UNSPEC,
-    MAP_START           = 1 << 0,
-    MAP_END             = 1 << 1,
-    MAP_ALLOCATED       = 1 << 2,
-    MAP_UNALLOCATED     = 1 << 3,
-    MAP_MASK            = 0x0000000F,
-};
-
-struct mapping_chunk {
-    uint64_t cur_vcn;   /* Current Virtual Cluster Number */
-    uint8_t vcn_len;    /* Virtual Cluster Number length in bytes */
-    uint64_t next_vcn;  /* Next Virtual Cluster Number */
-    uint8_t lcn_len;    /* Logical Cluster Number length in bytes */
-    int64_t cur_lcn;    /* Logical Cluster Number offset */
-    uint32_t flags;     /* Specific flags of this chunk */
-};
-
 static inline uint8_t *mapping_chunk_init(ATTR_RECORD *attr,
                                     struct mapping_chunk *chunk,
                                     uint32_t *offset)
 {
     memset(chunk, 0, sizeof(*chunk));
-    chunk->cur_vcn = attr->data.non_resident.lowest_vcn;
-    chunk->cur_lcn = 0LL;
-
     *offset = 0U;
 
     return (uint8_t *)attr + attr->data.non_resident.mapping_pairs_offset;
@@ -276,8 +254,6 @@ static int parse_data_run(const void *stream, uint32_t *offset,
     if (!*offset)
         chunk->flags |= MAP_START;  /* initial chunk */
 
-    chunk->cur_vcn = chunk->next_vcn;
-
     count = *buf;
     v = count & 0x0F;
     l = count >> 4;
@@ -285,9 +261,6 @@ static int parse_data_run(const void *stream, uint32_t *offset,
     if (v > 8 || l > 8) /* more than 8 bytes ? */
         goto out;
 
-    chunk->vcn_len = v;
-    chunk->lcn_len = l;
-
     byte = (uint8_t *)buf + v;
     count = v;
 
@@ -298,7 +271,7 @@ static int parse_data_run(const void *stream, uint32_t *offset,
         res = (res << byte_shift) | ((val + mask) ^ mask);
     }
 
-    chunk->next_vcn += res;
+    chunk->len = res;   /* get length data */
 
     byte = (uint8_t *)buf + v + l;
     count = l;
@@ -311,14 +284,12 @@ static int parse_data_run(const void *stream, uint32_t *offset,
     while (count--)
         res = (res << byte_shift) | *byte--;
 
-    chunk->cur_lcn += res;
-    if (!chunk->cur_lcn) {  /* is LCN 0 ? */
-        /* then VCNS from cur_vcn to next_vcn - 1 are unallocated */
+    chunk->lcn += res;
+    /* are VCNS from cur_vcn to next_vcn - 1 unallocated ? */
+    if (!chunk->lcn)
         chunk->flags |= MAP_UNALLOCATED;
-    } else {
-        /* otherwise they're all allocated */
+    else
         chunk->flags |= MAP_ALLOCATED;
-    }
 
     *offset += v + l + 1;
 
@@ -412,8 +383,6 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
             goto out;
         }
 
-        printf("here!\n");
-
         /* note: INDEX_ROOT is always resident */
         ir = (INDEX_ROOT *)((uint8_t *)attr +
                                     attr->data.resident.value_offset);
@@ -457,14 +426,7 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
         } else {
             attr_len = (uint8_t *)attr + attr->len;
 
-            memset((void *)&chunk, 0, sizeof(chunk));
-            chunk.cur_vcn = attr->data.non_resident.lowest_vcn;
-            chunk.cur_lcn = 0LL;
-
-            stream = (uint8_t *)attr +
-                            attr->data.non_resident.mapping_pairs_offset;
-            droffset = 0U;
-
+            stream = mapping_chunk_init(attr, &chunk, &droffset);
             for (;;) {
                 err = parse_data_run(stream, &droffset, attr_len, &chunk);
                 if (err) {
@@ -483,10 +445,8 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
                 goto out;
             }
 
-            NTFS_PVT(inode)->data.non_resident.start_vcn = chunk.cur_vcn;
-            NTFS_PVT(inode)->data.non_resident.next_vcn = chunk.next_vcn;
-            NTFS_PVT(inode)->data.non_resident.vcn_no = chunk.vcn_len;
-            NTFS_PVT(inode)->data.non_resident.lcn = chunk.cur_lcn;
+            NTFS_PVT(inode)->data.non_resident.len = chunk.len;
+            NTFS_PVT(inode)->data.non_resident.lcn = chunk.lcn;
             inode->size = attr->data.non_resident.initialized_size;
         }
     }
@@ -629,8 +589,7 @@ static struct inode *index_lookup(const char *dname, struct inode *dir)
             continue;
 
         if (chunk.flags & MAP_ALLOCATED) {
-            dprintf("%d cluster(s) starting at 0x%X\n", chunk.vcn_len,
-                    chunk.cur_lcn);
+            printf("%d cluster(s) starting at 0x%X\n", chunk.len, chunk.lcn);
             memcpy(&chunks[i++], &chunk, sizeof chunk);
         }
 
@@ -639,8 +598,8 @@ static struct inode *index_lookup(const char *dname, struct inode *dir)
     i = 0;
     while (chunks_count--) {
         vcn = 0;
-        lcn = chunks[i].cur_lcn;
-        while (vcn < chunks[i].vcn_len) {
+        lcn = chunks[i].lcn;
+        while (vcn < chunks[i].len) {
             block = ((lcn + vcn) << NTFS_SB(fs)->clust_shift) <<
                     SECTOR_SHIFT(fs) >> BLOCK_SHIFT(fs);
 
@@ -692,7 +651,7 @@ static struct inode *index_lookup(const char *dname, struct inode *dir)
     }
 
 not_found:
-    printf("Index not found\n");
+    dprintf("Index not found\n");
 
 out:
     printf("%s not found!\n", dname);
diff --git a/core/fs/ntfs/ntfs.h b/core/fs/ntfs/ntfs.h
index 2187693..3174fe0 100644
--- a/core/fs/ntfs/ntfs.h
+++ b/core/fs/ntfs/ntfs.h
@@ -43,7 +43,7 @@ struct ntfs_bpb {
     uint32_t unused_6;
 
     uint8_t pad[428];       /* padding to a sector boundary (512 bytes) */
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 struct ntfs_sb_info {
     block_t mft_block;              /* The first MFT record block */
@@ -58,7 +58,7 @@ struct ntfs_sb_info {
     unsigned clust_mask;
     unsigned clust_size;
 
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 /* The NTFS in-memory inode structure */
 struct ntfs_inode {
@@ -77,9 +77,7 @@ struct ntfs_inode {
             uint32_t offset;    /* Data offset */
         } resident;
         struct {            /* Used only if non_resident is set */
-            uint64_t start_vcn; /* Starting Virtual Cluster Number */
-            uint64_t next_vcn;  /* Next Virtual Cluster Number */
-            uint8_t vcn_no;     /* Number of Virtual Cluster Numbers */
+            uint8_t len;
             int64_t lcn;        /* Logical Cluster Number offset */
         } non_resident;
     } data;
@@ -104,6 +102,21 @@ struct ntfs_inode {
     sector_t here;          /* Sector corresponding to offset */
 };
 
+enum {
+    MAP_UNSPEC,
+    MAP_START           = 1 << 0,
+    MAP_END             = 1 << 1,
+    MAP_ALLOCATED       = 1 << 2,
+    MAP_UNALLOCATED     = 1 << 3,
+    MAP_MASK            = 0x0000000F,
+};
+
+struct mapping_chunk {
+    uint8_t len;
+    int64_t lcn;        /* Logical Cluster Number */
+    uint32_t flags;     /* Specific flags of this chunk */
+};
+
 /* System defined attributes (32-bit)
  * Each attribute type has a corresponding attribute name (in Unicode)
  */
@@ -186,7 +199,7 @@ typedef struct {
     uint32_t magic;
     uint16_t usa_ofs;
     uint16_t usa_count;
-} __attribute__((packed)) NTFS_RECORD;
+} __attribute__((__packed__)) NTFS_RECORD;
 
 /* The $MFT metadata file types */
 typedef enum {
@@ -213,7 +226,7 @@ typedef enum {
 enum {
     MFT_RECORD_IN_USE       = 0x0001,
     MFT_RECORD_IS_DIRECTORY = 0x0002,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 typedef struct {
     uint32_t magic;
@@ -230,7 +243,7 @@ typedef struct {
     uint16_t next_attr_instance;
     uint16_t reserved;
     uint32_t mft_record_no;
-} __attribute__((packed)) MFT_RECORD;   /* 48 bytes */
+} __attribute__((__packed__)) MFT_RECORD;   /* 48 bytes */
 
 /* This is the version without the NTFS 3.1+ specific fields */
 typedef struct {
@@ -246,7 +259,7 @@ typedef struct {
     uint32_t bytes_allocated;
     uint64_t base_mft_record;
     uint16_t next_attr_instance;
-} __attribute__((packed)) MFT_RECORD_OLD;   /* 42 bytes */
+} __attribute__((__packed__)) MFT_RECORD_OLD;   /* 42 bytes */
 
 enum {
     ATTR_DEF_INDEXABLE          = 0x02,
@@ -266,7 +279,7 @@ typedef struct {
     uint32_t flags;     /* Attr def flags */
     uint64_t min_size;
     uint64_t max_size;
-} __attribute__((packed)) ATTR_DEF;
+} __attribute__((__packed__)) ATTR_DEF;
 
 /* Attribute flags (16-bit) */
 enum {
@@ -275,12 +288,12 @@ enum {
 
     ATTR_IS_ENCRYPTED       = 0x4000,
     ATTR_IS_SPARSE          = 0x8000,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 /* Flags of resident attributes (8-bit) */
 enum {
     RESIDENT_ATTR_IS_INDEXED = 0x01,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 typedef struct {
     uint32_t type;      /* Attr. type code */
@@ -296,7 +309,7 @@ typedef struct {
             uint16_t value_offset;
             uint8_t flags;  /* Flags of resident attributes */
             int8_t reserved;
-        } __attribute__((packed)) resident;
+        } __attribute__((__packed__)) resident;
         struct {    /* Non-resident attributes */
             uint64_t lowest_vcn;
             uint64_t highest_vcn;
@@ -306,9 +319,9 @@ typedef struct {
             int64_t allocated_size;
             int64_t initialized_size;
             int64_t compressed_size;
-        } __attribute__((packed)) non_resident;
-    } __attribute__((packed)) data;
-} __attribute__((packed)) ATTR_RECORD;
+        } __attribute__((__packed__)) non_resident;
+    } __attribute__((__packed__)) data;
+} __attribute__((__packed__)) ATTR_RECORD;
 
 /* Attribute: Standard Information (0x10)
  * Note: always resident
@@ -322,7 +335,7 @@ typedef struct {
     union {
         struct {    /* NTFS 1.2 (48 bytes) */
             uint8_t reserved12[12];
-        } __attribute__((packed)) v1;
+        } __attribute__((__packed__)) v1;
         struct {    /* NTFS 3.x (72 bytes) */
             uint32_t max_version;
             uint32_t version;
@@ -331,9 +344,9 @@ typedef struct {
             uint32_t sec_id;
             uint64_t quota_charged;
             int64_t usn;
-        } __attribute__((packed)) v3;
-    } __attribute__((packed)) ver;
-} __attribute__((packed)) STANDARD_INFORMATION;
+        } __attribute__((__packed__)) v3;
+    } __attribute__((__packed__)) ver;
+} __attribute__((__packed__)) STANDARD_INFORMATION;
 
 /* Attribute: Attribute List (0x20)
  * Note: can be either resident or non-resident
@@ -348,7 +361,7 @@ typedef struct {
     uint16_t instance;
     uint16_t name[0];       /* Name in Unicode */
     /* sizeof() = 26 + (attribute_name_length * 2) bytes */
-} __attribute__((packed)) ATTR_LIST_ENTRY;
+} __attribute__((__packed__)) ATTR_LIST_ENTRY;
 
 #define NTFS_MAX_FILE_NAME_LEN 255
 
@@ -358,7 +371,7 @@ enum {
     FILE_NAME_WIN32             = 0x01,
     FILE_NAME_DOS               = 0x02,
     FILE_NAME_WIN32_AND_DOS     = 0x03,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 /* Attribute: Filename (0x30)
  * Note: always resident
@@ -374,17 +387,17 @@ typedef struct {
     uint32_t file_attrs;
     union {
         struct {
-            uint16_t packed_ea_size;
+            uint16_t __packed___ea_size;
             uint16_t reserved;      /* reserved for alignment */
-        } __attribute__((packed)) ea;
+        } __attribute__((__packed__)) ea;
         struct {
             uint32_t reparse_point_tag;
-        } __attribute__((packed)) rp;
-    } __attribute__((packed)) type;
+        } __attribute__((__packed__)) rp;
+    } __attribute__((__packed__)) type;
     uint8_t file_name_len;
     uint8_t file_name_type;
     uint16_t file_name[0];          /* File name in Unicode */
-} __attribute__((packed)) FILE_NAME_ATTR;
+} __attribute__((__packed__)) FILE_NAME_ATTR;
 
 /* GUID structure */
 typedef struct {
@@ -392,7 +405,7 @@ typedef struct {
     uint16_t data1;
     uint16_t data2;
     uint8_t data3[8];
-} __attribute__((packed)) GUID;
+} __attribute__((__packed__)) GUID;
 
 typedef struct {
     uint64_t mft_ref;
@@ -401,10 +414,10 @@ typedef struct {
             GUID birth_vol_id;
             GUID birth_obj_id;
             GUID domain_id;
-        } __attribute__((packed)) origin;
+        } __attribute__((__packed__)) origin;
         uint8_t extended_info[48];
-    } __attribute__((packed)) opt;
-} __attribute__((packed)) OBJ_ID_INDEX_DATA;
+    } __attribute__((__packed__)) opt;
+} __attribute__((__packed__)) OBJ_ID_INDEX_DATA;
 
 /* Attribute: Object ID (NTFS 3.0+) (0x40)
  * Note: always resident
@@ -416,10 +429,10 @@ typedef struct {
             GUID birth_vol_id;
             GUID birth_obj_id;
             GUID domain_id;
-        } __attribute__((packed)) origin;
+        } __attribute__((__packed__)) origin;
         uint8_t extended_info[48];
-    } __attribute__((packed)) opt;
-} __attribute__((packed)) OBJECT_ID_ATTR;
+    } __attribute__((__packed__)) opt;
+} __attribute__((__packed__)) OBJECT_ID_ATTR;
 
 /* Attribute: Volume Name (0x60)
  * Note: always resident
@@ -427,7 +440,7 @@ typedef struct {
  */
 typedef struct {
     uint16_t name[0];       /* The name of the volume in Unicode */
-} __attribute__((packed)) VOLUME_NAME;
+} __attribute__((__packed__)) VOLUME_NAME;
 
 /* Volume flags (16-bit) */
 enum {
@@ -445,7 +458,7 @@ enum {
     VOLUME_FLAGS_MASK           = 0xC03F,
 
     VOLUME_MUST_MOUNT_RO_MASK   = 0xC027,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 /* Attribute: Volume Information (0x70)
  * Note: always resident
@@ -456,14 +469,14 @@ typedef struct {
     uint8_t major_ver;
     uint8_t minor_ver;
     uint16_t flags;     /* Volume flags */
-} __attribute__((packed)) VOLUME_INFORMATION;
+} __attribute__((__packed__)) VOLUME_INFORMATION;
 
 /* Attribute: Data attribute (0x80)
  * Note: can be either resident or non-resident
  */
 typedef struct {
     uint8_t data[0];
-} __attribute__((packed)) DATA_ATTR;
+} __attribute__((__packed__)) DATA_ATTR;
 
 /* Index header flags (8-bit) */
 enum {
@@ -472,7 +485,7 @@ enum {
     LEAF_NODE   = 0,
     INDEX_NODE  = 1,
     NODE_MASK   = 1,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 /* Header for the indexes, describing the INDEX_ENTRY records, which
  * follow the INDEX_HEADER.
@@ -483,7 +496,7 @@ typedef struct {
     uint32_t allocated_size;
     uint8_t flags;              /* Index header flags */
     uint8_t reserved[3];        /* Align to 8-byte boundary */
-} __attribute__((packed)) INDEX_HEADER;
+} __attribute__((__packed__)) INDEX_HEADER;
 
 /* Attribute: Index Root (0x90)
  * Note: always resident
@@ -497,7 +510,7 @@ typedef struct {
     uint8_t clust_per_index_block;
     uint8_t reserved[3];
     INDEX_HEADER index;
-} __attribute__((packed)) INDEX_ROOT;
+} __attribute__((__packed__)) INDEX_ROOT;
 
 /* Attribute: Index allocation (0xA0)
  * Note: always non-resident, of course! :-)
@@ -509,7 +522,7 @@ typedef struct {
     int64_t lsn;
     int64_t index_block_vcn;    /* Virtual cluster number of the index block */
     INDEX_HEADER index;
-} __attribute__((packed)) INDEX_BLOCK;
+} __attribute__((__packed__)) INDEX_BLOCK;
 
 typedef INDEX_BLOCK INDEX_ALLOCATION;
 
@@ -518,36 +531,36 @@ enum {
     INDEX_ENTRY_END             = 2,
     /* force enum bit width to 16-bit */
     INDEX_ENTRY_SPACE_FILTER    = 0xFFFF,
-} __attribute__((packed));
+} __attribute__((__packed__));
 
 typedef struct {
     union {
         struct { /* Only valid when INDEX_ENTRY_END is not set */
             uint64_t indexed_file;
-        } __attribute__((packed)) dir;
+        } __attribute__((__packed__)) dir;
         struct { /* Used for views/indexes to find the entry's data */
             uint16_t data_offset;
             uint16_t data_len;
             uint32_t reservedV;
-        } __attribute__((packed)) vi;
-    } __attribute__((packed)) data;
+        } __attribute__((__packed__)) vi;
+    } __attribute__((__packed__)) data;
     uint16_t len;
     uint16_t key_len;
     uint16_t flags;     /* Index entry flags */
     uint16_t reserved;  /* Align to 8-byte boundary */
-} __attribute__((packed)) INDEX_ENTRY_HEADER;
+} __attribute__((__packed__)) INDEX_ENTRY_HEADER;
 
 typedef struct {
     union {
         struct { /* Only valid when INDEX_ENTRY_END is not set */
             uint64_t indexed_file;
-        } __attribute__((packed)) dir;
+        } __attribute__((__packed__)) dir;
         struct { /* Used for views/indexes to find the entry's data */
             uint16_t data_offset;
             uint16_t data_len;
             uint32_t reservedV;
-        } __attribute__((packed)) vi;
-    } __attribute__((packed)) data;
+        } __attribute__((__packed__)) vi;
+    } __attribute__((__packed__)) data;
     uint16_t len;
     uint16_t key_len;
     uint16_t flags;     /* Index entry flags */
@@ -560,12 +573,12 @@ typedef struct {
         //REPARSE_INDEX_KEY reparse;
         //SID sid;
         uint32_t owner_id;
-    } __attribute__((packed)) key;
-} __attribute__((packed)) INDEX_ENTRY;
+    } __attribute__((__packed__)) key;
+} __attribute__((__packed__)) INDEX_ENTRY;
 
 typedef struct {
     uint8_t bitmap[0];      /* Array of bits */
-} __attribute__((packed)) BITMAP_ATTR;
+} __attribute__((__packed__)) BITMAP_ATTR;
 
 static inline struct ntfs_sb_info *NTFS_SB(struct fs_info *fs)
 {


More information about the Syslinux-commits mailing list