>Number:         150334
>Category:       kern
>Synopsis:       geom label does not support UDF
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>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:
>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     
[email protected]:/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 <[email protected]>
+ * 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>


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to