From nobody@FreeBSD.org Mon Sep 6 19:32:08 2010 Return-Path: Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7CA3110656AB for ; Mon, 6 Sep 2010 19:32:08 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 6BA528FC14 for ; Mon, 6 Sep 2010 19:32:08 +0000 (UTC) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o86JW84C054543 for ; Mon, 6 Sep 2010 19:32:08 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id o86JW8wV054542; Mon, 6 Sep 2010 19:32:08 GMT (envelope-from nobody) Message-Id: <201009061932.o86JW8wV054542@www.freebsd.org> Date: Mon, 6 Sep 2010 19:32:08 GMT From: Takanori Watanabe To: freebsd-gnats-submit@FreeBSD.org Subject: geom label does not support UDF X-Send-Pr-Version: www-3.1 X-GNATS-Notify: >Number: 150334 >Category: kern >Synopsis: [geom] [udf] [patch] geom label does not support UDF >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-geom >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Sep 06 19:40:07 UTC 2010 >Closed-Date: >Last-Modified: Mon Sep 06 22:19:11 UTC 2010 >Originator: Takanori Watanabe >Release: 9.0-CURRENT >Organization: private >Environment: FreeBSD rin.init-main.com 9.0-CURRENT FreeBSD 9.0-CURRENT #51 r212175M: Mon Sep 6 02:35:31 JST 2010 takawata@rin.init-main.com:/usr/obj/usr/src.svn/head/sys/LIEUTENANT i386 >Description: geom label supports various labeling scheme based on filesystem metadata, FAT, UFS, NTFS, EXT2FS, REISERFS, ISO9660. But does not support UDF, used on DVD etc. >How-To-Repeat: Load geom_label module with your DVD inserted in DVD drive >Fix: Apply the following patch.And check /dev/udf directory. Here is example to ISO9660 and UDF bridged disk. /dev/iso9660: total 0 crw-r----- 1 root operator 0, 63 Sep 7 04:26 kud_wafter /dev/udf: total 0 crw-r----- 1 root operator 0, 62 Sep 7 04:26 kud_wafter Patch attached with submission follows: 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 + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#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 >Release-Note: >Audit-Trail: Responsible-Changed-From-To: freebsd-bugs->freebsd-geom Responsible-Changed-By: arundel Responsible-Changed-When: Mon Sep 6 22:16:51 UTC 2010 Responsible-Changed-Why: Assign to maintainer(s). http://www.freebsd.org/cgi/query-pr.cgi?pr=150334 >Unformatted: