Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/msdosfs createde(): if an error occurs, make sure to mar...
details: https://anonhg.NetBSD.org/src/rev/91d525924334
branches: trunk
changeset: 483989:91d525924334
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Wed Mar 22 14:56:56 2000 +0000
description:
createde(): if an error occurs, make sure to mark all modified directory
slots as deleted - otherwise we would leave bogus slots in
diffstat:
sys/msdosfs/TODO | 4 +-
sys/msdosfs/msdosfs_lookup.c | 116 +++++++++++++++++++++++++++++++++---------
2 files changed, 92 insertions(+), 28 deletions(-)
diffs (206 lines):
diff -r a05b08a4c154 -r 91d525924334 sys/msdosfs/TODO
--- a/sys/msdosfs/TODO Wed Mar 22 14:49:32 2000 +0000
+++ b/sys/msdosfs/TODO Wed Mar 22 14:56:56 2000 +0000
@@ -1,7 +1,5 @@
-# $NetBSD: TODO,v 1.2 2000/03/20 07:30:14 jdolecek Exp $
+# $NetBSD: TODO,v 1.3 2000/03/22 14:56:56 jdolecek Exp $
-- createde(): do cleanup in an error occurs in middle of our work (especially,
- clean the recently added entries)
- support async mount (handy e.g. on slow medium when extracting lot's
of small files)
- the fat cache (see msdosfs_fat.c, denode->de_fc[]) should prolly
diff -r a05b08a4c154 -r 91d525924334 sys/msdosfs/msdosfs_lookup.c
--- a/sys/msdosfs/msdosfs_lookup.c Wed Mar 22 14:49:32 2000 +0000
+++ b/sys/msdosfs/msdosfs_lookup.c Wed Mar 22 14:56:56 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: msdosfs_lookup.c,v 1.46 2000/03/22 14:49:32 jdolecek Exp $ */
+/* $NetBSD: msdosfs_lookup.c,v 1.47 2000/03/22 14:56:56 jdolecek Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -595,13 +595,14 @@
struct denode **depp;
struct componentname *cnp;
{
- int error;
- u_long dirclust, diroffset;
+ int error, rberror;
+ u_long dirclust, clusoffset, oldlen=0;
+ u_long fndoffset, havecnt=0, wcnt=1;
struct direntry *ndep;
struct msdosfsmount *pmp = ddep->de_pmp;
struct buf *bp;
daddr_t bn;
- int blsize;
+ int blsize, i;
#ifdef MSDOSFS_DEBUG
printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n",
@@ -617,12 +618,13 @@
* case.
*/
if (ddep->de_fndoffset >= ddep->de_FileSize) {
- diroffset = ddep->de_fndoffset + sizeof(struct direntry)
+ u_long needlen = ddep->de_fndoffset + sizeof(struct direntry)
- ddep->de_FileSize;
- dirclust = de_clcount(pmp, diroffset);
+ dirclust = de_clcount(pmp, needlen);
+ oldlen = ddep->de_FileSize;
if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR)) != 0) {
(void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED, NULL);
- return error;
+ goto err_norollback;
}
/*
@@ -639,15 +641,15 @@
error = pcbmap(ddep, de_cluster(pmp, ddep->de_fndoffset),
&bn, &dirclust, &blsize);
if (error)
- return error;
- diroffset = ddep->de_fndoffset;
+ goto err_norollback;
+ clusoffset = ddep->de_fndoffset;
if (dirclust != MSDOSFSROOT)
- diroffset &= pmp->pm_crbomask;
+ clusoffset &= pmp->pm_crbomask;
if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
brelse(bp);
- return error;
+ goto err_norollback;
}
- ndep = bptoep(pmp, bp, ddep->de_fndoffset);
+ ndep = bptoep(pmp, bp, clusoffset);
DE_EXTERNALIZE(ndep, dep);
@@ -658,44 +660,52 @@
u_int8_t chksum = winChksum(ndep->deName);
const u_char *un = (const u_char *)cnp->cn_nameptr;
int unlen = cnp->cn_namelen;
- int cnt = 1;
+ u_long havecnt;
+
+ fndoffset = ddep->de_fndoffset;
+ havecnt = ddep->de_fndcnt + 1;
- while (--ddep->de_fndcnt >= 0) {
- if (!(ddep->de_fndoffset & pmp->pm_crbomask)) {
+ for(; wcnt < havecnt; wcnt++) {
+ if ((fndoffset & pmp->pm_crbomask) == 0) {
+ /* we should never get here if ddep is root
+ * directory */
+
if ((error = bwrite(bp)) != 0)
- return error;
+ goto rollback;
- ddep->de_fndoffset -= sizeof(struct direntry);
+ fndoffset -= sizeof(struct direntry);
error = pcbmap(ddep,
- de_cluster(pmp,
- ddep->de_fndoffset),
+ de_cluster(pmp, fndoffset),
&bn, 0, &blsize);
if (error)
- return error;
+ goto rollback;
error = bread(pmp->pm_devvp, bn, blsize,
NOCRED, &bp);
if (error) {
brelse(bp);
- return error;
+ goto rollback;
}
- ndep = bptoep(pmp, bp, ddep->de_fndoffset);
+ ndep = bptoep(pmp, bp,
+ fndoffset & pmp->pm_crbomask);
} else {
ndep--;
- ddep->de_fndoffset -= sizeof(struct direntry);
+ fndoffset -= sizeof(struct direntry);
}
- if (!unix2winfn(un, unlen, (struct winentry *)ndep, cnt++, chksum))
+ if (!unix2winfn(un, unlen, (struct winentry *)ndep,
+ wcnt, chksum))
break;
}
}
if ((error = bwrite(bp)) != 0)
- return error;
+ goto rollback;
/*
* If they want us to return with the denode gotten.
*/
if (depp) {
+ u_long diroffset = clusoffset;
if (dep->de_Attributes & ATTR_DIRECTORY) {
dirclust = dep->de_StartCluster;
if (FAT32(pmp) && dirclust == pmp->pm_rootdirblk)
@@ -709,6 +719,62 @@
}
return 0;
+
+ rollback:
+ /*
+ * Mark all slots modified so far as deleted. Note that we
+ * can't just call removede(), since directory is not in
+ * consistent state.
+ */
+ fndoffset = ddep->de_fndoffset;
+ rberror = pcbmap(ddep, de_cluster(pmp, fndoffset),
+ &bn, NULL, &blsize);
+ if (rberror)
+ goto err_norollback;
+ if ((rberror = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
+ brelse(bp);
+ goto err_norollback;
+ }
+ ndep = bptoep(pmp, bp, clusoffset);
+
+ havecnt = ddep->de_fndcnt + 1;
+ for(i=wcnt; i <= havecnt; i++) {
+ printf("rolling back %d\n", i);
+ /* mark entry as deleted */
+ ndep->deName[0] = SLOT_DELETED;
+
+ if ((fndoffset & pmp->pm_crbomask) == 0) {
+ /* we should never get here if ddep is root
+ * directory */
+
+ if ((rberror = bwrite(bp)) != 0)
+ goto err_norollback;
+
+ fndoffset -= sizeof(struct direntry);
+ rberror = pcbmap(ddep,
+ de_cluster(pmp, fndoffset),
+ &bn, 0, &blsize);
+ if (rberror)
+ goto err_norollback;
+
+ rberror = bread(pmp->pm_devvp, bn, blsize,
+ NOCRED, &bp);
+ if (rberror) {
+ brelse(bp);
+ goto err_norollback;
+ }
+ ndep = bptoep(pmp, bp, fndoffset);
+ } else {
+ ndep--;
+ fndoffset -= sizeof(struct direntry);
+ }
+ }
+
+ /* ignore any further error */
+ (void) bwrite(bp);
+
+ err_norollback:
+ return error;
}
/*
Home |
Main Index |
Thread Index |
Old Index