summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext2fs/inode.c23
-rw-r--r--ext2fs/pager.c13
-rw-r--r--fatfs/fat.c2
-rw-r--r--fatfs/inode.c2
-rw-r--r--fatfs/pager.c11
-rw-r--r--libdiskfs/disk-pager.c7
-rw-r--r--libdiskfs/diskfs-pager.h6
7 files changed, 45 insertions, 19 deletions
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index a23baee7..dc309ac8 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -634,7 +634,10 @@ diskfs_set_translator (struct node *np, const char *name, mach_msg_type_number_t
char buf[block_size];
if (namelen + 2 > block_size)
- return ENAMETOOLONG;
+ {
+ diskfs_end_catch_exception ();
+ return ENAMETOOLONG;
+ }
di = dino_ref (np->cache_id);
blkno = le32toh (di->i_translator);
@@ -650,7 +653,10 @@ diskfs_set_translator (struct node *np, const char *name, mach_msg_type_number_t
newmode = (np->dn_stat.st_mode & ~S_IFMT) | S_IFREG;
err = diskfs_validate_mode_change (np, newmode);
if (err)
- return err;
+ {
+ diskfs_end_catch_exception ();
+ return err;
+ }
}
/* Allocate block for translator */
@@ -712,7 +718,10 @@ diskfs_set_translator (struct node *np, const char *name, mach_msg_type_number_t
}
}
else
- return EOPNOTSUPP;
+ {
+ diskfs_end_catch_exception ();
+ return EOPNOTSUPP;
+ }
diskfs_end_catch_exception ();
@@ -778,7 +787,10 @@ diskfs_get_translator (struct node *np, char **namep, mach_msg_type_number_t *na
{
err = ext2_get_xattr (np, "gnu.translator", NULL, &datalen);
if (err)
- return err;
+ {
+ diskfs_end_catch_exception ();
+ return err;
+ }
*namep = malloc (datalen);
if (!*namep)
@@ -790,6 +802,9 @@ diskfs_get_translator (struct node *np, char **namep, mach_msg_type_number_t *na
*namelen = datalen;
}
+ else
+ diskfs_end_catch_exception ();
+
return err;
}
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index b93a9edd..c55107a9 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -617,8 +617,8 @@ pager_unlock_page (struct user_pager_info *pager, vm_offset_t page)
break;
left -= block_size;
}
+ diskfs_end_catch_exception ();
}
- diskfs_end_catch_exception ();
if (partial_page)
/* If an error occurred, this page still isn't writable; otherwise,
@@ -711,12 +711,15 @@ diskfs_grow (struct node *node, off_t size, struct protid *cred)
end_block);
err = diskfs_catch_exception ();
- while (!err && end_block < writable_end)
+ if (! err)
{
- block_t disk_block;
- err = ext2_getblk (node, end_block++, 1, &disk_block);
+ while (!err && end_block < writable_end)
+ {
+ block_t disk_block;
+ err = ext2_getblk (node, end_block++, 1, &disk_block);
+ }
+ diskfs_end_catch_exception ();
}
- diskfs_end_catch_exception ();
if (! err)
/* Reflect how much we allocated successfully. */
diff --git a/fatfs/fat.c b/fatfs/fat.c
index f31ce115..e765376d 100644
--- a/fatfs/fat.c
+++ b/fatfs/fat.c
@@ -606,8 +606,8 @@ fat_get_freespace (void)
if (next_cluster == FAT_FREE_CLUSTER)
free_clusters++;
}
+ diskfs_end_catch_exception ();
}
- diskfs_end_catch_exception ();
return free_clusters;
}
diff --git a/fatfs/inode.c b/fatfs/inode.c
index c38ee0d9..cefcba47 100644
--- a/fatfs/inode.c
+++ b/fatfs/inode.c
@@ -533,8 +533,8 @@ diskfs_truncate (struct node *node, loff_t length)
{
fat_truncate_node(node, round_cluster(length) >> log2_bytes_per_cluster);
node->allocsize = round_cluster(length);
+ diskfs_end_catch_exception ();
}
- diskfs_end_catch_exception ();
node->dn_set_mtime = 1;
node->dn_set_ctime = 1;
diff --git a/fatfs/pager.c b/fatfs/pager.c
index efe02038..e2302cec 100644
--- a/fatfs/pager.c
+++ b/fatfs/pager.c
@@ -646,12 +646,15 @@ diskfs_grow (struct node *node, loff_t size, struct protid *cred)
if (new_end_cluster > end_cluster)
{
err = diskfs_catch_exception ();
- while (!err && end_cluster < new_end_cluster)
+ if (! err)
{
- cluster_t disk_cluster;
- err = fat_getcluster (node, end_cluster++, 1, &disk_cluster);
+ while (!err && end_cluster < new_end_cluster)
+ {
+ cluster_t disk_cluster;
+ err = fat_getcluster (node, end_cluster++, 1, &disk_cluster);
+ }
+ diskfs_end_catch_exception ();
}
- diskfs_end_catch_exception ();
if (err)
/* Reflect how much we allocated successfully. */
diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
index 7af0e3ba..886ce157 100644
--- a/libdiskfs/disk-pager.c
+++ b/libdiskfs/disk-pager.c
@@ -84,6 +84,7 @@ diskfs_start_disk_pager (struct user_pager_info *upi,
static void
fault_handler (int sig, long int sigcode, struct sigcontext *scp)
{
+ jmp_buf *env;
error_t err;
#ifndef NDEBUG
@@ -102,8 +103,10 @@ fault_handler (int sig, long int sigcode, struct sigcontext *scp)
}
#endif
+ env = &diskfs_exception_diu->env;
+
/* Clear the record, since the faulting thread will not. */
- diskfs_exception_diu = NULL;
+ diskfs_exception_diu = diskfs_exception_diu->next;
/* Fetch the error code from the pager. */
assert_backtrace (scp->sc_error == EKERN_MEMORY_ERROR);
@@ -111,5 +114,5 @@ fault_handler (int sig, long int sigcode, struct sigcontext *scp)
assert_backtrace (err);
/* Make `diskfault_catch' return the error code. */
- longjmp (diskfs_exception_diu->env, err);
+ longjmp (*env, err);
}
diff --git a/libdiskfs/diskfs-pager.h b/libdiskfs/diskfs-pager.h
index e8227413..f490e776 100644
--- a/libdiskfs/diskfs-pager.h
+++ b/libdiskfs/diskfs-pager.h
@@ -48,9 +48,11 @@ struct disk_image_user
struct disk_image_user *next;
};
-/* Return zero now. Return a second time with a nonzero error_t
+/* Returns zero now. Returns a second time with a nonzero error_t
if this thread faults accessing `disk_image' before calling
- `diskfs_end_catch_exception' (below). */
+ `diskfs_end_catch_exception' (below), in which case
+ diskfs_end_catch_exception should not be called and the access should be
+ avoided. */
#define diskfs_catch_exception() \
({ \
struct disk_image_user *diu = alloca (sizeof *diu); \