diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-10-04 06:34:16 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-10-04 06:34:16 +0000 |
commit | b2d95e7216075bc9e4caff1c70ba880801d770a2 (patch) | |
tree | 37d71909f6f4650ae4574cbdd09c929300a52779 | |
parent | ba3b952dd16e913bcf611881906b0a7ee0a0a41d (diff) |
Formerly sizes.c.~24~
-rw-r--r-- | ufs/sizes.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/ufs/sizes.c b/ufs/sizes.c index 8f6174af..7225a851 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -39,11 +39,12 @@ diskfs_truncate (struct node *np, { int offset; struct dinode *di = dino (np->dn->number); - int blocksfreed = 0; + volatile int blocksfreed = 0; error_t err; int i; struct iblock_spec indirs[NIADDR + 1]; - daddr_t lbn; + volatile daddr_t lbn; + struct user_pager_info *upi; if (length >= np->dn_stat.st_size) return 0; @@ -89,19 +90,26 @@ diskfs_truncate (struct node *np, immediately. (We are changing the data implicitly to zeros and doing it without the kernels immediate knowledge; this forces us to help out the kernel thusly.) */ - if (np->dn->fileinfo) + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + + if (upi) { mach_port_t obj; - pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, + pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np); mach_port_insert_right (mach_task_self (), obj, obj, MACH_MSG_TYPE_MAKE_SEND); poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (np->dn->fileinfo->p, round_page (length), + pager_flush_some (upi->p, round_page (length), np->allocsize - length, 1); + pager_unreference (upi->p); } /* Update the size on disk; fsck will finish freeing blocks if necessary @@ -118,9 +126,10 @@ diskfs_truncate (struct node *np, /* err XXX */ /* We don't support triple indirs */ - assert (indirs[0].offset == -1 - || indirs[1].offset == -1 - || indirs[2].offset == -1); + assert (indirs[3].offset == -2); + + err = diskfs_catch_exception (); + /* err XXX */ /* BSD carefully finds out how far to clear; it's vastly simpler to just clear everything after the new last block. */ @@ -252,9 +261,17 @@ diskfs_truncate (struct node *np, diskfs_end_catch_exception (); /* Now we can permit delayed copies again. */ - if (np->dn->fileinfo) - pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, - MEMORY_OBJECT_COPY_DELAY, 0); + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + if (upi) + { + pager_change_attributes (upi->p, MAY_CACHE, + MEMORY_OBJECT_COPY_DELAY, 0); + pager_unreference (upi->p); + } return err; } |