summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-02-26 06:45:46 +0000
committermsmith <msmith@FreeBSD.org>1998-02-26 06:45:46 +0000
commit4abe3410e6b7490667772d899fd8b5f41416c487 (patch)
treee46a6730f5f210b692d0353ccc3fda2be11d7531 /sys
parent15e6194107ac825d2decda9954710a2fbbbe591d (diff)
downloadFreeBSD-src-4abe3410e6b7490667772d899fd8b5f41416c487.zip
FreeBSD-src-4abe3410e6b7490667772d899fd8b5f41416c487.tar.gz
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>
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/msdosfs/direntry.h3
-rw-r--r--sys/fs/msdosfs/msdosfs_conv.c20
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c8
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c21
-rw-r--r--sys/msdosfs/direntry.h3
-rw-r--r--sys/msdosfs/msdosfs_conv.c20
-rw-r--r--sys/msdosfs/msdosfs_lookup.c8
-rw-r--r--sys/msdosfs/msdosfs_vnops.c21
8 files changed, 62 insertions, 42 deletions
diff --git a/sys/fs/msdosfs/direntry.h b/sys/fs/msdosfs/direntry.h
index 2bbf8e5..c0db68c 100644
--- a/sys/fs/msdosfs/direntry.h
+++ b/sys/fs/msdosfs/direntry.h
@@ -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 */
diff --git a/sys/fs/msdosfs/msdosfs_conv.c b/sys/fs/msdosfs/msdosfs_conv.c
index 8812a5e..ca3bdb6 100644
--- a/sys/fs/msdosfs/msdosfs_conv.c
+++ b/sys/fs/msdosfs/msdosfs_conv.c
@@ -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;
+}
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index 94b3708..54bcce1 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -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;
}
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 0226db3..8823d0d 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -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 @@ out:
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)
diff --git a/sys/msdosfs/direntry.h b/sys/msdosfs/direntry.h
index 2bbf8e5..c0db68c 100644
--- a/sys/msdosfs/direntry.h
+++ b/sys/msdosfs/direntry.h
@@ -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 */
diff --git a/sys/msdosfs/msdosfs_conv.c b/sys/msdosfs/msdosfs_conv.c
index 8812a5e..ca3bdb6 100644
--- a/sys/msdosfs/msdosfs_conv.c
+++ b/sys/msdosfs/msdosfs_conv.c
@@ -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;
+}
diff --git a/sys/msdosfs/msdosfs_lookup.c b/sys/msdosfs/msdosfs_lookup.c
index 94b3708..54bcce1 100644
--- a/sys/msdosfs/msdosfs_lookup.c
+++ b/sys/msdosfs/msdosfs_lookup.c
@@ -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;
}
diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c
index 0226db3..8823d0d 100644
--- a/sys/msdosfs/msdosfs_vnops.c
+++ b/sys/msdosfs/msdosfs_vnops.c
@@ -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 @@ out:
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)
OpenPOWER on IntegriCloud