Fixes for some bugs in the VFAT/FAT32 support:

- 'mv longnamedfile1 longnamedfile2' would cause longnamedfile2 to lose its
   long name.
 - Long names have trailing spaces/dots stripped for lookup as well as
   assignment.
 - A lockup when the mdsosfs was accessed from within the Linux emulator is fixed.
 - A bug whereby long filenames were recognised by Microsoft operating systems but
   not FreeBSD is fixed.

Submitted by:	Dmitrij Tejblum <dima@tejblum.dnttm.rssi.ru>
This commit is contained in:
msmith 1998-02-26 06:45:46 +00:00
parent 3a08734751
commit 4e774d7d5f
8 changed files with 62 additions and 42 deletions

View File

@ -1,4 +1,4 @@
/* $Id: direntry.h,v 1.10 1998/02/23 16:44:26 ache Exp $ */
/* $Id: direntry.h,v 1.11 1998/02/24 14:13:08 ache Exp $ */
/* $NetBSD: direntry.h,v 1.14 1997/11/17 15:36:32 ws Exp $ */
/*-
@ -137,4 +137,5 @@ int winChkName __P((const u_char *un, int unlen, struct winentry *wep, int chksu
int win2unixfn __P((struct winentry *wep, struct dirent *dp, int chksum, int table_loaded, u_int16_t *u2w));
u_int8_t winChksum __P((u_int8_t *name));
int winSlotCnt __P((const u_char *un, int unlen));
int winLenFixup __P((const u_char *un, int unlen));
#endif /* KERNEL */

View File

@ -1,4 +1,4 @@
/* $Id: msdosfs_conv.c,v 1.22 1998/02/23 16:44:27 ache Exp $ */
/* $Id: msdosfs_conv.c,v 1.23 1998/02/24 14:13:11 ache Exp $ */
/* $NetBSD: msdosfs_conv.c,v 1.25 1997/11/17 15:36:40 ws Exp $ */
/*-
@ -995,10 +995,22 @@ winSlotCnt(un, unlen)
const u_char *un;
int unlen;
{
for (un += unlen; unlen > 0; unlen--)
if (*--un != ' ' && *un != '.')
break;
unlen = winLenFixup(un, unlen);
if (unlen > WIN_MAXLEN)
return 0;
return howmany(unlen, WIN_CHARS);
}
/*
* Determine the number of bytes neccesary for Win95 names
*/
int
winLenFixup(un, unlen)
const u_char* un;
int unlen;
{
for (un += unlen; unlen > 0; unlen--)
if (*--un != ' ' && *un != '.')
break;
return unlen;
}

View File

@ -1,4 +1,4 @@
/* $Id: msdosfs_lookup.c,v 1.20 1998/02/23 16:44:30 ache Exp $ */
/* $Id: msdosfs_lookup.c,v 1.21 1998/02/24 14:13:13 ache Exp $ */
/* $NetBSD: msdosfs_lookup.c,v 1.37 1997/11/17 15:36:54 ws Exp $ */
/*-
@ -114,6 +114,7 @@ msdosfs_lookup(ap)
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
struct proc *p = cnp->cn_proc;
int unlen;
int wincnt = 1;
int chksum = -1;
@ -170,6 +171,7 @@ msdosfs_lookup(ap)
}
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
wincnt = 1;
unlen = winLenFixup(cnp->cn_nameptr, cnp->cn_namelen);
/*
* Suppress search for slots unless creating
@ -255,7 +257,7 @@ msdosfs_lookup(ap)
continue;
chksum = winChkName((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen,
unlen,
(struct winentry *)dep,
chksum,
pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
@ -292,7 +294,7 @@ msdosfs_lookup(ap)
* this lookup.
*/
dp->de_fndoffset = diroff;
dp->de_fndcnt = 0; /* unused anyway */
dp->de_fndcnt = wincnt;
goto found;
}

View File

@ -1,4 +1,4 @@
/* $Id: msdosfs_vnops.c,v 1.60 1998/02/23 16:44:36 ache Exp $ */
/* $Id: msdosfs_vnops.c,v 1.61 1998/02/24 14:13:16 ache Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */
/*-
@ -1539,8 +1539,6 @@ msdosfs_readdir(ap)
long n;
int blsize;
long on;
long lost;
long count;
u_long cn;
u_long fileno;
u_long dirsperblk;
@ -1581,13 +1579,10 @@ msdosfs_readdir(ap)
* entry or the file offset is not a multiple of the size of a
* directory entry, then we fail the read.
*/
count = uio->uio_resid & ~(sizeof(struct direntry) - 1);
offset = uio->uio_offset;
if (count < sizeof(struct direntry) ||
off = offset = uio->uio_offset;
if (uio->uio_resid < sizeof(struct direntry) ||
(offset & (sizeof(struct direntry) - 1)))
return (EINVAL);
lost = uio->uio_resid - count;
uio->uio_resid = count;
if (ap->a_ncookies) {
ncookies = uio->uio_resid / 16;
@ -1640,12 +1635,13 @@ msdosfs_readdir(ap)
dirbuf.d_reclen, uio);
if (error)
goto out;
offset += sizeof(struct direntry);
off = offset;
if (cookies) {
*cookies++ = offset;
if (--ncookies <= 0)
goto out;
}
offset += sizeof(struct direntry);
}
}
}
@ -1763,13 +1759,13 @@ msdosfs_readdir(ap)
goto out;
}
if (cookies) {
*cookies++ = off;
off = offset + sizeof(struct direntry);
*cookies++ = offset + sizeof(struct direntry);
if (--ncookies <= 0) {
brelse(bp);
goto out;
}
}
off = offset + sizeof(struct direntry);
}
brelse(bp);
}
@ -1778,8 +1774,7 @@ msdosfs_readdir(ap)
if (ap->a_ncookies)
*ap->a_ncookies -= ncookies;
uio->uio_offset = offset;
uio->uio_resid += lost;
uio->uio_offset = off;
/*
* Set the eofflag (NFS uses it)

View File

@ -1,4 +1,4 @@
/* $Id: direntry.h,v 1.10 1998/02/23 16:44:26 ache Exp $ */
/* $Id: direntry.h,v 1.11 1998/02/24 14:13:08 ache Exp $ */
/* $NetBSD: direntry.h,v 1.14 1997/11/17 15:36:32 ws Exp $ */
/*-
@ -137,4 +137,5 @@ int winChkName __P((const u_char *un, int unlen, struct winentry *wep, int chksu
int win2unixfn __P((struct winentry *wep, struct dirent *dp, int chksum, int table_loaded, u_int16_t *u2w));
u_int8_t winChksum __P((u_int8_t *name));
int winSlotCnt __P((const u_char *un, int unlen));
int winLenFixup __P((const u_char *un, int unlen));
#endif /* KERNEL */

View File

@ -1,4 +1,4 @@
/* $Id: msdosfs_conv.c,v 1.22 1998/02/23 16:44:27 ache Exp $ */
/* $Id: msdosfs_conv.c,v 1.23 1998/02/24 14:13:11 ache Exp $ */
/* $NetBSD: msdosfs_conv.c,v 1.25 1997/11/17 15:36:40 ws Exp $ */
/*-
@ -995,10 +995,22 @@ winSlotCnt(un, unlen)
const u_char *un;
int unlen;
{
for (un += unlen; unlen > 0; unlen--)
if (*--un != ' ' && *un != '.')
break;
unlen = winLenFixup(un, unlen);
if (unlen > WIN_MAXLEN)
return 0;
return howmany(unlen, WIN_CHARS);
}
/*
* Determine the number of bytes neccesary for Win95 names
*/
int
winLenFixup(un, unlen)
const u_char* un;
int unlen;
{
for (un += unlen; unlen > 0; unlen--)
if (*--un != ' ' && *un != '.')
break;
return unlen;
}

View File

@ -1,4 +1,4 @@
/* $Id: msdosfs_lookup.c,v 1.20 1998/02/23 16:44:30 ache Exp $ */
/* $Id: msdosfs_lookup.c,v 1.21 1998/02/24 14:13:13 ache Exp $ */
/* $NetBSD: msdosfs_lookup.c,v 1.37 1997/11/17 15:36:54 ws Exp $ */
/*-
@ -114,6 +114,7 @@ msdosfs_lookup(ap)
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
struct proc *p = cnp->cn_proc;
int unlen;
int wincnt = 1;
int chksum = -1;
@ -170,6 +171,7 @@ msdosfs_lookup(ap)
}
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
wincnt = 1;
unlen = winLenFixup(cnp->cn_nameptr, cnp->cn_namelen);
/*
* Suppress search for slots unless creating
@ -255,7 +257,7 @@ msdosfs_lookup(ap)
continue;
chksum = winChkName((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen,
unlen,
(struct winentry *)dep,
chksum,
pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
@ -292,7 +294,7 @@ msdosfs_lookup(ap)
* this lookup.
*/
dp->de_fndoffset = diroff;
dp->de_fndcnt = 0; /* unused anyway */
dp->de_fndcnt = wincnt;
goto found;
}

View File

@ -1,4 +1,4 @@
/* $Id: msdosfs_vnops.c,v 1.60 1998/02/23 16:44:36 ache Exp $ */
/* $Id: msdosfs_vnops.c,v 1.61 1998/02/24 14:13:16 ache Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */
/*-
@ -1539,8 +1539,6 @@ msdosfs_readdir(ap)
long n;
int blsize;
long on;
long lost;
long count;
u_long cn;
u_long fileno;
u_long dirsperblk;
@ -1581,13 +1579,10 @@ msdosfs_readdir(ap)
* entry or the file offset is not a multiple of the size of a
* directory entry, then we fail the read.
*/
count = uio->uio_resid & ~(sizeof(struct direntry) - 1);
offset = uio->uio_offset;
if (count < sizeof(struct direntry) ||
off = offset = uio->uio_offset;
if (uio->uio_resid < sizeof(struct direntry) ||
(offset & (sizeof(struct direntry) - 1)))
return (EINVAL);
lost = uio->uio_resid - count;
uio->uio_resid = count;
if (ap->a_ncookies) {
ncookies = uio->uio_resid / 16;
@ -1640,12 +1635,13 @@ msdosfs_readdir(ap)
dirbuf.d_reclen, uio);
if (error)
goto out;
offset += sizeof(struct direntry);
off = offset;
if (cookies) {
*cookies++ = offset;
if (--ncookies <= 0)
goto out;
}
offset += sizeof(struct direntry);
}
}
}
@ -1763,13 +1759,13 @@ msdosfs_readdir(ap)
goto out;
}
if (cookies) {
*cookies++ = off;
off = offset + sizeof(struct direntry);
*cookies++ = offset + sizeof(struct direntry);
if (--ncookies <= 0) {
brelse(bp);
goto out;
}
}
off = offset + sizeof(struct direntry);
}
brelse(bp);
}
@ -1778,8 +1774,7 @@ msdosfs_readdir(ap)
if (ap->a_ncookies)
*ap->a_ncookies -= ncookies;
uio->uio_offset = offset;
uio->uio_resid += lost;
uio->uio_offset = off;
/*
* Set the eofflag (NFS uses it)