diff options
Diffstat (limited to 'sys/isofs/udf/udf_subr.c')
-rw-r--r-- | sys/isofs/udf/udf_subr.c | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/sys/isofs/udf/udf_subr.c b/sys/isofs/udf/udf_subr.c index 2d05cf7b6ee..6d27148ed1e 100644 --- a/sys/isofs/udf/udf_subr.c +++ b/sys/isofs/udf/udf_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udf_subr.c,v 1.4 2006/01/15 00:04:42 pedro Exp $ */ +/* $OpenBSD: udf_subr.c,v 1.5 2006/07/05 17:57:50 pedro Exp $ */ /* * Copyright (c) 2006, Miodrag Vallat @@ -42,6 +42,8 @@ #include <isofs/udf/udf.h> #include <isofs/udf/udf_extern.h> +int udf_vat_read(struct udf_mnt *, uint32_t *); + /* * Convert a CS0 dstring to a 16-bit Unicode string. * Returns the length of the Unicode string, in unicode characters (not @@ -178,3 +180,84 @@ out: return (error); } + +/* Get a vnode for the Virtual Allocation Table (VAT) */ +int +udf_vat_get(struct udf_mnt *ump) +{ + struct vnode *vp; + struct udf_node *unp; + int error; + + error = udf_vget(ump->im_mountp, ump->part_len - 3, &vp); + if (error) + return (error); + + unp = VTON(vp); + unp->vatlen = (letoh64(unp->fentry->inf_len) - 36) >> 2; + + ump->im_vat = vp; + ump->im_flags &= ~UDF_MNT_FIND_VAT; + ump->im_flags |= UDF_MNT_USES_VAT; + + vput(vp); + + return (0); +} + +/* Look up a sector in the VAT */ +int +udf_vat_map(struct udf_mnt *ump, uint32_t *sector) +{ + /* If there's no VAT, then it's easy */ + if (!(ump->im_flags & UDF_MNT_USES_VAT)) { + *sector += ump->part_start; + return (0); + } + + /* Sanity check the given sector */ + if (*sector >= VTON(ump->im_vat)->vatlen) + return (EINVAL); + + return (udf_vat_read(ump, sector)); +} + +/* Read from the VAT */ +int +udf_vat_read(struct udf_mnt *ump, uint32_t *sector) +{ + struct udf_node *unp; + struct buf *bp; + uint8_t *data; + int error, size; + + unp = VTON(ump->im_vat); + size = 4; + + /* + * Note that we rely on the buffer cache to keep frequently accessed + * buffers around to avoid reading them from the disk all the time. + */ + error = udf_readatoffset(unp, &size, *sector << 2, &bp, &data); + if (error) { + if (bp != NULL) + brelse(bp); + + return (error); + } + + /* Make sure we read at least a whole entry */ + if (size < 4) { + if (bp != NULL) + brelse(bp); + + return (EINVAL); + } + + /* Map the sector */ + *sector = letoh32(*(uint32_t *)data) + ump->part_start; + + brelse(bp); + + return (0); +} |