summaryrefslogtreecommitdiff
path: root/ufs/hyper.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-11-10 18:27:05 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-11-10 18:27:05 +0000
commit20f64886d96b73741bc85f6437c8baae0d2333b5 (patch)
tree5bb705551a2df638c120839690b7ef57142e4e9f /ufs/hyper.c
parent83eb31308b0ad461c79c1482456534d33457d30e (diff)
(diskfs_set_hypermetadata): Copy CSUM into a page-aligned page-sized
buffer for disk write to avoid inane kernel bug.
Diffstat (limited to 'ufs/hyper.c')
-rw-r--r--ufs/hyper.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/ufs/hyper.c b/ufs/hyper.c
index 1317e8b6..9f8bd8d5 100644
--- a/ufs/hyper.c
+++ b/ufs/hyper.c
@@ -112,13 +112,31 @@ get_hypermetadata (void)
void
diskfs_set_hypermetadata (int wait, int clean)
{
+ vm_address_t buf;
+ vm_size_t bufsize;
+ error_t err;
+
spin_lock (&alloclock);
- if (csum_dirty)
- (wait ? dev_write_sync : dev_write) (fsbtodb (sblock, sblock->fs_csaddr),
- (vm_address_t) csum,
- fragroundup (sblock,
- sblock->fs_cssize));
- csum_dirty = 0;
+
+ if (!csum_dirty)
+ {
+ spin_unlock (&alloclock);
+ return;
+ }
+
+ /* Copy into a page-aligned buffer to avoid bugs in kernel device code. */
+
+ bufsize = round_page (fragroundup (sblock, sblock->fs_cssize));
+
+ err = dev_read_sync (fsbtodb (sblock, sblock->fs_csaddr), &buf, bufsize);
+ if (!err)
+ {
+ bcopy (csum, (void *) buf, sblock->fs_cssize);
+ (wait ? dev_write_sync : dev_write) (fsbtodb (sblock, sblock->fs_csaddr),
+ buf, bufsize);
+ csum_dirty = 0;
+ }
+
spin_unlock (&alloclock);
}