diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-11-10 18:27:05 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-11-10 18:27:05 +0000 |
commit | 20f64886d96b73741bc85f6437c8baae0d2333b5 (patch) | |
tree | 5bb705551a2df638c120839690b7ef57142e4e9f | |
parent | 83eb31308b0ad461c79c1482456534d33457d30e (diff) |
(diskfs_set_hypermetadata): Copy CSUM into a page-aligned page-sized
buffer for disk write to avoid inane kernel bug.
-rw-r--r-- | ufs/hyper.c | 30 |
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); } |