WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] Add iso9660 support to libfsimage

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Add iso9660 support to libfsimage
From: john.levon@xxxxxxx
Date: Tue, 20 Feb 2007 14:54:05 -0700
Delivery-date: Tue, 20 Feb 2007 14:53:39 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User john.levon@xxxxxxx
# Date 1172012044 28800
# Node ID ba6219d465a57363f2e9db2c92bd537bcfe44a80
# Parent  32af7d1cf326c33b5c02e3114e94afc5c7ab360b
Add iso9660 support to libfsimage.

Signed-off-by: John Levon <john.levon@xxxxxxx>

diff --git a/tools/libfsimage/Makefile b/tools/libfsimage/Makefile
--- a/tools/libfsimage/Makefile
+++ b/tools/libfsimage/Makefile
@@ -1,7 +1,7 @@ XEN_ROOT = ../..
 XEN_ROOT = ../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-SUBDIRS-y = common ufs reiserfs
+SUBDIRS-y = common ufs reiserfs iso9660
 SUBDIRS-y += $(shell ./check-libext2fs)
 
 .PHONY: all
diff --git a/tools/libfsimage/common/fsimage_grub.c 
b/tools/libfsimage/common/fsimage_grub.c
--- a/tools/libfsimage/common/fsimage_grub.c
+++ b/tools/libfsimage/common/fsimage_grub.c
@@ -122,6 +122,84 @@ fsig_disk_read_junk(void)
        return (&disk_read_junk);
 }
 
+#if defined(__i386__) || defined(__x86_64__)
+
+#ifdef __amd64
+#define BSF "bsfq"
+#else
+#define BSF "bsfl"
+#endif
+unsigned long
+fsig_log2 (unsigned long word)
+{
+  __asm__ (BSF " %1,%0"
+          : "=r" (word)
+          : "r" (word));
+  return word;
+}
+
+#elif defined(__ia64__)
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define ia64_popcnt(x) __builtin_popcountl(x)
+#else
+# define ia64_popcnt(x)                                     \
+  ({                                                        \
+    __u64 ia64_intri_res;                                   \
+    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
+    ia64_intri_res;                                         \
+  })
+#endif
+
+unsigned long
+fsig_log2 (unsigned long word)
+{
+  unsigned long result;
+
+  result = ia64_popcnt((word - 1) & ~word);
+  return result;
+}
+
+#elif defined(__powerpc__)
+
+#ifdef __powerpc64__
+#define PPC_CNTLZL "cntlzd"
+#else
+#define PPC_CNTLZL "cntlzw"
+#endif
+#define BITS_PER_LONG (sizeof(long) * 8)
+
+static int
+__ilog2(unsigned long x)
+{
+  int lz;
+
+  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
+  return BITS_PER_LONG - 1 - lz;
+}
+
+unsigned long
+fsig_log2 (unsigned long word)
+{
+  return __ilog2(word & -word);
+}
+
+#else /* Unoptimized */
+
+unsigned long
+fsig_log2 (unsigned long word)
+{
+  unsigned long result = 0;
+
+  while (!(word & 1UL))
+    {
+      result++;
+      word >>= 1;
+    }
+  return result;
+}
+#endif
+
 int
 fsig_devread(fsi_file_t *ffi, unsigned int sector, unsigned int offset,
     unsigned int bufsize, char *buf)
diff --git a/tools/libfsimage/common/fsimage_grub.h 
b/tools/libfsimage/common/fsimage_grub.h
--- a/tools/libfsimage/common/fsimage_grub.h
+++ b/tools/libfsimage/common/fsimage_grub.h
@@ -57,16 +57,19 @@ typedef struct fsig_plugin_ops {
 #define        disk_read_func (*fsig_disk_read_junk())
 #define        disk_read_hook (*fsig_disk_read_junk())
 #define        print_possibilities 0
+#define        noisy_printf
 
 #define        grub_memset memset
 #define        grub_memmove memmove
+#define grub_log2 fsig_log2
 
 extern char **fsig_disk_read_junk(void);
+unsigned long fsig_log2(unsigned long);
 
 #define        ERR_FSYS_CORRUPT 1
+#define        ERR_OUTSIDE_PART 1
 #define        ERR_SYMLINK_LOOP 1
 #define        ERR_FILELENGTH 1
-#define        ERR_BAD_FILETYPE 1
 #define        ERR_BAD_FILETYPE 1
 #define        ERR_FILE_NOT_FOUND 1
 
diff --git a/tools/libfsimage/common/mapfile-GNU 
b/tools/libfsimage/common/mapfile-GNU
--- a/tools/libfsimage/common/mapfile-GNU
+++ b/tools/libfsimage/common/mapfile-GNU
@@ -20,6 +20,7 @@ VERSION {
                        fsig_init;
                        fsig_devread;
                        fsig_substring;
+                       fsig_log2;
                        fsig_fs_buf;
                        fsig_file_alloc;
                        fsig_file_buf;
diff --git a/tools/libfsimage/common/mapfile-SunOS 
b/tools/libfsimage/common/mapfile-SunOS
--- a/tools/libfsimage/common/mapfile-SunOS
+++ b/tools/libfsimage/common/mapfile-SunOS
@@ -19,6 +19,7 @@ libfsimage.so.1.0 {
                fsig_init;
                fsig_devread;
                fsig_substring;
+               fsig_log2;
                fsig_fs_buf;
                fsig_file_alloc;
                fsig_file_buf;
diff --git a/tools/libfsimage/ext2fs/fsys_ext2fs.c 
b/tools/libfsimage/ext2fs/fsys_ext2fs.c
--- a/tools/libfsimage/ext2fs/fsys_ext2fs.c
+++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c
@@ -191,7 +191,7 @@ struct ext2_dir_entry
 
 
 /* ext2/super.c */
-#define log2(n) ffz(~(n))
+#define log2(n) grub_log2(n)
 
 #define EXT2_SUPER_MAGIC      0xEF53   /* include/linux/ext2_fs.h */
 #define EXT2_ROOT_INO              2   /* include/linux/ext2_fs.h */
@@ -231,93 +231,6 @@ struct ext2_dir_entry
 #define S_ISLNK(m)     (((m) & S_IFMT) == S_IFLNK)
 #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
 #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
-
-#if defined(__i386__) || defined(__x86_64__)
-/* include/asm-i386/bitops.h */
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-#ifdef __amd64
-#define BSF "bsfq"
-#else
-#define BSF "bsfl"
-#endif
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
-  __asm__ (BSF " %1,%0"
-:         "=r" (word)
-:         "r" (~word));
-  return word;
-}
-
-#elif defined(__ia64__)
-
-typedef unsigned long __u64;
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# define ia64_popcnt(x) __builtin_popcountl(x)
-#else
-# define ia64_popcnt(x)                                     \
-  ({                                                        \
-    __u64 ia64_intri_res;                                   \
-    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
-    ia64_intri_res;                                         \
-  })
-#endif
-
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
-  unsigned long result;
-
-  result = ia64_popcnt(word & (~word - 1));
-  return result;
-}
-
-#elif defined(__powerpc__)
-
-#ifdef __powerpc64__
-#define PPC_CNTLZL "cntlzd"
-#else
-#define PPC_CNTLZL "cntlzw"
-#endif
-#define BITS_PER_LONG (sizeof(long) * 8)
-
-static __inline__ int
-__ilog2(unsigned long x)
-{
-  int lz;
-
-  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
-  return BITS_PER_LONG - 1 - lz;
-}
-
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
-  if ((word = ~word) == 0)
-    return BITS_PER_LONG;
-  return __ilog2(word & -word);
-}
-
-#else /* Unoptimized */
-
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
-  unsigned long result;
-
-  result = 0;
-  while(word & 1)
-    {
-      result++;
-      word >>= 1;
-    }
-  return result;
-}
-#endif
 
 /* check filesystem types and read superblock into memory buffer */
 int
diff --git a/tools/libfsimage/iso9660/Makefile 
b/tools/libfsimage/iso9660/Makefile
new file mode 100644
--- /dev/null
+++ b/tools/libfsimage/iso9660/Makefile
@@ -0,0 +1,15 @@
+XEN_ROOT = ../../..
+
+LIB_SRCS-y = fsys_iso9660.c
+
+FS = iso9660
+
+.PHONY: all
+all: fs-all
+
+.PHONY: install
+install: fs-install
+
+fsys_iso9660.c: iso9660.h
+
+include $(XEN_ROOT)/tools/libfsimage/Rules.mk
diff --git a/tools/libfsimage/iso9660/fsys_iso9660.c 
b/tools/libfsimage/iso9660/fsys_iso9660.c
new file mode 100644
--- /dev/null
+++ b/tools/libfsimage/iso9660/fsys_iso9660.c
@@ -0,0 +1,463 @@
+/*
+ *  ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
+ *  including Rock Ridge Extensions support
+ *
+ *  Copyright (C) 1998, 1999  Kousuke Takai  <tak@xxxxxxxxxxxxxxxxx>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ *  References:
+ *     linux/fs/isofs/rock.[ch]
+ *     mkisofs-1.11.1/diag/isoinfo.c
+ *     mkisofs-1.11.1/iso9660.h
+ *             (all are written by Eric Youngdale)
+ *
+ *  Modifications by:
+ *     Leonid Lisovskiy   <lly@xxxxxxxxx>      2003
+ */
+
+#include <fsimage_grub.h>
+#include <limits.h>
+
+#include "iso9660.h"
+
+#define        MAXINT INT_MAX
+
+/* iso9660 super-block data in memory */
+struct iso_sb_info {
+  unsigned long vol_sector;
+
+};
+
+/* iso fs inode data in memory */
+struct iso_inode_info {
+  unsigned long file_start;
+};
+
+#define ISO_SUPER      \
+    ((struct iso_sb_info *)(FSYS_BUF))
+#define INODE          \
+    ((struct iso_inode_info *)(FSYS_BUF+sizeof(struct iso_sb_info)))
+#define PRIMDESC        ((struct iso_primary_descriptor *)(FSYS_BUF + 2048))
+#define DIRREC          ((struct iso_directory_record *)(FSYS_BUF + 4096))
+#define RRCONT_BUF      ((unsigned char *)(FSYS_BUF + 6144))
+#define NAME_BUF        ((unsigned char *)(FSYS_BUF + 8192))
+
+
+#define log2 grub_log2
+
+static int
+iso9660_devread (fsi_file_t *ffi, int sector, int byte_offset, int byte_len, 
char *buf)
+{
+  static int read_count = 0, threshold = 2;
+  unsigned short sector_size_lg2 = log2(512 /*buf_geom.sector_size*/);
+
+  /*
+   * We have to use own devread() function since BIOS return wrong geometry
+   */
+  if (sector < 0)
+    {
+      errnum = ERR_OUTSIDE_PART;
+      return 0;
+    }
+  if (byte_len <= 0)
+    return 1;
+
+#if 0
+  sector += (byte_offset >> sector_size_lg2);
+  byte_offset &= (buf_geom.sector_size - 1);
+  asm volatile ("shl%L0 %1,%0"
+               : "=r"(sector)
+               : "Ic"((int8_t)(ISO_SECTOR_BITS - sector_size_lg2)),
+               "0"(sector));
+#else
+  sector = (sector * 4) + (byte_offset >> sector_size_lg2);
+  byte_offset &= 511;
+#endif
+
+#if !defined(STAGE1_5)
+  if (disk_read_hook && debug)
+    printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
+#endif /* !STAGE1_5 */
+
+  read_count += (byte_len >> 9);
+  if ((read_count >> 11) > threshold) {
+       noisy_printf(".");
+       threshold += 2; /* one dot every 2 MB */
+  }
+  return devread(ffi, sector, byte_offset, byte_len, buf);
+}
+
+int
+iso9660_mount (fsi_file_t *ffi, const char *options)
+{
+  unsigned int sector;
+
+  /*
+   *  Because there is no defined slice type ID for ISO-9660 filesystem,
+   *  this test will pass only either (1) if entire disk is used, or
+   *  (2) if current partition is BSD style sub-partition whose ID is
+   *  ISO-9660.
+   */
+#if 0
+  if ((current_partition != 0xFFFFFF)
+      && !IS_PC_SLICE_TYPE_BSD_WITH_FS(current_slice, FS_ISO9660))
+    return 0;
+#endif
+
+  /*
+   *  Currently, only FIRST session of MultiSession disks are supported !!!
+   */
+  for (sector = 16 ; sector < 32 ; sector++)
+    {
+      if (!iso9660_devread(ffi, sector, 0, sizeof(*PRIMDESC), (char 
*)PRIMDESC)) 
+       break;
+      /* check ISO_VD_PRIMARY and ISO_STANDARD_ID */
+      if (PRIMDESC->type.l == ISO_VD_PRIMARY
+         && !memcmp(PRIMDESC->id, ISO_STANDARD_ID, sizeof(PRIMDESC->id)))
+       {
+         ISO_SUPER->vol_sector = sector;
+         INODE->file_start = 0;
+#if 0
+         fsmax = PRIMDESC->volume_space_size.l;
+#endif
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+int
+iso9660_dir (fsi_file_t *ffi, char *dirname)
+{
+  struct iso_directory_record *idr;
+  RR_ptr_t rr_ptr;
+  struct rock_ridge *ce_ptr;
+  unsigned int pathlen;
+  int size;
+  unsigned int extent;
+  unsigned char file_type;
+  unsigned int rr_len;
+  unsigned char rr_flag;
+
+  idr = &PRIMDESC->root_directory_record;
+  INODE->file_start = 0;
+
+  do
+    {
+      while (*dirname == '/')  /* skip leading slashes */
+       dirname++;
+      /* pathlen = strcspn(dirname, "/\n\t "); */
+      for (pathlen = 0 ;
+          dirname[pathlen]
+            && !isspace(dirname[pathlen]) && dirname[pathlen] != '/' ;
+          pathlen++)
+       ;
+
+      size = idr->size.l;
+      extent = idr->extent.l;
+
+      while (size > 0)
+       {
+         if (!iso9660_devread(ffi, extent, 0, ISO_SECTOR_SIZE, (char *)DIRREC))
+           {
+             errnum = ERR_FSYS_CORRUPT;
+             return 0;
+           }
+         extent++;
+
+         idr = (struct iso_directory_record *)DIRREC;
+         for (; idr->length.l > 0;
+              idr = (struct iso_directory_record *)((char *)idr + 
idr->length.l) )
+           {
+             const char *name = idr->name;
+             unsigned int name_len = idr->name_len.l;
+
+             file_type = (idr->flags.l & 2) ? ISO_DIRECTORY : ISO_REGULAR;
+             if (name_len == 1)
+               {
+                 if ((name[0] == 0) || /* self */
+                     (name[0] == 1))   /* parent */
+                   continue;
+               }
+             if (name_len > 2 && CHECK2(name + name_len - 2, ';', '1'))
+               {
+                 name_len -= 2;        /* truncate trailing file version */
+                 if (name_len > 1 && name[name_len - 1] == '.')
+                   name_len--;         /* truncate trailing dot */
+               }
+
+             /*
+              *  Parse Rock-Ridge extension
+              */
+             rr_len = (idr->length.l - idr->name_len.l
+                       - sizeof(struct iso_directory_record)
+                       + sizeof(idr->name));
+             rr_ptr.ptr = ((unsigned char *)idr + idr->name_len.l
+                           + sizeof(struct iso_directory_record)
+                           - sizeof(idr->name));
+             if (rr_ptr.i & 1)
+               rr_ptr.i++, rr_len--;
+             ce_ptr = NULL;
+             rr_flag = RR_FLAG_NM | RR_FLAG_PX /*| RR_FLAG_SL*/;
+
+             while (rr_len >= 4)
+               {
+                 if (rr_ptr.rr->version != 1)
+                   {
+#ifndef STAGE1_5
+                     if (debug)
+                       printf(
+                              "Non-supported version (%d) RockRidge chunk "
+                              "`%c%c'\n", rr_ptr.rr->version,
+                              rr_ptr.rr->signature & 0xFF,
+                              rr_ptr.rr->signature >> 8);
+#endif
+                   }
+                 else
+                   {
+                     switch (rr_ptr.rr->signature)
+                       {
+                       case RRMAGIC('R', 'R'):
+                         if ( rr_ptr.rr->len >= (4+sizeof(struct RR)))
+                           rr_flag &= rr_ptr.rr->u.rr.flags.l;
+                         break;
+                       case RRMAGIC('N', 'M'):
+                         name = rr_ptr.rr->u.nm.name;
+                         name_len = rr_ptr.rr->len - (4+sizeof(struct NM));
+                         rr_flag &= ~RR_FLAG_NM;
+                         break;
+                       case RRMAGIC('P', 'X'):
+                         if (rr_ptr.rr->len >= (4+sizeof(struct PX)))
+                           {
+                             file_type = ((rr_ptr.rr->u.px.mode.l & 
POSIX_S_IFMT)
+                                          == POSIX_S_IFREG
+                                          ? ISO_REGULAR
+                                          : ((rr_ptr.rr->u.px.mode.l & 
POSIX_S_IFMT)
+                                             == POSIX_S_IFDIR
+                                             ? ISO_DIRECTORY : ISO_OTHER));
+                             rr_flag &= ~RR_FLAG_PX;
+                           }
+                         break;
+                       case RRMAGIC('C', 'E'):
+                         if (rr_ptr.rr->len >= (4+sizeof(struct CE)))
+                           ce_ptr = rr_ptr.rr;
+                         break;
+#if 0          // RockRidge symlinks are not supported yet
+                       case RRMAGIC('S', 'L'):
+                         {
+                           int slen;
+                           unsigned char rootflag, prevflag;
+                           char *rpnt = NAME_BUF+1024;
+                           struct SL_component *slp;
+
+                           slen = rr_ptr.rr->len - (4+1);
+                           slp = &rr_ptr.rr->u.sl.link;
+                           while (slen > 1)
+                             {
+                               rootflag = 0;
+                               switch (slp->flags.l)
+                                 {
+                                 case 0:
+                                   memcpy(rpnt, slp->text, slp->len);
+                                   rpnt += slp->len;
+                                   break;
+                                 case 4:
+                                   *rpnt++ = '.';
+                                   /* fallthru */
+                                 case 2:
+                                   *rpnt++ = '.';
+                                   break;
+                                 case 8:
+                                   rootflag = 1;
+                                   *rpnt++ = '/';
+                                   break;
+                                 default:
+                                   printf("Symlink component flag not 
implemented (%d)\n",
+                                          slp->flags.l);
+                                   slen = 0;
+                                   break;
+                                 }
+                               slen -= slp->len + 2;
+                               prevflag = slp->flags.l;
+                               slp = (struct SL_component *) ((char *) slp + 
slp->len + 2);
+
+                               if (slen < 2)
+                                 {
+                                   /*
+                                    * If there is another SL record, and this 
component
+                                    * record isn't continued, then add a slash.
+                                    */
+                                   if ((!rootflag) && (rr_ptr.rr->u.sl.flags.l 
& 1) && !(prevflag & 1))
+                                     *rpnt++='/';
+                                   break;
+                                 }
+
+                               /*
+                                * If this component record isn't continued, 
then append a '/'.
+                                */
+                               if (!rootflag && !(prevflag & 1))
+                                 *rpnt++ = '/';
+                             }
+                           *rpnt++ = '\0';
+                           grub_putstr(NAME_BUF+1024);// debug print!
+                         }
+                         rr_flag &= ~RR_FLAG_SL;
+                         break;
+#endif
+                       default:
+                         break;
+                       }
+                   }
+                 if (!rr_flag)
+                   /*
+                    * There is no more extension we expects...
+                    */
+                   break;
+
+                 rr_len -= rr_ptr.rr->len;
+                 rr_ptr.ptr += rr_ptr.rr->len;
+                 if (rr_len < 4 && ce_ptr != NULL)
+                   {
+                     /* preserve name before loading new extent. */
+                     if( RRCONT_BUF <= (unsigned char *)name
+                         && (unsigned char *)name < RRCONT_BUF + 
ISO_SECTOR_SIZE )
+                       {
+                         memcpy(NAME_BUF, name, name_len);
+                         name = NAME_BUF;
+                       }
+                     rr_ptr.ptr = RRCONT_BUF + ce_ptr->u.ce.offset.l;
+                     rr_len = ce_ptr->u.ce.size.l;
+                     if (!iso9660_devread(ffi, ce_ptr->u.ce.extent.l, 0, 
ISO_SECTOR_SIZE, RRCONT_BUF))
+                       {
+                         errnum = 0;   /* this is not fatal. */
+                         break;
+                       }
+                     ce_ptr = NULL;
+                   }
+               } /* rr_len >= 4 */
+
+             filemax = MAXINT;
+             if (name_len >= pathlen
+                 && !memcmp(name, dirname, pathlen))
+               {
+                 if (dirname[pathlen] == '/' || !print_possibilities)
+                   {
+                     /*
+                      *  DIRNAME is directory component of pathname,
+                      *  or we are to open a file.
+                      */
+                     if (pathlen == name_len)
+                       {
+                         if (dirname[pathlen] == '/')
+                           {
+                             if (file_type != ISO_DIRECTORY)
+                               {
+                                 errnum = ERR_BAD_FILETYPE;
+                                 return 0;
+                               }
+                             goto next_dir_level;
+                           }
+                         if (file_type != ISO_REGULAR)
+                           {
+                             errnum = ERR_BAD_FILETYPE;
+                             return 0;
+                           }
+                         INODE->file_start = idr->extent.l;
+                         filepos = 0;
+                         filemax = idr->size.l;
+                         return 1;
+                       }
+                   }
+                 else  /* Completion */
+                   {
+#ifndef STAGE1_5
+                     if (print_possibilities > 0)
+                       print_possibilities = -print_possibilities;
+                     memcpy(NAME_BUF, name, name_len);
+                     NAME_BUF[name_len] = '\0';
+                     print_a_completion (NAME_BUF);
+#endif
+                   }
+               }
+           } /* for */
+
+         size -= ISO_SECTOR_SIZE;
+       } /* size>0 */
+
+      if (dirname[pathlen] == '/' || print_possibilities >= 0)
+       {
+         errnum = ERR_FILE_NOT_FOUND;
+         return 0;
+       }
+
+    next_dir_level:
+      dirname += pathlen;
+
+    } while (*dirname == '/');
+
+  return 1;
+}
+
+int
+iso9660_read (fsi_file_t *ffi, char *buf, int len)
+{
+  int sector, blkoffset, size, ret;
+
+  if (INODE->file_start == 0)
+    return 0;
+
+  ret = 0;
+  blkoffset = filepos & (ISO_SECTOR_SIZE - 1);
+  sector = filepos >> ISO_SECTOR_BITS;
+  while (len > 0)
+    {
+      size = ISO_SECTOR_SIZE - blkoffset;
+      if (size > len)
+        size = len;
+
+      disk_read_func = disk_read_hook;
+
+      if (!iso9660_devread(ffi, INODE->file_start + sector, blkoffset, size, 
buf))
+       return 0;
+
+      disk_read_func = NULL;
+
+      len -= size;
+      buf += size;
+      ret += size;
+      filepos += size;
+      sector++;
+      blkoffset = 0;
+    }
+
+  return ret;
+}
+
+fsi_plugin_ops_t *
+fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
+{
+       static fsig_plugin_ops_t ops = {
+               FSIMAGE_PLUGIN_VERSION,
+               .fpo_mount = iso9660_mount,
+               .fpo_dir = iso9660_dir,
+               .fpo_read = iso9660_read
+       };
+
+       *name = "iso9660";
+       return (fsig_init(fp, &ops));
+}
diff --git a/tools/libfsimage/iso9660/iso9660.h 
b/tools/libfsimage/iso9660/iso9660.h
new file mode 100644
--- /dev/null
+++ b/tools/libfsimage/iso9660/iso9660.h
@@ -0,0 +1,219 @@
+/*
+ *  ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
+ *  including Rock Ridge Extensions support
+ *
+ *  Copyright (C) 1998, 1999  Kousuke Takai  <tak@xxxxxxxxxxxxxxxxx>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ *  References:
+ *     linux/fs/isofs/rock.[ch]
+ *     mkisofs-1.11.1/diag/isoinfo.c
+ *     mkisofs-1.11.1/iso9660.h
+ *             (all are written by Eric Youngdale)
+ */
+
+#ifndef _ISO9660_H_
+#define _ISO9660_H_
+
+#define ISO_SECTOR_BITS              (11)
+#define ISO_SECTOR_SIZE              (1<<ISO_SECTOR_BITS)
+
+#define        ISO_REGULAR     1       /* regular file */
+#define        ISO_DIRECTORY   2       /* directory    */
+#define        ISO_OTHER       0       /* other file (with Rock Ridge) */
+
+#define        RR_FLAG_PX      0x01    /* have POSIX file attributes */
+#define RR_FLAG_PN     0x02    /* POSIX devices */
+#define RR_FLAG_SL     0x04    /* Symbolic link */
+#define        RR_FLAG_NM      0x08    /* have alternate file name   */
+#define RR_FLAG_CL     0x10    /* Child link */
+#define RR_FLAG_PL     0x20    /* Parent link */
+#define RR_FLAG_RE     0x40    /* Relocation directory */
+#define RR_FLAG_TF     0x80    /* Timestamps */
+
+/* POSIX file attributes for Rock Ridge extensions */
+#define        POSIX_S_IFMT    0xF000
+#define        POSIX_S_IFREG   0x8000
+#define        POSIX_S_IFDIR   0x4000
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+
+#ifndef ASM_FILE
+
+#ifndef __sun
+#ifndef        __BIT_TYPES_DEFINED__
+typedef                 int     int8_t __attribute__((mode(QI)));
+typedef unsigned int   u_int8_t        __attribute__((mode(QI)));
+typedef                 int    int16_t __attribute__((mode(HI)));
+typedef unsigned int  u_int16_t        __attribute__((mode(HI)));
+typedef                 int    int32_t __attribute__((mode(SI)));
+typedef unsigned int  u_int32_t        __attribute__((mode(SI)));
+#endif
+#else
+#ifndef GRUB_UTIL
+typedef                 char  int8_t;
+typedef                 short int16_t;
+typedef                 int   int32_t;
+#endif /* ! GRUB_UTIL */
+typedef unsigned char  u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned int   u_int32_t;
+#endif /* __sun */
+
+typedef        union {
+  u_int8_t l,b;
+}      iso_8bit_t;
+
+struct __iso_16bit {
+  u_int16_t l, b;
+} __attribute__ ((packed));
+typedef        struct __iso_16bit iso_16bit_t;
+
+struct __iso_32bit {
+  u_int32_t l, b;
+} __attribute__ ((packed));
+typedef        struct __iso_32bit iso_32bit_t;
+
+typedef u_int8_t               iso_date_t[7];
+
+struct iso_directory_record {
+  iso_8bit_t   length;
+  iso_8bit_t   ext_attr_length;
+  iso_32bit_t  extent;
+  iso_32bit_t  size;
+  iso_date_t   date;
+  iso_8bit_t   flags;
+  iso_8bit_t   file_unit_size;
+  iso_8bit_t   interleave;
+  iso_16bit_t  volume_seq_number;
+  iso_8bit_t   name_len;
+  u_int8_t     name[1];
+} __attribute__ ((packed));
+
+struct iso_primary_descriptor {
+  iso_8bit_t   type;
+  u_int8_t     id[5];
+  iso_8bit_t   version;
+  u_int8_t     _unused1[1];
+  u_int8_t     system_id[32];
+  u_int8_t     volume_id[32];
+  u_int8_t     _unused2[8];
+  iso_32bit_t  volume_space_size;
+  u_int8_t     _unused3[32];
+  iso_16bit_t  volume_set_size;
+  iso_16bit_t  volume_seq_number;
+  iso_16bit_t  logical_block_size;
+  iso_32bit_t  path_table_size;
+  u_int8_t     type_l_path_table[4];
+  u_int8_t     opt_type_l_path_table[4];
+  u_int8_t     type_m_path_table[4];
+  u_int8_t     opt_type_m_path_table[4];
+  struct iso_directory_record root_directory_record;
+  u_int8_t     volume_set_id[128];
+  u_int8_t     publisher_id[128];
+  u_int8_t     preparer_id[128];
+  u_int8_t     application_id[128];
+  u_int8_t     copyright_file_id[37];
+  u_int8_t     abstract_file_id[37];
+  u_int8_t     bibliographic_file_id[37];
+  u_int8_t     creation_date[17];
+  u_int8_t     modification_date[17];
+  u_int8_t     expiration_date[17];
+  u_int8_t     effective_date[17];
+  iso_8bit_t   file_structure_version;
+  u_int8_t     _unused4[1];
+  u_int8_t     application_data[512];
+  u_int8_t     _unused5[653];
+} __attribute__ ((packed));
+
+struct rock_ridge {
+  u_int16_t    signature;
+  u_int8_t     len;
+  u_int8_t     version;
+  union {
+    struct SP {
+      u_int16_t        magic;
+      u_int8_t skip;
+    } sp;
+    struct CE {
+      iso_32bit_t      extent;
+      iso_32bit_t      offset;
+      iso_32bit_t      size;
+    } ce;
+    struct ER {
+      u_int8_t len_id;
+      u_int8_t len_des;
+      u_int8_t len_src;
+      u_int8_t ext_ver;
+      u_int8_t data[0];
+    } er;
+    struct RR {
+      iso_8bit_t       flags;
+    } rr;
+    struct PX {
+      iso_32bit_t      mode;
+      iso_32bit_t      nlink;
+      iso_32bit_t      uid;
+      iso_32bit_t      gid;
+    } px;
+    struct PN {
+      iso_32bit_t      dev_high;
+      iso_32bit_t      dev_low;
+    } pn;
+    struct SL {
+      iso_8bit_t flags;
+      struct SL_component {
+       iso_8bit_t      flags;
+       u_int8_t                len;
+       u_int8_t                text[0];
+      } link;
+    } sl;
+    struct NM {
+      iso_8bit_t       flags;
+      u_int8_t name[0];
+    } nm;
+    struct CL {
+      iso_32bit_t      location;
+    } cl;
+    struct PL {
+      iso_32bit_t      location;
+    } pl;
+    struct TF {
+      iso_8bit_t       flags;
+      iso_date_t       times[0];
+    } tf;
+  } u;
+} __attribute__ ((packed));
+
+typedef        union RR_ptr {
+  struct rock_ridge *rr;
+  char           *ptr;
+  int             i;
+} RR_ptr_t;
+
+#define        RRMAGIC(c1, c2) ((c1)|(c2) << 8)
+
+#define        CHECK2(ptr, c1, c2) \
+       (*(unsigned short *)(ptr) == (((c1) | (c2) << 8) & 0xFFFF))
+
+#endif /* !ASM_FILE */
+
+#endif /* _ISO9660_H_ */
diff --git a/tools/libfsimage/reiserfs/fsys_reiserfs.c 
b/tools/libfsimage/reiserfs/fsys_reiserfs.c
--- a/tools/libfsimage/reiserfs/fsys_reiserfs.c
+++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c
@@ -363,83 +363,6 @@ struct fsys_reiser_info
 #define JOURNAL_START    ((__u32 *) (INFO + 1))
 #define JOURNAL_END      ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
 
-#if defined(__i386__) || defined(__x86_64__)
-
-#ifdef __amd64
-#define BSF "bsfq"
-#else
-#define BSF "bsfl"
-#endif
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
-  __asm__ (BSF " %1,%0"
-          : "=r" (word)
-          : "r" (word));
-  return word;
-}
-
-#elif defined(__ia64__)
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# define ia64_popcnt(x) __builtin_popcountl(x)
-#else
-# define ia64_popcnt(x)                                     \
-  ({                                                        \
-    __u64 ia64_intri_res;                                   \
-    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
-    ia64_intri_res;                                         \
-  })
-#endif
-
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
-  unsigned long result;
-
-  result = ia64_popcnt((word - 1) & ~word);
-  return result;
-}
-
-#elif defined(__powerpc__)
-
-#ifdef __powerpc64__
-#define PPC_CNTLZL "cntlzd"
-#else
-#define PPC_CNTLZL "cntlzw"
-#endif
-#define BITS_PER_LONG (sizeof(long) * 8)
-
-static __inline__ int
-__ilog2(unsigned long x)
-{
-  int lz;
-
-  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
-  return BITS_PER_LONG - 1 - lz;
-}
-
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
-  return __ilog2(word & -word);
-}
-
-#else /* Unoptimized */
-
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
-  unsigned long result = 0;
-
-  while (!(word & 1UL))
-    {
-      result++;
-      word >>= 1;
-    }
-  return result;
-}
-#endif
 #define log2 grub_log2
 
 static __inline__ int

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] Add iso9660 support to libfsimage, john . levon <=