Date: Tue, 20 Oct 1998 11:57:27 -0400 (EDT) From: cmascott@world.std.com To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/8383: msdosfs wipes out NT VFAT lower case flags Message-ID: <199810201557.LAA00522@europa.local>
next in thread | raw e-mail | index | archive | help
>Number: 8383 >Category: kern >Synopsis: msdosfs wipes out NT VFAT lower case flags >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Oct 20 09:00:00 PDT 1998 >Last-Modified: >Originator: Carl Mascott >Organization: >Release: FreeBSD 2.2.7-RELEASE i386 >Environment: FreeBSD europa.local 2.2.7-RELEASE FreeBSD 2.2.7-RELEASE #0: Mon Aug 24 20:48:25 EDT 1998 cmascott@europa.local:/usr/src/sys/compile/EUR980824 i386 >Description: The accompanying patch fixes the following three bugs in msdosfs: 1. When msdosfs updates an NT VFAT DOS (short name) directory entry it unconditionally clears the lower case flags (in the byte immediately following the file attributes). Thus all NT VFAT files with short names when accessed by msdosfs have their NT names converted to upper case. 2. msdosfs does not use the NT VFAT lower case flags when converting a short name from DOS to UNIX (with -l in effect). Thus files that have short lower case names on NT get upper case names on UNIX. 3. msdosfs updates access times even if the filesystem is mounted with "noatime". Problems #1 and #2 occur because msdosfs is unaware of the presence of the NT VFAT lower case flags in the directory entry. NOTE: The Windows 9x VFAT implementation does not use or recognize the NT VFAT lower case flags. Thus it would not be a good idea to modify msdosfs to use these flags when creating a short lower case filename. >How-To-Repeat: Mount an NT VFAT filesystem with -l. Copy a file with a short lower case (on NT) name. >Fix: Apply this patch. --------------------------- (cut here) ------------------------------ *** sys/msdosfs/msdosfs_vnops.c.orig Wed Jul 15 22:01:44 1998 --- sys/msdosfs/msdosfs_vnops.c Tue Oct 13 11:59:43 1998 *************** *** 200,205 **** --- 200,206 ---- ndirent.de_Attributes = (ap->a_vap->va_mode & VWRITE) ? ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY; + ndirent.de_LowerCase = 0; ndirent.de_StartCluster = 0; ndirent.de_FileSize = 0; ndirent.de_dev = pdep->de_dev; *************** *** 847,853 **** return (error); } error = uiomove(bp->b_data + on, (int) n, uio); ! if (!isadir) dep->de_flag |= DE_ACCESS; brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); --- 848,854 ---- return (error); } error = uiomove(bp->b_data + on, (int) n, uio); ! if (!isadir && !(vp->v_mount->mnt_flag & MNT_NOATIME)) dep->de_flag |= DE_ACCESS; brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); *************** *** 1715,1720 **** --- 1716,1722 ---- goto bad; ndirent.de_Attributes = ATTR_DIRECTORY; + ndirent.de_LowerCase = 0; ndirent.de_StartCluster = newcluster; ndirent.de_FileSize = 0; ndirent.de_dev = pdep->de_dev; *************** *** 2050,2055 **** --- 2052,2058 ---- dirbuf.d_namlen = dos2unixfn(dentp->deName, (u_char *)dirbuf.d_name, pmp->pm_flags & MSDOSFSMNT_SHORTNAME, + dentp->deLowerCase[0], pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_d2u, pmp->pm_flags & MSDOSFSMNT_ULTABLE, *** sys/msdosfs/direntry.h.orig Wed Jul 15 22:01:41 1998 --- sys/msdosfs/direntry.h Tue Oct 13 12:04:49 1998 *************** *** 65,71 **** #define ATTR_VOLUME 0x08 /* entry is a volume label */ #define ATTR_DIRECTORY 0x10 /* entry is a directory name */ #define ATTR_ARCHIVE 0x20 /* file is new or modified */ ! u_int8_t deReserved[1]; /* reserved */ u_int8_t deCHundredth; /* hundredth of seconds in CTime */ u_int8_t deCTime[2]; /* create time */ u_int8_t deCDate[2]; /* create date */ --- 65,73 ---- #define ATTR_VOLUME 0x08 /* entry is a volume label */ #define ATTR_DIRECTORY 0x10 /* entry is a directory name */ #define ATTR_ARCHIVE 0x20 /* file is new or modified */ ! u_int8_t deLowerCase[1]; /* NT VFAT lower case flags */ ! #define LCASE_BASE 0x08 /* filename base is lower case */ ! #define LCASE_EXT 0x10 /* filename extension is lower case */ u_int8_t deCHundredth; /* hundredth of seconds in CTime */ u_int8_t deCTime[2]; /* create time */ u_int8_t deCDate[2]; /* create date */ *************** *** 130,136 **** void unix2dostime __P((struct timespec *tsp, u_int16_t *ddp, u_int16_t *dtp, u_int8_t *dhp)); void dos2unixtime __P((u_int dd, u_int dt, u_int dh, struct timespec *tsp)); ! int dos2unixfn __P((u_char dn[11], u_char *un, int lower, int d2u_loaded, u_int8_t *d2u, int ul_loaded, u_int8_t *ul)); int unix2dosfn __P((const u_char *un, u_char dn[12], int unlen, u_int gen, int u2d_loaded, u_int8_t *u2d, int lu_loaded, u_int8_t *lu)); int unix2winfn __P((const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int table_loaded, u_int16_t *u2w)); int winChkName __P((const u_char *un, int unlen, struct winentry *wep, int chksum, int u2w_loaded, u_int16_t *u2w, int ul_loaded, u_int8_t *ul)); --- 132,138 ---- void unix2dostime __P((struct timespec *tsp, u_int16_t *ddp, u_int16_t *dtp, u_int8_t *dhp)); void dos2unixtime __P((u_int dd, u_int dt, u_int dh, struct timespec *tsp)); ! int dos2unixfn __P((u_char dn[11], u_char *un, int shortname, unsigned lcflags, int d2u_loaded, u_int8_t *d2u, int ul_loaded, u_int8_t *ul)); int unix2dosfn __P((const u_char *un, u_char dn[12], int unlen, u_int gen, int u2d_loaded, u_int8_t *u2d, int lu_loaded, u_int8_t *lu)); int unix2winfn __P((const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int table_loaded, u_int16_t *u2w)); int winChkName __P((const u_char *un, int unlen, struct winentry *wep, int chksum, int u2w_loaded, u_int16_t *u2w, int ul_loaded, u_int8_t *ul)); *** sys/msdosfs/denode.h.orig Wed Jul 15 22:01:41 1998 --- sys/msdosfs/denode.h Sun Oct 11 18:21:59 1998 *************** *** 156,161 **** --- 156,162 ---- #endif u_char de_Name[12]; /* name, from DOS directory entry */ u_char de_Attributes; /* attributes, from directory entry */ + u_char de_LowerCase; /* NT VFAT lower case flags */ u_char de_CHun; /* Hundredth of second of CTime*/ u_short de_CTime; /* creation time */ u_short de_CDate; /* creation date */ *************** *** 196,201 **** --- 197,203 ---- #define DE_INTERNALIZE(dep, dp) \ (bcopy((dp)->deName, (dep)->de_Name, 11), \ (dep)->de_Attributes = (dp)->deAttributes, \ + (dep)->de_LowerCase = (dp)->deLowerCase[0], \ (dep)->de_CHun = (dp)->deCHundredth, \ (dep)->de_CTime = getushort((dp)->deCTime), \ (dep)->de_CDate = getushort((dp)->deCDate), \ *************** *** 210,217 **** putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16) #define DE_EXTERNALIZE(dp, dep) \ (bcopy((dep)->de_Name, (dp)->deName, 11), \ ! bzero((dp)->deReserved, 10), \ (dp)->deAttributes = (dep)->de_Attributes, \ (dp)->deCHundredth = (dep)->de_CHun, \ putushort((dp)->deCTime, (dep)->de_CTime), \ putushort((dp)->deCDate, (dep)->de_CDate), \ --- 212,220 ---- putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16) #define DE_EXTERNALIZE(dp, dep) \ (bcopy((dep)->de_Name, (dp)->deName, 11), \ ! bzero((dp)->deLowerCase, 10), \ (dp)->deAttributes = (dep)->de_Attributes, \ + (dp)->deLowerCase[0] = (dep)->de_LowerCase, \ (dp)->deCHundredth = (dep)->de_CHun, \ putushort((dp)->deCTime, (dep)->de_CTime), \ putushort((dp)->deCDate, (dep)->de_CDate), \ *** sys/msdosfs/msdosfs_denode.c.orig Wed Jul 15 22:01:42 1998 --- sys/msdosfs/msdosfs_denode.c Sun Oct 11 18:13:55 1998 *************** *** 324,329 **** --- 324,330 ---- nvp->v_flag |= VROOT; /* should be further down XXX */ ldep->de_Attributes = ATTR_DIRECTORY; + ldep->de_LowerCase = 0; if (FAT32(pmp)) ldep->de_StartCluster = pmp->pm_rootdirblk; /* de_FileSize will be filled in further down */ *** sys/msdosfs/msdosfs_conv.c.orig Wed Jul 15 22:01:42 1998 --- sys/msdosfs/msdosfs_conv.c Tue Oct 13 11:57:22 1998 *************** *** 394,412 **** * null. */ int ! dos2unixfn(dn, un, lower, d2u_loaded, d2u, ul_loaded, ul) u_char dn[11]; u_char *un; ! int lower; int d2u_loaded; u_int8_t *d2u; int ul_loaded; u_int8_t *ul; { int i; int thislong = 1; u_char c; /* * If first char of the filename is SLOT_E5 (0x05), then the real * first char of the filename should be 0xe5. But, they couldn't --- 394,416 ---- * null. */ int ! dos2unixfn(dn, un, shortname, lcflags, d2u_loaded, d2u, ul_loaded, ul) u_char dn[11]; u_char *un; ! int shortname; ! unsigned lcflags; int d2u_loaded; u_int8_t *d2u; int ul_loaded; u_int8_t *ul; { int i; + int lower; int thislong = 1; u_char c; + lower = shortname || (lcflags & LCASE_BASE); + /* * If first char of the filename is SLOT_E5 (0x05), then the real * first char of the filename should be 0xe5. But, they couldn't *************** *** 440,445 **** --- 444,450 ---- * the extension. */ if (*dn != ' ') { + lower = shortname || (lcflags & LCASE_EXT); *un++ = '.'; thislong++; for (i = 0; i < 3 && *dn != ' '; i++) { --------------------------- (cut here) ------------------------------ >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199810201557.LAA00522>