[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.