diff options
-rw-r--r-- | ext2fs/inode.c | 23 | ||||
-rw-r--r-- | ext2fs/pager.c | 13 | ||||
-rw-r--r-- | fatfs/fat.c | 2 | ||||
-rw-r--r-- | fatfs/inode.c | 2 | ||||
-rw-r--r-- | fatfs/pager.c | 11 | ||||
-rw-r--r-- | libdiskfs/disk-pager.c | 7 | ||||
-rw-r--r-- | libdiskfs/diskfs-pager.h | 6 |
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); \ |