Page MenuHomeFreeBSD

D21539.id61704.diff
No OneTemporary

D21539.id61704.diff

Index: sys/fs/msdosfs/msdosfs_fat.c
===================================================================
--- sys/fs/msdosfs/msdosfs_fat.c
+++ sys/fs/msdosfs/msdosfs_fat.c
@@ -1145,10 +1145,8 @@
byteoffset = FATOFS(pmp, 1);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
+ if (error)
return (error);
- }
/*
* Get the current value of the FAT entry and set/clear the relevant
@@ -1174,5 +1172,24 @@
}
/* Write out the modified FAT block synchronously. */
- return (bwrite(bp));
+ error = bwrite(bp);
+ if (error != 0) {
+ int terror;
+ /*
+ * Get the block back and discard it without write to disk.
+ *
+ * If we're now discovering that this media is readonly (the
+ * WriteProtect discovery earlier didn't discover this info) or
+ * just gone, throw away our unimportant attempt to modify the
+ * clean bit and bail higher up the stack (failing mount, or
+ * failing RO -> RW transition, at least). See PR 210316 for
+ * more context.
+ */
+ terror = getblkx(pmp->pm_devvp, bn, bsize, 0, 0, GB_UNMAPPED,
+ &bp);
+ KASSERT(terror == 0, ("getblkx: %d for just written block %lu "
+ "(handling failed write %d)\n", terror, bn, error));
+ bfinval(bp);
+ }
+ return (error);
}
Index: sys/fs/msdosfs/msdosfs_vfsops.c
===================================================================
--- sys/fs/msdosfs/msdosfs_vfsops.c
+++ sys/fs/msdosfs/msdosfs_vfsops.c
@@ -311,16 +311,28 @@
if (error)
return (error);
- pmp->pm_fmod = 1;
pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
- MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_RDONLY;
- MNT_IUNLOCK(mp);
/* Now that the volume is modifiable, mark it dirty. */
error = markvoldirty(pmp, 1);
- if (error)
+ if (error) {
+ /*
+ * If dirtying the superblock failed, restore
+ * prior R/O mode.
+ */
+ pmp->pm_flags |= MSDOSFSMNT_RONLY;
+
+ g_topology_lock();
+ (void)g_access(pmp->pm_cp, 0, -1, 0);
+ g_topology_unlock();
+
return (error);
+ }
+
+ pmp->pm_fmod = 1;
+ MNT_ILOCK(mp);
+ mp->mnt_flag &= ~MNT_RDONLY;
+ MNT_IUNLOCK(mp);
}
}
/*
@@ -701,10 +713,8 @@
if (ronly)
pmp->pm_flags |= MSDOSFSMNT_RONLY;
else {
- if ((error = markvoldirty(pmp, 1)) != 0) {
- (void)markvoldirty(pmp, 0);
+ if ((error = markvoldirty(pmp, 1)) != 0)
goto error_exit;
- }
pmp->pm_fmod = 1;
}
mp->mnt_data = pmp;
Index: sys/kern/vfs_bio.c
===================================================================
--- sys/kern/vfs_bio.c
+++ sys/kern/vfs_bio.c
@@ -2488,6 +2488,32 @@
bp->b_flags &= ~B_DEFERRED;
}
+/*
+ * bfinval:
+ *
+ * Forced invalidation of dirty buffer contents. The buffer is
+ * invalidated and released.
+ */
+void
+bfinval(struct buf *bp)
+{
+ CTR3(KTR_BUF, "bfinval(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
+ BUF_ASSERT_HELD(bp);
+
+ /*
+ * Remove from vnode's dirty list and adjust numdirtybuffers
+ * accounting.
+ */
+ bundirty(bp);
+
+ /*
+ * Fire it into the sun.
+ */
+ bp->b_flags |= B_INVAL | B_RELBUF | B_NOCACHE;
+ bp->b_flags &= ~(B_ASYNC | B_CACHE);
+ brelse(bp);
+}
+
/*
* bawrite:
*
Index: sys/sys/buf.h
===================================================================
--- sys/sys/buf.h
+++ sys/sys/buf.h
@@ -534,6 +534,7 @@
int bbarrierwrite(struct buf *);
void bdirty(struct buf *);
void bundirty(struct buf *);
+void bfinval(struct buf *);
void bufstrategy(struct bufobj *, struct buf *);
void brelse(struct buf *);
void bqrelse(struct buf *);

File Metadata

Mime Type
text/plain
Expires
Fri, Jul 31, 5:07 PM (4 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35791346
Default Alt Text
D21539.id61704.diff (3 KB)

Event Timeline