[syslinux:pathbased] fat: handle .. pointing back to the root directory

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sun Jun 13 14:21:15 PDT 2010


Commit-ID:  1ea741be7aad4c77d4fd2a602c3669ac59f1db73
Gitweb:     http://syslinux.zytor.com/commit/1ea741be7aad4c77d4fd2a602c3669ac59f1db73
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 13 Jun 2010 14:18:23 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 13 Jun 2010 14:18:23 -0700

fat: handle .. pointing back to the root directory

.. pointing back to the root directory will have a cluster number of
0, even for FAT32 where there is an actual cluster number for the root
directory.  Handle this as a special case.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/fs/fat/fat.c |   36 +++++++++++++++++++++++++++---------
 1 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index 6850993..5902f48 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -276,26 +276,32 @@ static void mangle_dos_name(char *mangle_buf, const char *src)
     int i;
     unsigned char c;
 
-    i = 0;
-    while (i < 11) {
-	c = *src++;
-
+    if (src[0] == '.' && (!src[1] || (src[1] == '.' && !src[2]))) {
+	/* . and .. mangle to their respective zero-padded version */
+	i = stpcpy(mangle_buf, src) - mangle_buf;
+    } else {
+	i = 0;
+	while (i < 11) {
+	    c = *src++;
+	    
 	if ((c <= ' ') || (c == '/'))
 	    break;
-
+	
 	if (c == '.') {
 	    while (i < 8)
 		mangle_buf[i++] = ' ';
 	    i = 8;
 	    continue;
 	}
-
+	
 	c = codepage.upper[c];
 	if (i == 0 && c == 0xe5)
 	    c = 0x05;		/* Special hack for the first byte only! */
-
+	
 	mangle_buf[i++] = c;
+	}
     }
+
     while (i < 11)
 	mangle_buf[i++] = ' ';
 
@@ -408,7 +414,10 @@ static inline sector_t first_sector(struct fs_info *fs,
     sector_t sector;
 
     first_clust = (dir->first_cluster_high << 16) + dir->first_cluster_low;
-    sector = ((first_clust - 2) << sbi->clust_shift) + sbi->data;
+    if (first_clust == 0)
+	sector = sbi->root;	/* first_clust == 0 means root directory */
+    else
+	sector = ((first_clust - 2) << sbi->clust_shift) + sbi->data;
 
     return sector;
 }
@@ -533,7 +542,16 @@ found:
     inode->size = de->file_size;
     PVT(inode)->start_cluster = 
 	(de->first_cluster_high << 16) + de->first_cluster_low;
-    PVT(inode)->start = PVT(inode)->here = first_sector(fs, de);
+    if (PVT(inode)->start_cluster == 0) {
+	/* Root directory */
+	int root_size = FAT_SB(fs)->root_size;
+
+	PVT(inode)->start_cluster = FAT_SB(fs)->root_cluster;
+	inode->size = root_size ? root_size << fs->sector_shift : ~0;
+	PVT(inode)->start = PVT(inode)->here = FAT_SB(fs)->root;
+    } else {
+	PVT(inode)->start = PVT(inode)->here = first_sector(fs, de);
+    }
     inode->mode = get_inode_mode(de->attr);
 
     return inode;



More information about the Syslinux-commits mailing list