diff options
author | rodrigc <rodrigc@FreeBSD.org> | 2005-10-09 04:45:33 +0000 |
---|---|---|
committer | rodrigc <rodrigc@FreeBSD.org> | 2005-10-09 04:45:33 +0000 |
commit | 5eb4cdb70354b3c2bcd1f2fef97b15ca44ac86e9 (patch) | |
tree | 6f575af978b60fe022cc9e6bd1c23a4b126c20f5 /sys/fs | |
parent | 8e27c37e5f92718580ddd0d95093da6ed3bca34a (diff) | |
download | FreeBSD-src-5eb4cdb70354b3c2bcd1f2fef97b15ca44ac86e9.zip FreeBSD-src-5eb4cdb70354b3c2bcd1f2fef97b15ca44ac86e9.tar.gz |
- Do not hardcode the bsize to a sectorsize of 2048, even though
the UDF specification specifies a logical sectorsize of 2048.
Instead, get it from GEOM.
- When reading the UDF Anchor Volume Descriptor, use the logical
sectorsize of 2048 when calculating the offset to read from, but
use the actual sectorsize to determine how much to read.
- works with reading a DVD disk and a DVD disk image file via mdconfig
- correctly returns EINVAL if we try to mount_udf an audio CD, instead
of panicking inside GEOM when INVARIANTS is set
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/udf/udf_vfsops.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index 896f0cf..6abe549 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -314,6 +314,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { struct fileset_desc *fsd; struct file_entry *root_fentry; uint32_t sector, size, mvds_start, mvds_end; + uint32_t logical_secsize; uint32_t fsd_offset = 0; uint16_t part_num = 0, fsd_part = 0; int error = EINVAL; @@ -356,16 +357,31 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { #if 0 udfmp->im_l2d = NULL; #endif + /* + * The UDF specification defines a logical sectorsize of 2048 + * for DVD media. + */ + logical_secsize = 2048; + + if (((logical_secsize % cp->provider->sectorsize) != 0) || + (logical_secsize < cp->provider->sectorsize)) { + DROP_GIANT(); + g_topology_lock(); + g_vfs_close(cp, td); + g_topology_unlock(); + PICKUP_GIANT(); + return (EINVAL); + } - bsize = 2048; /* XXX Should probe the media for it's size */ + bsize = cp->provider->sectorsize; /* * Get the Anchor Volume Descriptor Pointer from sector 256. * XXX Should also check sector n - 256, n, and 512. */ sector = 256; - if ((error = bread(devvp, sector * btodb(bsize), bsize, NOCRED, - &bp)) != 0) + if ((error = bread(devvp, sector * btodb(logical_secsize), bsize, + NOCRED, &bp)) != 0) goto bail; if ((error = udf_checktag((struct desc_tag *)bp->b_data, TAGID_ANCHOR))) goto bail; @@ -383,8 +399,8 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { mvds_start = le32toh(avdp.main_vds_ex.loc); mvds_end = mvds_start + (le32toh(avdp.main_vds_ex.len) - 1) / bsize; for (sector = mvds_start; sector < mvds_end; sector++) { - if ((error = bread(devvp, sector * btodb(bsize), bsize, - NOCRED, &bp)) != 0) { + if ((error = bread(devvp, sector * btodb(logical_secsize), + bsize, NOCRED, &bp)) != 0) { printf("Can't read sector %d of VDS\n", sector); goto bail; } |