diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2006-07-05 17:57:51 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2006-07-05 17:57:51 +0000 |
commit | e8d61eff01a7c10b1ed93d666610ee8624b18b3f (patch) | |
tree | ad19737e67262f1c0033324dd93fb86b87dfce24 /sys/isofs | |
parent | 1a0e57227fae21b3378b06ad28ba1bb8f91ad365 (diff) |
Add VAT support a la UDF 1.50
Diffstat (limited to 'sys/isofs')
-rw-r--r-- | sys/isofs/udf/udf.h | 14 | ||||
-rw-r--r-- | sys/isofs/udf/udf_extern.h | 8 | ||||
-rw-r--r-- | sys/isofs/udf/udf_subr.c | 85 | ||||
-rw-r--r-- | sys/isofs/udf/udf_vfsops.c | 34 | ||||
-rw-r--r-- | sys/isofs/udf/udf_vnops.c | 4 |
5 files changed, 128 insertions, 17 deletions
diff --git a/sys/isofs/udf/udf.h b/sys/isofs/udf/udf.h index 3d42b186868..63e61d4fd1f 100644 --- a/sys/isofs/udf/udf.h +++ b/sys/isofs/udf/udf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: udf.h,v 1.4 2006/06/24 21:47:50 pedro Exp $ */ +/* $OpenBSD: udf.h,v 1.5 2006/07/05 17:57:50 pedro Exp $ */ /* * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> @@ -42,10 +42,16 @@ struct udf_node { struct lock i_lock; dev_t i_dev; ino_t hash_id; - long diroff; + union { + long diroff; + long vatlen; + } un_u; struct file_entry *fentry; }; +#define diroff un_u.diroff +#define vatlen un_u.vatlen + struct udf_mnt { int im_flags; struct mount *im_mountp; @@ -56,6 +62,7 @@ struct udf_mnt { int bmask; uint32_t part_start; uint32_t part_len; + struct vnode *im_vat; struct vnode *root_vp; struct long_ad root_icb; LIST_HEAD(udf_hash_lh, udf_node) *hashtbl; @@ -66,6 +73,9 @@ struct udf_mnt { struct udf_sparing_table *s_table; }; +#define UDF_MNT_FIND_VAT 0x01 /* Indicates a VAT must be found */ +#define UDF_MNT_USES_VAT 0x02 /* Indicates a VAT must be used */ + struct udf_dirstream { struct udf_node *node; struct udf_mnt *udfmp; diff --git a/sys/isofs/udf/udf_extern.h b/sys/isofs/udf/udf_extern.h index 6d314c533e7..72db7d4615a 100644 --- a/sys/isofs/udf/udf_extern.h +++ b/sys/isofs/udf/udf_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: udf_extern.h,v 1.3 2006/01/14 19:04:17 miod Exp $ */ +/* $OpenBSD: udf_extern.h,v 1.4 2006/07/05 17:57:50 pedro Exp $ */ /* * Written by Pedro Martelletto <pedro@openbsd.org> in February 2005. @@ -9,13 +9,15 @@ * udf_subr.c */ int udf_rawnametounicode(u_int len, char *, unicode_t *); +int udf_vat_get(struct udf_mnt *); +int udf_vat_map(struct udf_mnt *, uint32_t *); /* * udf_vfsops.c */ int udf_init(struct vfsconf *); int udf_mount(struct mount *, const char *, void *, struct nameidata *, - struct proc *); + struct proc *); int udf_unmount(struct mount *, int, struct proc *); int udf_start(struct mount *, int, struct proc *); int udf_root(struct mount *, struct vnode **); @@ -49,6 +51,8 @@ int udf_unlock(void *v); int udf_islocked(void *v); int udf_print(void *v); int udf_transname(char *, char *, int, struct udf_mnt *); +int udf_readatoffset(struct udf_node *, int *, off_t, struct buf **, + uint8_t **); /* * Memory pools. 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); +} diff --git a/sys/isofs/udf/udf_vfsops.c b/sys/isofs/udf/udf_vfsops.c index edb8f8617c3..e2e49f562ea 100644 --- a/sys/isofs/udf/udf_vfsops.c +++ b/sys/isofs/udf/udf_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udf_vfsops.c,v 1.13 2006/07/01 00:08:57 pedro Exp $ */ +/* $OpenBSD: udf_vfsops.c,v 1.14 2006/07/05 17:57:50 pedro Exp $ */ /* * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> @@ -328,13 +328,24 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p) goto bail; } + mtx_init(&udfmp->hash_mtx, IPL_NONE); + udfmp->hashtbl = hashinit(UDF_HASHTBLSIZE, M_UDFMOUNT, M_WAITOK, + &udfmp->hashsz); + + /* Get the VAT, if needed */ + if (udfmp->im_flags & UDF_MNT_FIND_VAT) { + error = udf_vat_get(udfmp); + if (error) + goto bail; + } /* * Grab the Fileset Descriptor * Thanks to Chuck McCrobie <mccrobie@cablespeed.com> for pointing * me in the right direction here. */ - sector = udfmp->part_start + fsd_offset; + sector = fsd_offset; + udf_vat_map(udfmp, §or); if ((error = RDSECTOR(devvp, sector, udfmp->bsize, &bp)) != 0) { printf("Cannot read sector %d of FSD\n", sector); goto bail; @@ -358,8 +369,9 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p) /* * Find the file entry for the root directory. */ - sector = letoh32(udfmp->root_icb.loc.lb_num) + udfmp->part_start; + sector = letoh32(udfmp->root_icb.loc.lb_num); size = letoh32(udfmp->root_icb.len); + udf_vat_map(udfmp, §or); if ((error = udf_readlblks(udfmp, sector, size, &bp)) != 0) { printf("Cannot read sector %d\n", sector); goto bail; @@ -374,15 +386,14 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p) brelse(bp); bp = NULL; - mtx_init(&udfmp->hash_mtx, IPL_NONE); - udfmp->hashtbl = hashinit(UDF_HASHTBLSIZE, M_UDFMOUNT, M_WAITOK, - &udfmp->hashsz); - devvp->v_specmountpoint = mp; return (0); bail: + if (udfmp->hashtbl != NULL) + free(udfmp->hashtbl, M_UDFMOUNT); + if (udfmp != NULL) { FREE(udfmp, M_UDFMOUNT); mp->mnt_data = NULL; @@ -522,8 +533,9 @@ udf_vget(struct mount *mp, ino_t ino, struct vnode **vpp) /* * Copy in the file entry. Per the spec, the size can only be 1 block. */ - sector = ino + udfmp->part_start; + sector = ino; devvp = udfmp->im_devvp; + udf_vat_map(udfmp, §or); if ((error = RDSECTOR(devvp, sector, udfmp->bsize, &bp)) != 0) { printf("Cannot read sector %d\n", sector); pool_put(&udf_node_pool, unode); @@ -600,6 +612,9 @@ udf_vget(struct mount *mp, ino_t ino, struct vnode **vpp) case UDF_ICB_TYPE_SYMLINK: vp->v_type = VLNK; break; + case UDF_ICB_TYPE_VAT_150: + vp->v_type = VREG; + break; } *vpp = vp; @@ -665,7 +680,8 @@ udf_checkexp(struct mount *mp, struct mbuf *nam, int *exflagsp, int udf_get_vpartmap(struct udf_mnt *udfmp, struct part_map_virt *pmv) { - return (EOPNOTSUPP); /* Not supported yet */ + udfmp->im_flags |= UDF_MNT_FIND_VAT; /* Should do more than this */ + return (0); } /* Handle a sparable partition map */ diff --git a/sys/isofs/udf/udf_vnops.c b/sys/isofs/udf/udf_vnops.c index c6b5d59164c..e0243e2ddda 100644 --- a/sys/isofs/udf/udf_vnops.c +++ b/sys/isofs/udf/udf_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udf_vnops.c,v 1.14 2006/07/01 00:08:57 pedro Exp $ */ +/* $OpenBSD: udf_vnops.c,v 1.15 2006/07/05 17:57:50 pedro Exp $ */ /* * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> @@ -55,8 +55,6 @@ #include <isofs/udf/udf.h> #include <isofs/udf/udf_extern.h> -int udf_readatoffset(struct udf_node *, int *, off_t, struct buf **, - uint8_t **); int udf_bmap_internal(struct udf_node *, off_t, daddr_t *, uint32_t *); int (**udf_vnodeop_p)(void *); |