diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-07-21 22:01:46 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-07-21 22:01:46 +0000 |
commit | 9cd6b737c3397706b075fd3258bd11ebdf8fb880 (patch) | |
tree | 4ddfb611bacd145faef6ddf9af3ca07bec4bcdac /ext2fs | |
parent | a73f77bbccdf0d6ab30fbf897bd178b337142337 (diff) |
(diskfs_get_filemap): Drop initial reference created by pager_create.
(pager_clear_user_data): Only clear UPI->node->dn->fileinfo if it still
points to us.
Diffstat (limited to 'ext2fs')
-rw-r--r-- | ext2fs/pager.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/ext2fs/pager.c b/ext2fs/pager.c index 558c87e4..8869c652 100644 --- a/ext2fs/pager.c +++ b/ext2fs/pager.c @@ -598,7 +598,8 @@ pager_clear_user_data (struct user_pager_info *upi) if (upi->type == FILE_DATA) { spin_lock (&node_to_page_lock); - upi->node->dn->fileinfo = 0; + if (upi->node->dn->fileinfo == upi) + upi->node->dn->fileinfo = 0; spin_unlock (&node_to_page_lock); diskfs_nrele_light (upi->node); @@ -662,21 +663,31 @@ diskfs_get_filemap (struct node *node) || (S_ISLNK (node->dn_stat.st_mode))); spin_lock (&node_to_page_lock); - if (!node->dn->fileinfo) - { - upi = malloc (sizeof (struct user_pager_info)); - upi->type = FILE_DATA; - upi->node = node; - diskfs_nref_light (node); - upi->p = - pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); - node->dn->fileinfo = upi; - right = pager_get_port (node->dn->fileinfo->p); - ports_port_deref (node->dn->fileinfo->p); - } - else - /* XXX race; see ufs/pager.c here. */ - right = pager_get_port (node->dn->fileinfo->p); + do + if (!node->dn->fileinfo) + { + upi = malloc (sizeof (struct user_pager_info)); + upi->type = FILE_DATA; + upi->node = node; + diskfs_nref_light (node); + upi->p = + pager_create (upi, pager_bucket, MAY_CACHE, + MEMORY_OBJECT_COPY_DELAY); + node->dn->fileinfo = upi; + right = pager_get_port (node->dn->fileinfo->p); + ports_port_deref (node->dn->fileinfo->p); + } + else + { + /* Because NP->dn->fileinfo->p is not a real reference, + this might be nearly deallocated. If that's so, then + the port right will be null. In that case, clear here + and loop. The deallocation will complete separately. */ + right = pager_get_port (node->dn->fileinfo->p); + if (right == MACH_PORT_NULL) + node->dn->fileinfo = 0; + } + while (right == MACH_PORT_NULL); spin_unlock (&node_to_page_lock); mach_port_insert_right (mach_task_self (), right, right, |