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 | a7cb22de8543981acf8101cc70cc4b14c4742242 (patch) | |
tree | 11e445165b59a5234ac53052cd11ac181037cc88 | |
parent | 9aaa8d2a028e054848cfe1e244f6a32b4e225d09 (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); } |