kern/150334: geom label does not support UDF

Takanori Watanabe takawata at FreeBSD.org
Mon Sep 6 19:40:08 UTC 2010


>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     takawata at 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 <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>


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list