isofs: basic improvements

- fix for "out of extents" panic;
- return ENOENT when a file name does not exist;
- inode count sanity check upon unmount.

Change-Id: Icb97dbaf7c8aec463438f06b341defca357094b2
This commit is contained in:
David van Moolenbroek 2014-08-24 11:50:23 +00:00
parent e2dc2c8954
commit edfcb02885
4 changed files with 26 additions and 3 deletions

View file

@ -212,6 +212,7 @@ void read_inode_iso9660(struct inode *i,
/* Parse first extent. */ /* Parse first extent. */
if (dir_rec->data_length_l > 0) { if (dir_rec->data_length_l > 0) {
assert(i->extent == NULL);
i->extent = alloc_extent(); i->extent = alloc_extent();
i->extent->location = dir_rec->loc_extent_l + i->extent->location = dir_rec->loc_extent_l +
dir_rec->ext_attr_rec_length; dir_rec->ext_attr_rec_length;
@ -299,6 +300,7 @@ void read_inode_extents(struct inode *i,
(memcmp(dir_rec->file_id, extent_rec->file_id, (memcmp(dir_rec->file_id, extent_rec->file_id,
dir_rec->length_file_id) == 0)) { dir_rec->length_file_id) == 0)) {
/* Add the extent at the end of the linked list. */ /* Add the extent at the end of the linked list. */
assert(cur_extent->next == NULL);
cur_extent->next = alloc_extent(); cur_extent->next = alloc_extent();
cur_extent->next->location = dir_rec->loc_extent_l + cur_extent->next->location = dir_rec->loc_extent_l +
dir_rec->ext_attr_rec_length; dir_rec->ext_attr_rec_length;
@ -388,3 +390,15 @@ int check_dir_record(const struct iso9660_dir_record *d, size_t offset)
return OK; return OK;
} }
int check_inodes(void)
{
/* Check whether there are no more inodes in use. Called on unmount. */
int i;
for (i = 0; i < NR_INODE_RECORDS; i++)
if (inodes[i].i_count > 0)
return FALSE;
return TRUE;
}

View file

@ -60,4 +60,7 @@ void fs_unmount(void)
release_vol_pri_desc(&v_pri); /* Release the super block */ release_vol_pri_desc(&v_pri); /* Release the super block */
bdev_close(fs_dev); bdev_close(fs_dev);
if (check_inodes() == FALSE)
printf("ISOFS: unmounting with in-use inodes!\n");
} }

View file

@ -41,12 +41,16 @@ static int search_dir(
r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos); r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos);
if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) { if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) {
put_inode(dir_tmp); put_inode(dir_tmp);
return EINVAL; return ENOENT;
} }
/* Temporary fix for extent spilling */
put_inode(dir_tmp);
dir_tmp = alloc_inode();
/* End of fix */
r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos); r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos);
if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) { if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) {
put_inode(dir_tmp); put_inode(dir_tmp);
return EINVAL; return ENOENT;
} }
*numb = dir_tmp->i_stat.st_ino; *numb = dir_tmp->i_stat.st_ino;
put_inode(dir_tmp); put_inode(dir_tmp);
@ -60,7 +64,7 @@ static int search_dir(
r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos); r = read_inode(dir_tmp, ldir_ptr->extent, pos, &pos);
if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) { if ((r != OK) || (pos >= ldir_ptr->i_stat.st_size)) {
put_inode(dir_tmp); put_inode(dir_tmp);
return EINVAL; return ENOENT;
} }
if ((strcmp(dir_tmp->i_name, string) == 0) || if ((strcmp(dir_tmp->i_name, string) == 0) ||

View file

@ -28,6 +28,8 @@ void read_inode_susp(struct inode *i, const struct iso9660_dir_record *dir_rec,
int check_dir_record(const struct iso9660_dir_record *d, size_t offset); int check_dir_record(const struct iso9660_dir_record *d, size_t offset);
int check_inodes(void);
/* link.c */ /* link.c */
ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes); ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes);