{
        dir_entry *realdent;
        dir_slot *slotptr = (dir_slot *)retdent;
-       __u8 *nextclust = cluster + mydata->clust_size * SECTOR_SIZE;
+       __u8 *buflimit = cluster + ((curclust == 0) ?
+                                       LINEAR_PREFETCH_SIZE :
+                                       (mydata->clust_size * SECTOR_SIZE)
+                                  );
        __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff;
        int idx = 0;
 
-       while ((__u8 *)slotptr < nextclust) {
+       if (counter > VFAT_MAXSEQ) {
+               debug("Error: VFAT name is too long\n");
+               return -1;
+       }
+
+       while ((__u8 *)slotptr < buflimit) {
                if (counter == 0)
                        break;
                if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter)
                counter--;
        }
 
-       if ((__u8 *)slotptr >= nextclust) {
+       if ((__u8 *)slotptr >= buflimit) {
                dir_slot *slotptr2;
 
-               slotptr--;
+               if (curclust == 0)
+                       return -1;
                curclust = get_fatent(mydata, curclust);
                if (CHECK_CLUST(curclust, mydata->fatsize)) {
                        debug("curclust: 0x%x\n", curclust);
                }
 
                slotptr2 = (dir_slot *)get_vfatname_block;
-               while (slotptr2->id > 0x01)
+               while (counter > 0) {
+                       if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK)
+                           & 0xff) != counter)
+                               return -1;
                        slotptr2++;
+                       counter--;
+               }
 
                /* Save the real directory entry */
-               realdent = (dir_entry *)slotptr2 + 1;
-               while ((__u8 *)slotptr2 >= get_vfatname_block) {
-                       slot2str(slotptr2, l_name, &idx);
+               realdent = (dir_entry *)slotptr2;
+               while ((__u8 *)slotptr2 > get_vfatname_block) {
                        slotptr2--;
+                       slot2str(slotptr2, l_name, &idx);
                }
        } else {
                /* Save the real directory entry */
                dentptr = (dir_entry *)get_dentfromdir_block;
 
                for (i = 0; i < DIRENTSPERCLUST; i++) {
-                       char s_name[14], l_name[256];
+                       char s_name[14], l_name[VFAT_MAXLEN_BYTES];
 
                        l_name[0] = '\0';
                        if (dentptr->name[0] == DELETED_FLAG) {
                debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%d\n",
                        cursect, mydata->clust_size, DIRENTSPERBLOCK);
 
-               if (disk_read(cursect, mydata->clust_size, do_fat_read_block) < 0) {
+               if (disk_read(cursect,
+                               (mydata->fatsize == 32) ?
+                               (mydata->clust_size) :
+                               LINEAR_PREFETCH_SIZE,
+                               do_fat_read_block) < 0) {
                        debug("Error: reading rootdir block\n");
                        return -1;
                }
                dentptr = (dir_entry *) do_fat_read_block;
 
                for (i = 0; i < DIRENTSPERBLOCK; i++) {
-                       char s_name[14], l_name[256];
+                       char s_name[14], l_name[VFAT_MAXLEN_BYTES];
 
                        l_name[0] = '\0';
+                       if (dentptr->name[0] == DELETED_FLAG) {
+                               dentptr++;
+                               continue;
+                       }
                        if ((dentptr->attr & ATTR_VOLUME)) {
 #ifdef CONFIG_SUPPORT_VFAT
                                if ((dentptr->attr & ATTR_VFAT) &&
                                        prevcksum =
                                                ((dir_slot *)dentptr)->alias_checksum;
 
-                                       get_vfatname(mydata, 0,
+                                       get_vfatname(mydata,
+                                                    (mydata->fatsize == 32) ?
+                                                    root_cluster :
+                                                    0,
                                                     do_fat_read_block,
                                                     dentptr, l_name);