[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00769] Re: ext3 の dir_index & [FDclone-users:00766] のパッチ検証結果



 しらいです。

In Message-Id <20080410023934.GA29613@trix.islocal>
        Takeshi Hamasaki <hma@syd.odn.ne.jp>さんwrites:
> 濱崎です。

>  0. テスト用のディレクトリを新規に作って中に移動する 
>     mkdir testdir55 ; cd testdir55
>  1. ファイルを作る。これ以外のファイル名だと再現しないことがあります。
>     touch a b e d c
>  2. ディレクトリ内の並びを確認する
>     ls -f
>  3. FDclone を起動
>  4. 名前順にでソートする
>  5. WRITE_DIR する
>  6. 念のため ls -f でも確認

 どうも vfat にも色々あるようですね。kernel version にも依
存するのかも知れません。
 割と典型的な vfat の振舞いは、SFN を小文字で見せる癖に新規
作成時は大文字も小文字も LFN で格納するという変則的な仕様で
すね。
 実装の中には mkdir(2) のみは大文字 8+3 形式なら SFN で格納、
というパターンも見つかったのですが、vfat 上には LFN entry し
か作られないという傾向は割と不変のようです。
 そもそも file system 名に「vfat」なんて名乗ってる時点でお
里が知れる訳ですけど、こういう非対象な実装は何とかして欲しい
ものですね。

 つまるところ、Linux の vfat だと SFN を rename(2) で移動す
ると LFN に化ける訳で、これでは directory entry のサイズを保
存し続けることが出来ません。
 まぁ、現実的には MS-DOS からの access なんて既にあり得ない
し、Windows と Linux とから頻繁に交互 access するなんて事態
もなかなかないので、そういう前提の下では対応可能です。

 全てのケースには対応出来ていませんが、多分以下の patch で
何とかなると思います。[FDclone-users:00766] は捨ててこっちの
patch のみ適用して下さい。

---- Cut Here ----
diff -u ../old/FD-2.09h/file.c ./file.c
--- ../old/FD-2.09h/file.c	Sat Mar 15 00:00:00 2008
+++ ./file.c	Thu Apr 10 22:37:49 2008
@@ -23,6 +23,11 @@
 #define	LFNONLY		" +,;=[]"
 #define	DOSBODYLEN	8
 #define	DOSEXTLEN	3
+#define	FAT_NONE	0
+#define	FAT_PRIMAL	1
+#define	FAT_LFN		2
+#define	FAT_VFAT	3
+#define	FAT_DOSDRIVE	4
 
 #ifndef	O_BINARY
 #define	O_BINARY	0
@@ -1474,18 +1479,18 @@
 	return(1);
 }
 
-static int NEAR realdirsiz(s, dos, boundary, dirsize, ofs)
+static int NEAR realdirsiz(s, fat, boundary, dirsize, ofs)
 CONST char *s;
-int dos, boundary, dirsize, ofs;
+int fat, boundary, dirsize, ofs;
 {
 	int i, len, lfn, dot;
 
-	if (!dos) {
+	if (fat == FAT_NONE) {
 		len = (strlen(s) + ofs + boundary) & ~(boundary - 1);
 		return(len + dirsize);
 	}
 
-	if (dos > 1 && !isdotdir(s)) {
+	if (fat > FAT_PRIMAL && !isdotdir(s)) {
 
 		lfn = dot = 0;
 		for (i = len = 0; s[i]; i++, len++) {
@@ -1497,6 +1502,7 @@
 				i++;
 				lfn = 1;
 			}
+			else if (fat == FAT_VFAT && islower2(s[i])) lfn = 1;
 			else if (!lfn && strchr(LFNONLY, s[i])) lfn = 1;
 		}
 		if (lfn) /*EMPTY*/;
@@ -1512,20 +1518,22 @@
 	return(DOSDIRENT);
 }
 
-static int NEAR getnamlen(size, dos, boundary, dirsize, ofs)
-int size, dos, boundary, dirsize, ofs;
+static int NEAR getnamlen(size, fat, boundary, dirsize, ofs)
+int size, fat, boundary, dirsize, ofs;
 {
-	if (!dos) {
+	if (fat == FAT_NONE) {
 		size -= dirsize;
-		return((size & ~(boundary - 1)) - 1 - ofs);
+		size = (size & ~(boundary - 1)) - 1 - ofs;
+		if (size > MAXNAMLEN) size = MAXNAMLEN;
 	}
-
-	if (size > DOSDIRENT) {
+	else if (size <= DOSDIRENT) size = DOSBODYLEN;
+	else {
 		size -= DOSDIRENT;
-		return((size / DOSDIRENT) * LFNENTSIZ - 1);
+		size = (size / DOSDIRENT) * LFNENTSIZ - 1;
+		if (size > DOSMAXNAMLEN) size = DOSMAXNAMLEN;
 	}
 
-	return(DOSBODYLEN);
+	return(size);
 }
 
 static int NEAR saferename(from, to)
@@ -1535,7 +1543,7 @@
 	char fpath[MAXPATHLEN], tpath[MAXPATHLEN];
 #endif
 
-	if (!strpathcmp(from, to)) return(0);
+	if (!strpathcmp2(from, to)) return(0);
 #ifdef	_USEDOSEMU
 	from = nodospath(fpath, from);
 	to = nodospath(tpath, to);
@@ -1545,8 +1553,8 @@
 }
 
 /*ARGSUSED*/
-static char *NEAR maketmpfile(len, dos, tmpdir, old)
-int len, dos;
+static char *NEAR maketmpfile(len, fat, tmpdir, old)
+int len, fat;
 CONST char *tmpdir, *old;
 {
 #ifndef	PATHNOCASE
@@ -1567,7 +1575,7 @@
 	for (;;) {
 		genrandname(fname, len);
 #ifndef	PATHNOCASE
-		if (dos) for (i = 0; fname[i]; i++)
+		if (fat != FAT_NONE) for (i = 0; fname[i]; i++)
 			fname[i] = toupper2(fname[i]);
 #endif
 		if (tmpdir) {
@@ -1682,9 +1690,12 @@
 	char **tmpfiles;
 	int n, tmpno, block, ptr, totalptr, headbyte;
 #endif
+#ifndef	PATHNOCASE
+	int duppathignorecase;
+#endif
 	DIR *dirp;
 	struct dirent *dp;
-	int dos, boundary, dirsize, namofs;
+	int fat, boundary, dirsize, namofs;
 	int i, top, size, len, fnamp, ent;
 	CONST char *cp;
 	char *tmp, *tmpdir, **fnamelist, path[MAXPATHLEN];
@@ -1692,29 +1703,36 @@
 	switch (fs) {
 #if	!MSDOS
 		case FSID_EFS:		/* IRIX File System */
-			dos = 0;
+			fat = FAT_NONE;
 			headbyte = 4;
 			boundary = 2;
 			dirsize = sizeof(u_long);
 			namofs = 0;
 			break;
 		case FSID_SYSV:		/* SystemV R3 File System */
-			dos = 0;
+			fat = FAT_NONE;
 			headbyte = 0;
 			boundary = 8;
 			dirsize = sizeof(u_short);
 			namofs = 0;
 			break;
 		case FSID_LINUX:	/* Linux File System */
-			dos = 0;
+			fat = FAT_NONE;
 			headbyte = 0;
 			boundary = 4;
 			dirsize = 4;	/* short + short */
 			namofs = 3;
 			break;
+		case FSID_VFAT:		/* Linux File System for Windows */
+			fat = FAT_VFAT;
+			headbyte = -1;
+			boundary = LFNENTSIZ;
+			dirsize = DOSDIRENT;
+			namofs = 0;
+			break;
 # ifndef	_NODOSDRIVE
 		case FSID_DOSDRIVE:	/* Windows95 File System on DOSDRIVE */
-			dos = 3;
+			fat = FAT_DOSDRIVE;
 			headbyte = -1;
 			boundary = LFNENTSIZ;
 			dirsize = DOSDIRENT;
@@ -1723,7 +1741,7 @@
 # endif
 #endif	/* !MSDOS */
 		case FSID_FAT:		/* MS-DOS File System */
-			dos = 1;
+			fat = FAT_PRIMAL;
 #if	!MSDOS
 			headbyte = -1;
 #endif
@@ -1732,7 +1750,7 @@
 			namofs = 0;
 			break;
 		case FSID_LFN:		/* Windows95 File System */
-			dos = 2;
+			fat = FAT_LFN;
 #if	!MSDOS
 			headbyte = -1;
 #endif
@@ -1741,7 +1759,7 @@
 			namofs = 0;
 			break;
 		default:
-			dos = 0;
+			fat = FAT_NONE;
 #if	!MSDOS
 			headbyte = 0;
 #endif
@@ -1770,12 +1788,19 @@
 		return;
 	}
 
+#ifndef	PATHNOCASE
+	duppathignorecase = pathignorecase;
+	pathignorecase = (fat != FAT_NONE) ? 1 : 0;
+#endif
 	noconv++;
-	size = realdirsiz(fnamelist[top], dos, boundary, dirsize, namofs);
-	len = getnamlen(size, dos, boundary, dirsize, namofs);
-	if (!(tmpdir = maketmpfile(len, dos, NULL, NULL))) {
+	size = realdirsiz(fnamelist[top], fat, boundary, dirsize, namofs);
+	len = getnamlen(size, fat, boundary, dirsize, namofs);
+	if (!(tmpdir = maketmpfile(len, fat, NULL, NULL))) {
 		warning(0, NOWRT_K);
 		freevar(fnamelist);
+#ifndef	PATHNOCASE
+		pathignorecase = duppathignorecase;
+#endif
 		noconv--;
 		return;
 	}
@@ -1788,6 +1813,9 @@
 
 	if (!(dirp = Xopendir(curpath))) {
 		freevar(fnamelist);
+#ifndef	PATHNOCASE
+		pathignorecase = duppathignorecase;
+#endif
 		noconv--;
 		lostcwd(path);
 		return;
@@ -1795,12 +1823,13 @@
 	i = ent = 0;
 	while ((dp = Xreaddir(dirp))) {
 		if (isdotdir(dp -> d_name)) continue;
-		else if (!strpathcmp(dp -> d_name, tmpdir)) {
+		else if (!strpathcmp2(dp -> d_name, tmpdir)) {
 #if	MSDOS
 			if (!(dp -> d_alias[0])) len = DOSBODYLEN;
 #else	/* !MSDOS */
 # ifndef	_NODOSDRIVE
-			if (dos == 3 && wrap_reclen(dp) == DOSDIRENT)
+			if (fat == FAT_DOSDRIVE
+			&& wrap_reclen(dp) == DOSDIRENT)
 				len = DOSBODYLEN;
 # endif
 #endif	/* !MSDOS */
@@ -1813,6 +1842,9 @@
 				warning(-1, dp -> d_name);
 				restorefile(tmpdir, path, fnamp);
 				freevar(fnamelist);
+#ifndef	PATHNOCASE
+				pathignorecase = duppathignorecase;
+#endif
 				noconv--;
 				return;
 			}
@@ -1822,10 +1854,13 @@
 	Xclosedir(dirp);
 
 	if (ent > 0) {
-		if (!(tmp = maketmpfile(len, dos, tmpdir, tmpdir))) {
+		if (!(tmp = maketmpfile(len, fat, tmpdir, tmpdir))) {
 			warning(-1, tmpdir);
 			restorefile(tmpdir, path, fnamp);
 			freevar(fnamelist);
+#ifndef	PATHNOCASE
+			pathignorecase = duppathignorecase;
+#endif
 			noconv--;
 			return;
 		}
@@ -1840,13 +1875,16 @@
 		warning(-1, curpath);
 		restorefile(tmpdir, path, fnamp);
 		freevar(fnamelist);
+#ifndef	PATHNOCASE
+		pathignorecase = duppathignorecase;
+#endif
 		noconv--;
 		return;
 	}
 	totalent = headbyte
-		+ realdirsiz(tmpdir, dos, boundary, dirsize, namofs)
-		+ realdirsiz(curpath, dos, boundary, dirsize, namofs)
-		+ realdirsiz(parentpath, dos, boundary, dirsize, namofs);
+		+ realdirsiz(tmpdir, fat, boundary, dirsize, namofs)
+		+ realdirsiz(curpath, fat, boundary, dirsize, namofs)
+		+ realdirsiz(parentpath, fat, boundary, dirsize, namofs);
 	block = tmpno = 0;
 	ptr = 3;
 	totalptr = 0;
@@ -1859,7 +1897,7 @@
 #if	!MSDOS
 		ent = dirblocksize - totalent;
 		size = realdirsiz(fnamelist[i],
-			dos, boundary, dirsize, namofs);
+			fat, boundary, dirsize, namofs);
 		switch (fs) {
 			case FSID_EFS:	/* IRIX File System */
 				if (totalptr > ptr + 1) ent -= totalptr;
@@ -1868,17 +1906,18 @@
 			case FSID_SYSV:	/* SystemV R3 File System */
 			case FSID_FAT:	/* MS-DOS File System */
 			case FSID_LFN:	/* Windows95 File System */
+			case FSID_VFAT:	/* Linux File System for Windows */
 				ent = size;
 				break;
 			default:
 				break;
 		}
 		if (ent < size) {
-			n = getnamlen(ent, dos, boundary, dirsize, namofs);
+			n = getnamlen(ent, fat, boundary, dirsize, namofs);
 			if (n > 0) {
 				tmpfiles = b_realloc(tmpfiles, tmpno, char *);
 				tmpfiles[tmpno++] =
-					maketmpfile(n, dos, tmpdir, NULL);
+					maketmpfile(n, fat, tmpdir, NULL);
 			}
 			ptr = 0;
 			totalent = headbyte;
@@ -1906,7 +1945,7 @@
 	}
 #endif
 
-	if (!(tmp = maketmpfile(len, dos, tmpdir, tmpdir)))
+	if (!(tmp = maketmpfile(len, fat, tmpdir, tmpdir)))
 		warning(-1, tmpdir);
 	else {
 		free(tmpdir);
@@ -1918,6 +1957,9 @@
 	restorefile(tmpdir, path, fnamp);
 
 	freevar(fnamelist);
+#ifndef	PATHNOCASE
+	pathignorecase = duppathignorecase;
+#endif
 	noconv--;
 }
 #endif	/* !_NOWRITEFS */
diff -u ../old/FD-2.09h/info.c ./info.c
--- ../old/FD-2.09h/info.c	Sat Mar 15 00:00:00 2008
+++ ./info.c	Thu Apr 10 21:48:02 2008
@@ -302,6 +302,9 @@
 #ifndef	MNTTYPE_MSDOS
 #define	MNTTYPE_MSDOS	"msdos"	/* msdosfs */
 #endif
+#ifndef	MNTTYPE_MSDOSFS
+#define	MNTTYPE_MSDOSFS	"msdosfs"	/* msdosfs */
+#endif
 #ifndef	MNTTYPE_UMSDOS
 #define	MNTTYPE_UMSDOS	"umsdos"	/* umsdosfs */
 #endif
@@ -385,8 +388,9 @@
 # else
 	{FSID_LFN, MNTTYPE_MSDOS},
 # endif
+	{FSID_LFN, MNTTYPE_MSDOSFS},
 	{FSID_LFN, MNTTYPE_UMSDOS},
-	{FSID_LFN, MNTTYPE_VFAT},
+	{FSID_VFAT, MNTTYPE_VFAT},
 	{0, MNTTYPE_ADVFS},
 	{0, MNTTYPE_VXFS},
 # ifdef	DARWIN
diff -u ../old/FD-2.09h/types.h ./types.h
--- ../old/FD-2.09h/types.h	Sat Mar 15 00:00:00 2008
+++ ./types.h	Thu Apr 10 22:31:55 2008
@@ -357,10 +357,11 @@
 #define	FSID_UFS		1
 #define	FSID_EFS		2
 #define	FSID_SYSV		3
-#define	FSID_FAT		4
-#define	FSID_LFN		5
-#define	FSID_LINUX		6
-#define	FSID_DOSDRIVE		7
+#define	FSID_LINUX		4
+#define	FSID_FAT		5
+#define	FSID_LFN		6
+#define	FSID_VFAT		7
+#define	FSID_DOSDRIVE		8
 
 #define	LCK_READ		0
 #define	LCK_WRITE		1
---- Cut Here ----

                                               しらい たかし