UDF label function patch.
Takanori Watanabe
takawata at init-main.com
Sun Sep 5 18:16:03 UTC 2010
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>
More information about the freebsd-geom
mailing list