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