UDF label function patch.
jhell
jhell at DataIX.net
Mon Sep 6 16:55:11 UTC 2010
Can you file this here: http://www.freebsd.org/send-pr.html as a
misc/change-request so it does not get lost ? Would be awesome!
On 09/05/2010 14:15, Takanori Watanabe wrote:
> I wrote a patch to add UDF support on geom label module.
> How about it?
>
> Index: sys/conf/files
> ===================================================================
> --- sys/conf/files (revision 212175)
> +++ sys/conf/files (working copy)
> @@ -2023,6 +2023,7 @@
> geom/label/g_label_msdosfs.c optional geom_label
> geom/label/g_label_ntfs.c optional geom_label
> geom/label/g_label_reiserfs.c optional geom_label
> +geom/label/g_label_udf.c optional geom_label
> geom/label/g_label_ufs.c optional geom_label
> geom/label/g_label_gpt.c optional geom_label
> geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm
> Index: sbin/geom/class/label/glabel.8
> ===================================================================
> --- sbin/geom/class/label/glabel.8 (revision 212175)
> +++ sbin/geom/class/label/glabel.8 (working copy)
> @@ -109,6 +109,9 @@
> CD ISO9660 (directory
> .Pa /dev/iso9660/ ) .
> .It
> +DVD UDF (directory
> +.Pa /dev/udf/ ) .
> +.It
> EXT2FS (directory
> .Pa /dev/ext2fs/ ) .
> .It
> Index: sys/geom/label/g_label_udf.c
> ===================================================================
> --- sys/geom/label/g_label_udf.c (revision 0)
> +++ sys/geom/label/g_label_udf.c (revision 0)
> @@ -0,0 +1,168 @@
> +/*-
> + * Copyright (c) 2010 Takanori Watanabe <takawata at freebsd.org>
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/kernel.h>
> +#include <sys/malloc.h>
> +
> +#include <geom/geom.h>
> +#include <geom/label/g_label.h>
> +#include <fs/udf/ecma167-udf.h>
> +#define G_LABEL_UDF_DIR "udf"
> +#define LOGICAL_SECTOR_SIZE 2048
> +#define UDF_OFFSET (256*LOGICAL_SECTOR_SIZE)
> +#define VOLUME_LEN 16
> +
> +static int
> +g_label_udf_checktag(struct desc_tag *tag, uint16_t id)
> +{
> + uint8_t *itag;
> + uint8_t i, cksum = 0;
> +
> + itag = (uint8_t *)tag;
> +
> + if (le16toh(tag->id) != id)
> + return (EINVAL);
> +
> + for (i = 0; i < 16; i++)
> + cksum = cksum + itag[i];
> + cksum = cksum - itag[4];
> +
> + if (cksum == tag->cksum)
> + return (0);
> +
> + return (EINVAL);
> +}
> +static int
> +g_label_udf_uncompress_unicode(unsigned char *dest,unsigned char *src, int size,int srcsize)
> +{
> + int i,j;
> + unsigned short unichar;
> + if(src[0] == 8){
> + strlcpy(dest, src+1 , size);
> + return 0;
> + }else if(src[0] == 16){
> + /*Encode as UTF-8*/
> + for(j = 0,i = 1; i < srcsize; i+=2){
> + unichar = src[i]<<8|src[i+1];
> + if(unichar == 0){
> + *dest = 0;
> + return 0;
> + }
> + if(unichar < 0x7f){
> + j++;
> + if(j > size){
> + *dest = 0;
> + return 0;
> + }
> + *dest++ = unichar;
> + }else if(unichar < 0x7ff){
> + j += 2 ;
> + if(j > size){
> + *dest = 0;
> + return 0;
> + }
> + *dest++ = ((unichar>>6)&0x1f)|0xc0;
> + *dest++ = (unichar &0x3f)|0x80;
> + }else{
> + j+= 3;
> + if(j > size){
> + *dest = 0;
> + return 0;
> + }
> + *dest++ = ((unichar>>12)&0x0f)|0xe0;
> + *dest++ = ((unichar>>6)&0x3f)|0x80;
> + *dest++ = (unichar&0x3f)|0x80;
> + }
> + }
> + }
> +
> + return 1;
> +}
> +
> +static void
> +g_label_udf_taste(struct g_consumer *cp, char *label, size_t size)
> +{
> + struct g_provider *pp;
> + unsigned char *sector = NULL;
> + unsigned char *volume = NULL;
> + int i;
> + struct anchor_vdp *avdp;
> + struct logvol_desc *logvol;
> +
> + g_topology_assert_not();
> + pp = cp->provider;
> + label[0] = '\0';
> +
> + if ((UDF_OFFSET % pp->sectorsize) != 0)
> + return;
> + sector = (unsigned char *)g_read_data(cp, UDF_OFFSET, pp->sectorsize,
> + NULL);
> + if (sector == NULL)
> + return;
> +
> + if (g_label_udf_checktag((struct desc_tag *)sector, TAGID_ANCHOR) != 0) {
> + goto end;
> + }
> + avdp = (struct anchor_vdp *) sector;
> + for(i = 0; i < avdp->main_vds_ex.len; i+= LOGICAL_SECTOR_SIZE){
> + volume =(unsigned char *)
> + g_read_data(cp,
> + LOGICAL_SECTOR_SIZE
> + *avdp->main_vds_ex.loc + i,
> + LOGICAL_SECTOR_SIZE,
> + NULL);
> + if (g_label_udf_checktag((struct desc_tag *)volume,
> + TAGID_LOGVOL) != 0) {
> + g_free(volume);
> + continue;
> + }
> + logvol = (struct logvol_desc *)volume;
> + G_LABEL_DEBUG(1, "UDF file system detected on %s.", pp->name);
> + if(g_label_udf_uncompress_unicode(label, logvol->logvol_id, size, sizeof(logvol->logvol_id))!= 0){
> + label[0] = '\0';
> + }
> + break;
> + }
> +end:
> + if(sector){
> + g_free(sector);
> + }
> + if(volume){
> + g_free(volume);
> + }
> +}
> +
> +struct g_label_desc g_label_udf = {
> + .ld_taste = g_label_udf_taste,
> + .ld_dir = G_LABEL_UDF_DIR,
> + .ld_enabled = 1
> +};
> +G_LABEL_INIT(udf, g_label_udf, "Create device nodes for UDF volumes");
> Index: sys/geom/label/g_label.c
> ===================================================================
> --- sys/geom/label/g_label.c (revision 212175)
> +++ sys/geom/label/g_label.c (working copy)
> @@ -78,6 +78,7 @@
> const struct g_label_desc *g_labels[] = {
> &g_label_ufs_id,
> &g_label_ufs_volume,
> + &g_label_udf,
> &g_label_iso9660,
> &g_label_msdosfs,
> &g_label_ext2fs,
> Index: sys/geom/label/g_label.h
> ===================================================================
> --- sys/geom/label/g_label.h (revision 212175)
> +++ sys/geom/label/g_label.h (working copy)
> @@ -80,6 +80,7 @@
> /* Supported labels. */
> extern struct g_label_desc g_label_ufs_id;
> extern struct g_label_desc g_label_ufs_volume;
> +extern struct g_label_desc g_label_udf;
> extern struct g_label_desc g_label_iso9660;
> extern struct g_label_desc g_label_msdosfs;
> extern struct g_label_desc g_label_ext2fs;
> Index: sys/modules/geom/geom_label/Makefile
> ===================================================================
> --- sys/modules/geom/geom_label/Makefile (revision 212175)
> +++ sys/modules/geom/geom_label/Makefile (working copy)
> @@ -10,6 +10,7 @@
> SRCS+= g_label_msdosfs.c
> SRCS+= g_label_ntfs.c
> SRCS+= g_label_reiserfs.c
> +SRCS+= g_label_udf.c
> SRCS+= g_label_ufs.c
>
> .include <bsd.kmod.mk>
> _______________________________________________
> freebsd-geom at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-geom
> To unsubscribe, send any mail to "freebsd-geom-unsubscribe at freebsd.org"
--
jhell,v
More information about the freebsd-geom
mailing list