patch-2.0.34 linux/fs/isofs/dir.c

Next file: linux/fs/isofs/inode.c
Previous file: linux/fs/isofs/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.33/linux/fs/isofs/dir.c linux/fs/isofs/dir.c
@@ -23,6 +23,7 @@
 
 #include <asm/segment.h>
 
+
 static int isofs_readdir(struct inode *, struct file *, void *, filldir_t);
 
 static struct file_operations isofs_dir_operations =
@@ -114,15 +115,18 @@
 	unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
 	unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
 	unsigned int block, offset;
-	int inode_number;
+	int inode_number = 0;	/* Quiet GCC */
 	struct buffer_head *bh;
-	int len, rrflag;
-	int high_sierra = 0;
-	char *name;
+	int len;
+	int map;
+	int high_sierra;
+	int first_de = 1;
+	char *p = NULL;		/* Quiet GCC */
 	struct iso_directory_record *de;
 
 	offset = filp->f_pos & (bufsize - 1);
 	block = isofs_bmap(inode, filp->f_pos >> bufbits);
+	high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
 
 	if (!block)
 		return 0;
@@ -154,7 +158,7 @@
 		}
 
 		de = (struct iso_directory_record *) (bh->b_data + offset);
-		inode_number = (block << bufbits) + (offset & (bufsize - 1));
+		if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
 		de_len = *(unsigned char *) de;
 #ifdef DEBUG
@@ -215,6 +219,13 @@
 		}
 		offset = next_offset;
 
+		if(de->flags[-high_sierra] & 0x80) {
+			first_de = 0;
+			filp->f_pos += de_len;
+			continue;
+		}
+		first_de = 1;
+
 		/* Handle the case of the '.' directory */
 		if (de->name_len[0] == 1 && de->name[0] == 0) {
 			if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino) < 0)
@@ -223,6 +234,8 @@
 			continue;
 		}
 
+		len = 0;
+
 		/* Handle the case of the '..' directory */
 		if (de->name_len[0] == 1 && de->name[0] == 1) {
 			inode_number = parent_inode_number(inode, de);
@@ -236,46 +249,43 @@
 
 		/* Handle everything else.  Do name translation if there
 		   is no Rock Ridge NM field. */
-
 		if (inode->i_sb->u.isofs_sb.s_unhide == 'n') {
 			/* Do not report hidden or associated files */
-			high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
 			if (de->flags[-high_sierra] & 5) {
 				filp->f_pos += de_len;
 				continue;
 			}
 		}
 
-		/* Check Rock Ridge name translation.. */
-		len = de->name_len[0];
-		name = de->name;
-		rrflag = get_rock_ridge_filename(de, &name, &len, inode);
-		if (rrflag) {
-			/* rrflag == 1 means that we have a new name (kmalloced) */
-			if (rrflag == 1) {
-				rrflag = filldir(dirent, name, len, filp->f_pos, inode_number);
-				dcache_add(inode, name, len, inode_number);
-				kfree(name); /* this was allocated in get_r_r_filename.. */
-				if (rrflag < 0)
-					break;
+		map = 1;
+		if (inode->i_sb->u.isofs_sb.s_rock) {
+			len = get_rock_ridge_filename(de, tmpname, inode);
+			if (len != 0) {
+				p = tmpname;
+				map = 0;
 			}
-			filp->f_pos += de_len;
-			continue;
 		}
-
-		if (inode->i_sb->u.isofs_sb.s_mapping == 'n') {
-			len = isofs_name_translate(name, len, tmpname);
-			if (filldir(dirent, tmpname, len, filp->f_pos, inode_number) < 0)
-				break;
-			dcache_add(inode, tmpname, len, inode_number);
-			filp->f_pos += de_len;
-			continue;
+		if (map) {
+			if (inode->i_sb->u.isofs_sb.s_joliet_level) {
+				len = get_joliet_filename(de, inode, tmpname);
+				p = tmpname;
+			} else {
+				if (inode->i_sb->u.isofs_sb.s_mapping == 'n') {
+					len = isofs_name_translate(de->name, de->name_len[0],
+								   tmpname);
+					p = tmpname;
+				} else {
+					p = de->name;
+					len = de->name_len[0];
+				}
+			}
 		}
+		if (len > 0) {
+			if (filldir(dirent, p, len, filp->f_pos, inode_number) < 0)
+				break;
 
-		if (filldir(dirent, name, len, filp->f_pos, inode_number) < 0)
-			break;
-
-		dcache_add(inode, name, len, inode_number);
+			dcache_add(inode, p, len, inode_number);
+		}
 		filp->f_pos += de_len;
 		continue;
 	}
@@ -301,7 +311,7 @@
 	tmpname = (char *) __get_free_page(GFP_KERNEL);
 	if (!tmpname)
 		return -ENOMEM;
-	tmpde = (struct iso_directory_record *) (tmpname+256);
+	tmpde = (struct iso_directory_record *) (tmpname+1024);
 
 	result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde);
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov