[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00769] Re: ext3 の dir_index & [FDclone-users:00766] のパッチ検証結果
- Subject: [FDclone-users:00769] Re: ext3 の dir_index & [FDclone-users:00766] のパッチ検証結果
- From: Takashi SHIRAI <shirai@unixusers.net>
- Date: Fri, 11 Apr 2008 00:14:18 +0900
しらいです。
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 ----
しらい たかし