From: millert Date: Sun, 2 Mar 1997 18:01:50 +0000 (+0000) Subject: Sync msdosfs with NetBSD sans const-ness. NetSBD log messages: X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=78b4a1c43a2451aa34b4d3b260cd534c8eac2e9e;p=openbsd Sync msdosfs with NetBSD sans const-ness. NetSBD log messages: Fix panic on mkdir. Thanks to Dave Huang for finding the bug. Fixes a bug with allowed/forbidden characters in non-W95 filenames. Don't extend directory when nothing is written to it. --- diff --git a/sys/msdosfs/denode.h b/sys/msdosfs/denode.h index bfa46e5ee65..a845705f8cb 100644 --- a/sys/msdosfs/denode.h +++ b/sys/msdosfs/denode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: denode.h,v 1.3 1996/02/29 10:46:45 niklas Exp $ */ +/* $OpenBSD: denode.h,v 1.4 1997/03/02 18:01:50 millert Exp $ */ /* $NetBSD: denode.h,v 1.20 1996/02/09 19:13:39 christos Exp $ */ /*- @@ -218,21 +218,18 @@ struct denode { #define VTODE(vp) ((struct denode *)(vp)->v_data) #define DETOV(de) ((de)->de_vnode) -#define DE_TIMES(dep) \ +#define DETIMES(dep, acc, mod, cre) \ if ((dep)->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)) { \ - if (((dep)->de_Attributes & ATTR_DIRECTORY) == 0) { \ - if ((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95 \ - || (dep)->de_flag & DE_UPDATE) { \ - unix2dostime(NULL, &(dep)->de_MDate, &(dep)->de_MTime); \ - (dep)->de_Attributes |= ATTR_ARCHIVE; \ - } \ - if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \ - if ((dep)->de_flag & DE_ACCESS) \ - unix2dostime(NULL, &(dep)->de_ADate, &(dep)->de_ATime); \ - if ((dep)->de_flag & DE_CREATE) \ - unix2dostime(NULL, &(dep)->de_CDate, &(dep)->de_CTime); \ - } \ - (dep)->de_flag |= DE_MODIFIED; \ + (dep)->de_flag |= DE_MODIFIED; \ + if ((dep)->de_flag & DE_UPDATE) { \ + unix2dostime((mod), &(dep)->de_MDate, &(dep)->de_MTime); \ + (dep)->de_Attributes |= ATTR_ARCHIVE; \ + } \ + if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \ + if ((dep)->de_flag & DE_ACCESS) \ + unix2dostime((acc), &(dep)->de_ADate, &(dep)->de_ATime); \ + if ((dep)->de_flag & DE_CREATE) \ + unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime); \ } \ (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \ } @@ -295,6 +292,7 @@ int msdosfs_islocked __P((void *)); int msdosfs_advlock __P((void *)); int msdosfs_reallocblks __P((void *)); int msdosfs_pathconf __P((void *)); +int msdosfs_update __P((void *)); /* * Internal service routine prototypes. diff --git a/sys/msdosfs/msdosfs_conv.c b/sys/msdosfs/msdosfs_conv.c index aa617c2baed..e31202b583f 100644 --- a/sys/msdosfs/msdosfs_conv.c +++ b/sys/msdosfs/msdosfs_conv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msdosfs_conv.c,v 1.5 1996/03/02 00:54:54 niklas Exp $ */ +/* $OpenBSD: msdosfs_conv.c,v 1.6 1997/03/02 18:01:53 millert Exp $ */ /* $NetBSD: msdosfs_conv.c,v 1.17 1996/02/09 19:13:42 christos Exp $ */ /*- @@ -105,15 +105,6 @@ unix2dostime(tsp, ddp, dtp) u_long year; u_long month; u_short *months; - struct timespec ts; - - /* - * NULL means to read the current time. - */ - if (tsp == NULL) { - TIMEVAL_TO_TIMESPEC(&time, &ts); - tsp = &ts; - } /* * If the time from the last conversion is the same as now, then @@ -217,10 +208,8 @@ dos2unixtime(dd, dt, tsp) */ month = (dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT; if (month == 0) { -#if 0 printf("dos2unixtime(): month value out of range (%ld)\n", - month); -#endif + month); month = 1; } for (m = 0; m < month - 1; m++) @@ -239,14 +228,14 @@ unix2dos[256] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 08-0f */ 0, 0, 0, 0, 0, 0, 0, 0, /* 10-17 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 18-1f */ - 0, 0x21, 0, 0x23, 0x24, 0x25, 0x26, 0, /* 20-27 */ - 0x28, 0x29, 0, 0, 0x2c, 0x2d, 0, 0, /* 28-2f */ + 0, 0x21, 0, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */ + 0x28, 0x29, 0, 0, 0, 0x2d, 0, 0, /* 28-2f */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */ - 0x38, 0x39, 0, 0x3b, 0, 0, 0, 0, /* 38-3f */ + 0x38, 0x39, 0, 0, 0, 0, 0, 0, /* 38-3f */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 40-47 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 48-4f */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 50-57 */ - 0x58, 0x59, 0x5a, 0, 0, 0, 0, 0x5f, /* 58-5f */ + 0x58, 0x59, 0x5a, 0, 0, 0, 0x5e, 0x5f, /* 58-5f */ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 60-67 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 68-6f */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 70-77 */ diff --git a/sys/msdosfs/msdosfs_denode.c b/sys/msdosfs/msdosfs_denode.c index 555285dd9c4..f0d33a33de0 100644 --- a/sys/msdosfs/msdosfs_denode.c +++ b/sys/msdosfs/msdosfs_denode.c @@ -1,5 +1,5 @@ -/* $OpenBSD: msdosfs_denode.c,v 1.3 1996/02/29 10:46:51 niklas Exp $ */ -/* $NetBSD: msdosfs_denode.c,v 1.19 1996/02/09 19:13:43 christos Exp $ */ +/* $OpenBSD: msdosfs_denode.c,v 1.4 1997/03/02 18:01:54 millert Exp $ */ +/* $NetBSD: msdosfs_denode.c,v 1.22 1996/10/13 04:16:31 christos Exp $ */ /*- * Copyright (C) 1994, 1995 Wolfgang Solfrank. @@ -169,7 +169,7 @@ deget(pmp, dirclust, diroffset, depp) #ifdef MSDOSFS_DEBUG printf("deget(pmp %08x, dirclust %d, diroffset %x, depp %08x)\n", - pmp, dirclust, diroffset, depp); + pmp, dirclust, diroffset, depp); #endif /* @@ -296,61 +296,10 @@ deupdat(dep, waitfor) struct denode *dep; int waitfor; { - int error; - struct buf *bp; - struct direntry *dirp; - struct vnode *vp = DETOV(dep); - -#ifdef MSDOSFS_DEBUG - printf("deupdat(): dep %08x\n", dep); -#endif - - /* If the time stamp needs updating, do it now. */ - DE_TIMES(dep); - - /* - * If the modified bit is off, or this denode is from a readonly - * filesystem, or the denode represents an open but unlinked file - * then don't do anything. DOS directory entries that describe a - * directory do not ever get updated. This is the way dos treats - * them. - */ - if ((dep->de_flag & DE_MODIFIED) == 0) - return (0); - - dep->de_flag &= ~DE_MODIFIED; - - if (dep->de_Attributes & ATTR_DIRECTORY) - panic("deupdat: directory"); + struct timespec ts; - if (vp->v_mount->mnt_flag & MNT_RDONLY || - dep->de_refcnt <= 0) - return (0); - - /* - * Read in the cluster containing the directory entry we want to - * update. - */ - if ((error = readde(dep, &bp, &dirp)) != 0) - return (error); - - /* - * Copy the directory entry out of the denode into the cluster it - * came from. - */ - DE_EXTERNALIZE(dirp, dep); - - /* - * Write the cluster back to disk. If they asked for us to wait - * for the write to complete, then use bwrite() otherwise use - * bdwrite(). - */ - error = 0; /* note that error is 0 from above, but ... */ - if (waitfor) - error = bwrite(bp); - else - bdwrite(bp); - return (error); + TIMEVAL_TO_TIMESPEC(&time, &ts); + return (VOP_UPDATE(DETOV(dep), &ts, &ts, waitfor)); } /* diff --git a/sys/msdosfs/msdosfs_fat.c b/sys/msdosfs/msdosfs_fat.c index cae9ea9ae2b..fe044d1a6e3 100644 --- a/sys/msdosfs/msdosfs_fat.c +++ b/sys/msdosfs/msdosfs_fat.c @@ -1,5 +1,5 @@ -/* $OpenBSD: msdosfs_fat.c,v 1.3 1996/02/29 10:46:53 niklas Exp $ */ -/* $NetBSD: msdosfs_fat.c,v 1.22 1996/02/09 19:13:45 christos Exp $ */ +/* $OpenBSD: msdosfs_fat.c,v 1.4 1997/03/02 18:01:56 millert Exp $ */ +/* $NetBSD: msdosfs_fat.c,v 1.24 1996/10/13 04:16:32 christos Exp $ */ /*- * Copyright (C) 1994, 1995 Wolfgang Solfrank. @@ -333,8 +333,8 @@ updatefats(pmp, bp, fatbn) struct buf *bpn; #ifdef MSDOSFS_DEBUG - printf("updatefats(pmp %08x, bp %08x, fatbn %d)\n", - pmp, bp, fatbn); + printf("fatentry(func %d, pmp %08x, clust %d, oldcon %08x, newcon %d)\n", + function, pmp, cluster, oldcontents, newcontents); #endif /* @@ -460,10 +460,10 @@ fatentry(function, pmp, cn, oldcontents, newcontents) u_long bn, bo, bsize, byteoffset; struct buf *bp; - /* - * printf("fatentry(func %d, pmp %08x, clust %d, oldcon %08x, newcon %d)\n", - * function, pmp, cluster, oldcontents, newcontents); - */ +#if 0 + printf("fatentry(func %d, pmp %08x, clust %d, oldcon %08x, newcon %d)\n", + function, pmp, cluster, oldcontents, newcontents); +#endif #ifdef DIAGNOSTIC /* @@ -552,7 +552,7 @@ fatchain(pmp, start, count, fillwith) #ifdef MSDOSFS_DEBUG printf("fatchain(pmp %08x, start %d, count %d, fillwith %d)\n", - pmp, start, count, fillwith); + pmp, start, count, fillwith); #endif /* * Be sure the clusters are in the filesystem. @@ -664,7 +664,7 @@ chainalloc(pmp, start, count, fillwith, retcluster, got) return (error); #ifdef MSDOSFS_DEBUG printf("clusteralloc(): allocated cluster chain at %d (%d clusters)\n", - start, count); + start, count); #endif if (retcluster) *retcluster = start; diff --git a/sys/msdosfs/msdosfs_lookup.c b/sys/msdosfs/msdosfs_lookup.c index 63fb02a6353..58e4aa8edb7 100644 --- a/sys/msdosfs/msdosfs_lookup.c +++ b/sys/msdosfs/msdosfs_lookup.c @@ -1,5 +1,5 @@ -/* $OpenBSD: msdosfs_lookup.c,v 1.4 1996/04/19 16:10:00 niklas Exp $ */ -/* $NetBSD: msdosfs_lookup.c,v 1.26 1996/03/07 13:30:46 ws Exp $ */ +/* $OpenBSD: msdosfs_lookup.c,v 1.5 1997/03/02 18:01:57 millert Exp $ */ +/* $NetBSD: msdosfs_lookup.c,v 1.30 1996/10/25 23:14:08 cgd Exp $ */ /*- * Copyright (C) 1994, 1995 Wolfgang Solfrank. @@ -125,7 +125,7 @@ msdosfs_lookup(v) wantparent = flags & (LOCKPARENT | WANTPARENT); #ifdef MSDOSFS_DEBUG printf("msdosfs_lookup(): vdp %08x, dp %08x, Attr %02x\n", - vdp, dp, dp->de_Attributes); + vdp, dp, dp->de_Attributes); #endif /* @@ -178,7 +178,7 @@ msdosfs_lookup(v) if (vpid == vdp->v_id) { #ifdef MSDOSFS_DEBUG printf("msdosfs_lookup(): cache hit, vnode %08x, file %s\n", - vdp, dp->de_Name); + vdp, dp->de_Name); #endif return (0); } @@ -217,11 +217,11 @@ msdosfs_lookup(v) case 1: break; case 2: - wincnt = winSlotCnt((u_char *)cnp->cn_nameptr,cnp->cn_namelen) + 1; + wincnt = winSlotCnt((u_char *)cnp->cn_nameptr, cnp->cn_namelen) + 1; break; case 3: olddos = 0; - wincnt = winSlotCnt((u_char *)cnp->cn_nameptr,cnp->cn_namelen) + 1; + wincnt = winSlotCnt((u_char *)cnp->cn_nameptr, cnp->cn_namelen) + 1; break; } if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) @@ -240,7 +240,7 @@ msdosfs_lookup(v) #ifdef MSDOSFS_DEBUG printf("msdosfs_lookup(): dos version of filename %s, length %d\n", - dosfilename, cnp->cn_namelen); + dosfilename, cnp->cn_namelen); #endif /* * Search the directory pointed at by vdp for the name pointed at @@ -335,7 +335,7 @@ msdosfs_lookup(v) } #ifdef MSDOSFS_DEBUG printf("msdosfs_lookup(): match blkoff %d, diroff %d\n", - blkoff, diroff); + blkoff, diroff); #endif /* * Remember where this directory @@ -379,9 +379,9 @@ notfound:; */ #ifdef MSDOSFS_DEBUG printf("msdosfs_lookup(): op %d, refcnt %d\n", - nameiop, dp->de_refcnt); + nameiop, dp->de_refcnt); printf(" slotcount %d, slotoffset %d\n", - slotcount, slotoffset); + slotcount, slotoffset); #endif if ((nameiop == CREATE || nameiop == RENAME) && (flags & ISLASTCN) && dp->de_refcnt != 0) { @@ -591,7 +591,7 @@ createde(dep, ddep, depp, cnp) #ifdef MSDOSFS_DEBUG printf("createde(dep %08x, ddep %08x, depp %08x, cnp %08x)\n", - dep, ddep, depp, cnp); + dep, ddep, depp, cnp); #endif /* @@ -606,8 +606,11 @@ createde(dep, ddep, depp, cnp) diroffset = ddep->de_fndoffset + sizeof(struct direntry) - ddep->de_FileSize; dirclust = de_clcount(pmp, diroffset); - if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR)) != 0) + if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR)) != 0) { + (void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED, NULL); return error; + } + /* * Update the size of the directory */ @@ -749,7 +752,7 @@ dosdirempty(dep) brelse(bp); #ifdef MSDOSFS_DEBUG printf("dosdirempty(): entry found %02x, %02x\n", - dentp->deName[0], dentp->deName[1]); + dentp->deName[0], dentp->deName[1]); #endif return (0); /* not empty */ } diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c index ef8f70647da..62423aa7e6e 100644 --- a/sys/msdosfs/msdosfs_vfsops.c +++ b/sys/msdosfs/msdosfs_vfsops.c @@ -1,5 +1,5 @@ -/* $OpenBSD: msdosfs_vfsops.c,v 1.5 1996/04/21 22:28:22 deraadt Exp $ */ -/* $NetBSD: msdosfs_vfsops.c,v 1.41 1996/03/20 00:45:40 thorpej Exp $ */ +/* $OpenBSD: msdosfs_vfsops.c,v 1.6 1997/03/02 18:01:59 millert Exp $ */ +/* $NetBSD: msdosfs_vfsops.c,v 1.44 1996/12/22 10:10:32 cgd Exp $ */ /*- * Copyright (C) 1994, 1995 Wolfgang Solfrank. diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 586ab8b5968..2bf40531c8c 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msdosfs_vnops.c,v 1.7 1996/10/24 17:56:18 tholo Exp $ */ +/* $OpenBSD: msdosfs_vnops.c,v 1.8 1997/03/02 18:02:01 millert Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.48 1996/03/20 00:45:43 thorpej Exp $ */ /*- @@ -34,17 +34,17 @@ */ /* * Written by Paul Popelka (paulp@uts.amdahl.com) - * + * * You can do anything you want with this software, just don't say you wrote * it, and don't remove this notice. - * + * * This software is provided "as is". - * + * * The author supplies this software to be publicly redistributed on the * understanding that the author is not responsible for the correct * functioning of this software in any circumstances and is not liable for * any damages caused by this software. - * + * * October 1992 */ @@ -75,7 +75,7 @@ /* * Some general notes: - * + * * In the ufs filesystem the inodes, superblocks, and indirect blocks are * read/written using the vnode for the filesystem. Blocks that represent * the contents of a file are read/written using the vnode for the file @@ -112,6 +112,7 @@ msdosfs_create(v) struct denode *dep; struct denode *pdep = VTODE(ap->a_dvp); int error; + struct timespec ts; #ifdef MSDOSFS_DEBUG printf("msdosfs_create(cnp %08x, vap %08x\n", cnp, ap->a_vap); @@ -141,7 +142,7 @@ msdosfs_create(v) bzero(&ndirent, sizeof(ndirent)); if ((error = uniqdosname(pdep, cnp, ndirent.de_Name)) != 0) goto bad; - + ndirent.de_Attributes = (ap->a_vap->va_mode & VWRITE) ? ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY; ndirent.de_StartCluster = 0; @@ -150,7 +151,8 @@ msdosfs_create(v) ndirent.de_devvp = pdep->de_devvp; ndirent.de_pmp = pdep->de_pmp; ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; - DE_TIMES(&ndirent); + TIMEVAL_TO_TIMESPEC(&time, &ts); + DETIMES(&ndirent, &ts, &ts, &ts); if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0) goto bad; if ((cnp->cn_flags & SAVESTART) == 0) @@ -175,7 +177,7 @@ msdosfs_mknod(v) struct componentname *a_cnp; struct vattr *a_vap; } */ *ap = v; - + switch (ap->a_vap->va_type) { case VDIR: return (msdosfs_mkdir((struct vop_mkdir_args *)ap)); @@ -221,9 +223,12 @@ msdosfs_close(v) } */ *ap = v; struct vnode *vp = ap->a_vp; struct denode *dep = VTODE(vp); + struct timespec ts; - if (vp->v_usecount > 1 && !(dep->de_flag & DE_LOCKED)) - DE_TIMES(dep); + if (vp->v_usecount > 1 && !(dep->de_flag & DE_LOCKED)) { + TIMEVAL_TO_TIMESPEC(&time, &ts); + DETIMES(dep, &ts, &ts, &ts); + } return (0); } @@ -240,7 +245,7 @@ msdosfs_access(v) struct denode *dep = VTODE(ap->a_vp); struct msdosfsmount *pmp = dep->de_pmp; mode_t dosmode; - + dosmode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH); if ((dep->de_Attributes & ATTR_READONLY) == 0) dosmode |= (S_IWUSR|S_IWGRP|S_IWOTH); @@ -263,8 +268,10 @@ msdosfs_getattr(v) u_int cn; struct denode *dep = VTODE(ap->a_vp); struct vattr *vap = ap->a_vap; + struct timespec ts; - DE_TIMES(dep); + TIMEVAL_TO_TIMESPEC(&time, &ts); + DETIMES(dep, &ts, &ts, &ts); vap->va_fsid = dep->de_dev; /* * The following computation of the fileid must be the same as that @@ -324,10 +331,10 @@ msdosfs_setattr(v) struct denode *dep = VTODE(ap->a_vp); struct vattr *vap = ap->a_vap; struct ucred *cred = ap->a_cred; - + #ifdef MSDOSFS_DEBUG printf("msdosfs_setattr(): vp %08x, vap %08x, cred %08x, p %08x\n", - ap->a_vp, vap, cred, ap->a_p); + ap->a_vp, vap, cred, ap->a_p); #endif if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || @@ -337,11 +344,11 @@ msdosfs_setattr(v) #ifdef MSDOSFS_DEBUG printf("msdosfs_setattr(): returning EINVAL\n"); printf(" va_type %d, va_nlink %x, va_fsid %x, va_fileid %x\n", - vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid); + vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid); printf(" va_blocksize %x, va_rdev %x, va_bytes %x, va_gen %x\n", - vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen); + vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen); printf(" va_uid %x, va_gid %x\n", - vap->va_uid, vap->va_gid); + vap->va_uid, vap->va_gid); #endif return (EINVAL); } @@ -359,7 +366,7 @@ msdosfs_setattr(v) if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { if (cred->cr_uid != dep->de_pmp->pm_uid && (error = suser(cred, &ap->a_p->p_acflag)) && - ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || + ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || (error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p)))) return (error); if (!(dep->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) @@ -511,12 +518,12 @@ msdosfs_write(v) struct denode *dep = VTODE(vp); struct msdosfsmount *pmp = dep->de_pmp; struct ucred *cred = ap->a_cred; - + #ifdef MSDOSFS_DEBUG printf("msdosfs_write(vp %08x, uio %08x, ioflag %08x, cred %08x\n", - vp, uio, ioflag, cred); + vp, uio, ioflag, cred); printf("msdosfs_write(): diroff %d, dirclust %d, startcluster %d\n", - dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster); + dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster); #endif switch (vp->v_type) { @@ -577,13 +584,13 @@ msdosfs_write(v) lastcn = dep->de_fc[FC_LASTFC].fc_frcn; } else lastcn = de_clcount(pmp, osize) - 1; - + do { if (de_cluster(pmp, uio->uio_offset) > lastcn) { error = ENOSPC; break; } - + bn = de_blk(pmp, uio->uio_offset); if ((uio->uio_offset & pmp->pm_crbomask) == 0 && (de_blk(pmp, uio->uio_offset + uio->uio_resid) > de_blk(pmp, uio->uio_offset) @@ -709,7 +716,7 @@ msdosfs_select(v) } */ *ap; #endif - return (1); /* DOS filesystems never block? */ + return (1); /* DOS filesystems never block? */ } int @@ -730,7 +737,7 @@ msdosfs_mmap(v) /* * Flush the blocks of a file to disk. - * + * * This function is worthless for vnodes that represent directories. Maybe we * could just do a sync if they try an fsync on a directory file. */ @@ -770,6 +777,52 @@ msdosfs_seek(v) return (0); } +int +msdosfs_update(v) + void *v; +{ + struct vop_update_args /* { + struct vnode *a_vp; + struct timespec *a_access; + struct timespec *a_modify; + int a_waitfor; + } */ *ap = v; + struct buf *bp; + struct direntry *dirp; + struct denode *dep; + int error; + struct timespec ts; + + if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) + return (0); + dep = VTODE(ap->a_vp); + TIMEVAL_TO_TIMESPEC(&time, &ts); + DETIMES(dep, ap->a_access, ap->a_modify, &ts); + if ((dep->de_flag & DE_MODIFIED) == 0) + return (0); + dep->de_flag &= ~DE_MODIFIED; + if (dep->de_Attributes & ATTR_DIRECTORY) + return (0); + if (dep->de_refcnt <= 0) + return (0); + error = readde(dep, &bp, &dirp); + if (error) + return (error); + DE_EXTERNALIZE(dirp, dep); + if (ap->a_waitfor) + return (bwrite(bp)); + else { + bdwrite(bp); + return (0); + } +} + +/* + * Flush the blocks of a file to disk. + * + * This function is worthless for vnodes that represent directories. Maybe we + * could just do a sync if they try an fsync on a directory file. + */ int msdosfs_remove(v) void *v; @@ -820,9 +873,9 @@ msdosfs_link(v) * Renames on files require moving the denode to a new hash queue since the * denode's location is used to compute which hash queue to put the file * in. Unless it is a rename in place. For example "mv a b". - * + * * What follows is the basic algorithm: - * + * * if (file move) { * if (dest file exists) { * remove dest file @@ -854,13 +907,13 @@ msdosfs_link(v) * clear old directory entry for moved directory * } * } - * + * * On entry: * source's parent directory is unlocked * source file or directory is unlocked * destination's parent directory is locked * destination file or directory is locked if it exists - * + * * On exit: * all denodes should be released * @@ -971,7 +1024,7 @@ abortit: * directory heirarchy above the target, as this would * orphan everything below the source directory. Also * the user must have write permission in the source so - * as to be able to change "..". We must repeat the call + * as to be able to change "..". We must repeat the call * to namei, as the parent directory is unlocked by the * call to doscheckpath(). */ @@ -1126,7 +1179,7 @@ abortit: if (newparent) VOP_UNLOCK(fdvp); } - + /* * If we moved a directory to a new parent directory, then we must * fixup the ".." entry in the moved directory. @@ -1212,6 +1265,7 @@ msdosfs_mkdir(v) struct direntry *denp; struct msdosfsmount *pmp = pdep->de_pmp; struct buf *bp; + struct timespec ts; /* * If this is the root directory and there is no space left we @@ -1232,11 +1286,10 @@ msdosfs_mkdir(v) goto bad2; bzero(&ndirent, sizeof(ndirent)); - if (!(pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { - unix2dostime(NULL, &ndirent.de_CDate, &ndirent.de_CTime); - unix2dostime(NULL, &ndirent.de_ADate, &ndirent.de_ATime); - } - unix2dostime(NULL, &ndirent.de_MDate, &ndirent.de_MTime); + ndirent.de_pmp = pmp; + ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; + TIMEVAL_TO_TIMESPEC(&time, &ts); + DETIMES(&ndirent, &ts, &ts, &ts); /* * Now fill the cluster with the "." and ".." entries. And write @@ -1277,7 +1330,7 @@ msdosfs_mkdir(v) #endif if ((error = uniqdosname(pdep, cnp, ndirent.de_Name)) != 0) goto bad; - + ndirent.de_Attributes = ATTR_DIRECTORY; ndirent.de_StartCluster = newcluster; ndirent.de_FileSize = 0; @@ -1419,10 +1472,10 @@ msdosfs_readdir(v) int ncookies; off_t offset; int chksum = -1; - + #ifdef MSDOSFS_DEBUG printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n", - ap->a_vp, uio, ap->a_cred, ap->a_eofflag); + ap->a_vp, uio, ap->a_cred, ap->a_eofflag); #endif /* @@ -1438,7 +1491,7 @@ msdosfs_readdir(v) * 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 @@ -1454,7 +1507,7 @@ msdosfs_readdir(v) cookies = ap->a_cookies; ncookies = ap->a_ncookies; - + /* * If they are reading from the root directory then, we simulate * the . and .. entries since these don't exist in the root @@ -1463,10 +1516,10 @@ msdosfs_readdir(v) * read the first entry in the root directory that lives on disk. */ if (dep->de_StartCluster == MSDOSFSROOT) { - /* - * printf("msdosfs_readdir(): going after . or .. in root dir, offset %d\n", - * offset); - */ +#if 0 + printf("msdosfs_readdir(): going after . or .. in root dir, offset %d\n", + offset); +#endif bias = 2 * sizeof(struct direntry); if (offset < bias) { for (n = (int)offset / sizeof(struct direntry); @@ -1524,10 +1577,10 @@ msdosfs_readdir(v) for (dentp = (struct direntry *)(bp->b_data + on); (char *)dentp < bp->b_data + on + n; dentp++, offset += sizeof(struct direntry)) { - /* - * printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n", - * dentp, prev, crnt, dentp->deName[0], dentp->deAttributes); - */ +#if 0 + printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n", + dentp, prev, crnt, dentp->deName[0], dentp->deAttributes); +#endif /* * If this is an unused entry, we can stop. */ @@ -1542,7 +1595,7 @@ msdosfs_readdir(v) chksum = -1; continue; } - + /* * Handle Win95 long directory entries */ @@ -1552,7 +1605,7 @@ msdosfs_readdir(v) chksum = win2unixfn((struct winentry *)dentp, &dirbuf, chksum); continue; } - + /* * Skip volume labels */ @@ -1956,7 +2009,8 @@ struct vnodeopv_entry_desc msdosfs_vnodeop_entries[] = { { &vop_pathconf_desc, msdosfs_pathconf }, /* pathconf */ { &vop_advlock_desc, msdosfs_advlock }, /* advlock */ { &vop_reallocblks_desc, msdosfs_reallocblks }, /* reallocblks */ - { &vop_bwrite_desc, vn_bwrite }, + { &vop_update_desc, msdosfs_update }, /* update */ + { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ { (struct vnodeop_desc *)NULL, (int (*) __P((void *)))NULL } }; struct vnodeopv_desc msdosfs_vnodeop_opv_desc = diff --git a/sys/msdosfs/msdosfsmount.h b/sys/msdosfs/msdosfsmount.h index 60720387479..6c3e1a76410 100644 --- a/sys/msdosfs/msdosfsmount.h +++ b/sys/msdosfs/msdosfsmount.h @@ -1,5 +1,5 @@ -/* $OpenBSD: msdosfsmount.h,v 1.4 1996/02/29 10:47:02 niklas Exp $ */ -/* $NetBSD: msdosfsmount.h,v 1.14 1996/02/09 19:13:56 christos Exp $ */ +/* $OpenBSD: msdosfsmount.h,v 1.5 1997/03/02 18:02:02 millert Exp $ */ +/* $NetBSD: msdosfsmount.h,v 1.15 1996/12/22 10:31:41 cgd Exp $ */ /*- * Copyright (C) 1994, 1995 Wolfgang Solfrank.