Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164315255
D21539.id61704.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D21539.id61704.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D21539: buf: Add bfinval() routine to discard data
Attached
Detach File
Event Timeline
Log In to Comment