From df713149f1fc3041a8ecb846672df9610ecc90ec Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Fri, 19 Aug 2005 14:02:39 +0000 Subject: [PATCH] Convert to vop_write_dirent. --- sys/vfs/msdosfs/direntry.h | 4 +- sys/vfs/msdosfs/msdosfs_conv.c | 16 +++---- sys/vfs/msdosfs/msdosfs_vnops.c | 99 +++++++++++++++++++---------------------- 3 files changed, 57 insertions(+), 62 deletions(-) diff --git a/sys/vfs/msdosfs/direntry.h b/sys/vfs/msdosfs/direntry.h index 62c9e2ce0f..c26b88bddf 100644 --- a/sys/vfs/msdosfs/direntry.h +++ b/sys/vfs/msdosfs/direntry.h @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/direntry.h,v 1.15 1999/12/29 04:54:52 peter Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/direntry.h,v 1.3 2003/08/20 09:56:32 rob Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/direntry.h,v 1.4 2005/08/19 14:02:39 joerg Exp $ */ /* $NetBSD: direntry.h,v 1.14 1997/11/17 15:36:32 ws Exp $ */ /*- @@ -137,7 +137,7 @@ int dos2unixfn (u_char dn[11], u_char *un, int lower, int d2u_loaded, u_int8_t * int unix2dosfn (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 (const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int table_loaded, u_int16_t *u2w); int winChkName (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); -int win2unixfn (struct winentry *wep, struct dirent *dp, int chksum, int table_loaded, u_int16_t *u2w); +int win2unixfn (struct winentry *wep, char *d_name, uint16_t *d_namlen, int chksum, int table_loaded, u_int16_t *u2w); u_int8_t winChksum (u_int8_t *name); int winSlotCnt (const u_char *un, int unlen); int winLenFixup (const u_char *un, int unlen); diff --git a/sys/vfs/msdosfs/msdosfs_conv.c b/sys/vfs/msdosfs/msdosfs_conv.c index 29daaf03ca..4471e5d58b 100644 --- a/sys/vfs/msdosfs/msdosfs_conv.c +++ b/sys/vfs/msdosfs/msdosfs_conv.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_conv.c,v 1.29.2.1 2002/11/08 22:01:22 semenu Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_conv.c,v 1.5 2004/04/17 00:30:17 cpressey Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_conv.c,v 1.6 2005/08/19 14:02:39 joerg Exp $ */ /* $NetBSD: msdosfs_conv.c,v 1.25 1997/11/17 15:36:40 ws Exp $ */ /*- @@ -834,11 +834,11 @@ winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum, * Returns the checksum or -1 if impossible */ int -win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded, +win2unixfn(struct winentry *wep, char *d_name, uint16_t *d_namlen, int chksum, int table_loaded, u_int16_t *u2w) { u_int8_t *cp; - u_int8_t *np, *ep = dp->d_name + WIN_MAXLEN; + u_int8_t *np, *ep = d_name + WIN_MAXLEN; u_int16_t code; int i; @@ -854,7 +854,7 @@ win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded /* * This works even though d_namlen is one byte! */ - dp->d_namlen = (wep->weCnt&WIN_CNT) * WIN_CHARS; + *d_namlen = (wep->weCnt&WIN_CNT) * WIN_CHARS; } else if (chksum != wep->weChksum) chksum = -1; if (chksum == -1) @@ -864,7 +864,7 @@ win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded * Offset of this entry */ i = ((wep->weCnt&WIN_CNT) - 1) * WIN_CHARS; - np = (u_int8_t *)dp->d_name + i; + np = (u_int8_t *)d_name + i; /* * Convert the name parts @@ -874,7 +874,7 @@ win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded switch (code) { case 0: *np = '\0'; - dp->d_namlen -= sizeof(wep->wePart2)/2 + *d_namlen -= sizeof(wep->wePart2)/2 + sizeof(wep->wePart3)/2 + i + 1; return chksum; case '/': @@ -906,7 +906,7 @@ win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded switch (code) { case 0: *np = '\0'; - dp->d_namlen -= sizeof(wep->wePart3)/2 + i + 1; + *d_namlen -= sizeof(wep->wePart3)/2 + i + 1; return chksum; case '/': *np = '\0'; @@ -937,7 +937,7 @@ win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int table_loaded switch (code) { case 0: *np = '\0'; - dp->d_namlen -= i + 1; + *d_namlen -= i + 1; return chksum; case '/': *np = '\0'; diff --git a/sys/vfs/msdosfs/msdosfs_vnops.c b/sys/vfs/msdosfs/msdosfs_vnops.c index d74ca1284d..7471644a61 100644 --- a/sys/vfs/msdosfs/msdosfs_vnops.c +++ b/sys/vfs/msdosfs/msdosfs_vnops.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_vnops.c,v 1.95.2.4 2003/06/13 15:05:47 trhodes Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.24 2005/04/15 19:08:19 dillon Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.25 2005/08/19 14:02:39 joerg Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ /*- @@ -1523,7 +1523,6 @@ msdosfs_readdir(struct vop_readdir_args *ap) int blsize; long on; u_long cn; - u_long fileno; u_long dirsperblk; long bias = 0; daddr_t bn, lbn; @@ -1531,12 +1530,16 @@ msdosfs_readdir(struct vop_readdir_args *ap) struct denode *dep = VTODE(ap->a_vp); struct msdosfsmount *pmp = dep->de_pmp; struct direntry *dentp; - struct dirent dirbuf; struct uio *uio = ap->a_uio; u_long *cookies = NULL; int ncookies = 0; off_t offset, off; int chksum = -1; + ino_t d_ino; + uint16_t d_namlen; + uint8_t d_type; + char *d_name_storage = NULL; + char *d_name; #ifdef MSDOSFS_DEBUG printf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n", @@ -1553,11 +1556,6 @@ msdosfs_readdir(struct vop_readdir_args *ap) return (ENOTDIR); /* - * To be safe, initialize dirbuf - */ - bzero(dirbuf.d_name, sizeof(dirbuf.d_name)); - - /* * If the user buffer is smaller than the size of one dos directory * entry or the file offset is not a multiple of the size of a * directory entry, then we fail the read. @@ -1592,30 +1590,25 @@ msdosfs_readdir(struct vop_readdir_args *ap) #endif bias = 2 * sizeof(struct direntry); if (offset < bias) { - for (n = (int)offset / sizeof(struct direntry); - n < 2; n++) { + for (n = (int)offset / sizeof(struct direntry); n < 2; + n++) { if (FAT32(pmp)) - dirbuf.d_fileno = cntobn(pmp, - pmp->pm_rootdirblk) - * dirsperblk; + d_ino = cntobn(pmp, pmp->pm_rootdirblk) + * dirsperblk; else - dirbuf.d_fileno = 1; - dirbuf.d_type = DT_DIR; - switch (n) { - case 0: - dirbuf.d_namlen = 1; - strcpy(dirbuf.d_name, "."); - break; - case 1: - dirbuf.d_namlen = 2; - strcpy(dirbuf.d_name, ".."); + d_ino = 1; + d_type = DT_DIR; + if (n == 0) { + d_namlen = 1; + d_name = "."; + } else /* if (n == 1) */{ + d_namlen = 2; + d_name = ".."; break; } - dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf); - if (uio->uio_resid < dirbuf.d_reclen) + if (vop_write_dirent(&error, uio, d_ino, d_type, + d_namlen, d_name)) goto out; - error = uiomove((caddr_t) &dirbuf, - dirbuf.d_reclen, uio); if (error) goto out; offset += sizeof(struct direntry); @@ -1629,7 +1622,9 @@ msdosfs_readdir(struct vop_readdir_args *ap) } } + d_name_storage = malloc(WIN_MAXLEN, M_TEMP, M_WAITOK); off = offset; + while (uio->uio_resid > 0) { lbn = de_cluster(pmp, offset - bias); on = (offset - bias) & pmp->pm_crbomask; @@ -1644,6 +1639,7 @@ msdosfs_readdir(struct vop_readdir_args *ap) error = bread(pmp->pm_devvp, bn, blsize, &bp); if (error) { brelse(bp); + free(d_name_storage, M_TEMP); return (error); } n = min(n, blsize - bp->b_resid); @@ -1659,6 +1655,7 @@ msdosfs_readdir(struct vop_readdir_args *ap) printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n", dentp, prev, crnt, dentp->deName[0], dentp->deAttributes); #endif + d_name = d_name_storage; /* * If this is an unused entry, we can stop. */ @@ -1681,7 +1678,7 @@ msdosfs_readdir(struct vop_readdir_args *ap) if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) continue; chksum = win2unixfn((struct winentry *)dentp, - &dirbuf, chksum, + d_name, &d_namlen, chksum, pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2w); continue; @@ -1695,33 +1692,30 @@ msdosfs_readdir(struct vop_readdir_args *ap) continue; } /* - * This computation of d_fileno must match + * This computation of d_ino must match * the computation of va_fileid in * msdosfs_getattr. */ if (dentp->deAttributes & ATTR_DIRECTORY) { - fileno = getushort(dentp->deStartCluster); + d_ino = getushort(dentp->deStartCluster); if (FAT32(pmp)) - fileno |= getushort(dentp->deHighClust) << 16; + d_ino |= getushort(dentp->deHighClust) << 16; /* if this is the root directory */ - if (fileno == MSDOSFSROOT) - if (FAT32(pmp)) - fileno = cntobn(pmp, - pmp->pm_rootdirblk) - * dirsperblk; - else - fileno = 1; + if (d_ino != MSDOSFSROOT) + d_ino = cntobn(pmp, d_ino) * dirsperblk; + else if (FAT32(pmp)) + d_ino = cntobn(pmp, pmp->pm_rootdirblk) + * dirsperblk; else - fileno = cntobn(pmp, fileno) * dirsperblk; - dirbuf.d_fileno = fileno; - dirbuf.d_type = DT_DIR; + d_ino = 1; + d_type = DT_DIR; } else { - dirbuf.d_fileno = offset / sizeof(struct direntry); - dirbuf.d_type = DT_REG; + d_ino = offset / sizeof(struct direntry); + d_type = DT_REG; } - if (chksum != winChksum(dentp->deName)) - dirbuf.d_namlen = dos2unixfn(dentp->deName, - (u_char *)dirbuf.d_name, + if (chksum != winChksum(dentp->deName)) { + d_namlen = dos2unixfn(dentp->deName, + (u_char *)d_name, dentp->deLowerCase | ((pmp->pm_flags & MSDOSFSMNT_SHORTNAME) ? (LCASE_BASE | LCASE_EXT) : 0), @@ -1729,20 +1723,18 @@ msdosfs_readdir(struct vop_readdir_args *ap) pmp->pm_d2u, pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_ul); - else - dirbuf.d_name[dirbuf.d_namlen] = 0; + } chksum = -1; - dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf); - if (uio->uio_resid < dirbuf.d_reclen) { + if (vop_write_dirent(&error, uio, d_ino, d_type, + d_namlen, d_name)) { brelse(bp); goto out; } - error = uiomove((caddr_t) &dirbuf, - dirbuf.d_reclen, uio); if (error) { brelse(bp); goto out; } + if (cookies) { *cookies++ = offset + sizeof(struct direntry); if (--ncookies <= 0) { @@ -1755,6 +1747,9 @@ msdosfs_readdir(struct vop_readdir_args *ap) brelse(bp); } out: + if (d_name_storage != NULL) + free(d_name_storage, M_TEMP); + /* Subtract unused cookies */ if (ap->a_ncookies) *ap->a_ncookies -= ncookies; -- 2.11.4.GIT