diff -Naur grub/grub-core/fs/udf.c grub-test/grub-core/fs/udf.c
--- grub/grub-core/fs/udf.c	2010-05-06 17:30:36.000000000 +0200
+++ grub-test/grub-core/fs/udf.c	2010-10-27 10:20:56.403999341 +0200
@@ -343,7 +343,7 @@
   struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
   struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
   struct grub_udf_long_ad root_icb;
-  int npd, npm;
+  int npd, npm, lbshift;
 };
 
 struct grub_fshelp_node
@@ -389,7 +389,7 @@
   if (grub_errno)
     return grub_errno;
 
-  if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+  if (grub_disk_read (data->disk, block << data->lbshift, 0,
 		      sizeof (struct grub_udf_file_entry),
 		      &node->fe))
     return grub_errno;
@@ -427,7 +427,7 @@
       struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr;
 
       len /= sizeof (struct grub_udf_short_ad);
-      filebytes = fileblock * GRUB_UDF_BLKSZ;
+      filebytes = fileblock * U32 (node->data->lvd.bsize);
       while (len > 0)
 	{
 	  if (filebytes < U32 (ad->length))
@@ -435,7 +435,8 @@
                     (grub_udf_get_block (node->data,
                                          node->part_ref,
                                          ad->position)
-                     + (filebytes / GRUB_UDF_BLKSZ)));
+                     + (filebytes >> (GRUB_DISK_SECTOR_BITS
+				      + node->data->lbshift))));
 
 	  filebytes -= U32 (ad->length);
 	  ad++;
@@ -447,7 +448,7 @@
       struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr;
 
       len /= sizeof (struct grub_udf_long_ad);
-      filebytes = fileblock * GRUB_UDF_BLKSZ;
+      filebytes = fileblock * U32 (node->data->lvd.bsize);
       while (len > 0)
 	{
 	  if (filebytes < U32 (ad->length))
@@ -455,7 +456,8 @@
                     (grub_udf_get_block (node->data,
                                          ad->block.part_ref,
                                          ad->block.block_num)
-		     + (filebytes / GRUB_UDF_BLKSZ)));
+		     + (filebytes >> (GRUB_DISK_SECTOR_BITS
+				      + node->data->lbshift))));
 
 	  filebytes -= U32 (ad->length);
 	  ad++;
@@ -496,21 +498,21 @@
     }
 
   return  grub_fshelp_read_file (node->data->disk, node, read_hook,
-                                 pos, len, buf, grub_udf_read_block,
-                                 U64 (node->fe.file_size),
-                                 GRUB_UDF_LOG2_BLKSZ);
+				 pos, len, buf, grub_udf_read_block,
+				 U64 (node->fe.file_size),
+				 node->data->lbshift);
 }
 
-static int sblocklist[] = { 256, 512, 0 };
+static unsigned sblocklist[] = { 256, 512, 0 };
 
 static struct grub_udf_data *
 grub_udf_mount (grub_disk_t disk)
 {
   struct grub_udf_data *data = 0;
   struct grub_udf_fileset root_fs;
-  int *sblklist = sblocklist;
+  unsigned *sblklist;
   grub_uint32_t block;
-  int i;
+  int i, lbshift;
 
   data = grub_malloc (sizeof (struct grub_udf_data));
   if (!data)
@@ -545,31 +547,46 @@
 	}
     }
 
-  /* Search for Anchor Volume Descriptor Pointer (AVDP).  */
-  while (1)
-    {
-      struct grub_udf_avdp avdp;
+  /* Search for Anchor Volume Descriptor Pointer (AVDP)
+   * and determine logical block size.  */
+  lbshift = 0;
+  block = 0;
+  while (lbshift <= 3)
+    {
+      sblklist = sblocklist;
+      while (*sblklist)
+        {
+	  struct grub_udf_avdp avdp;
 
-      if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0,
-			  sizeof (struct grub_udf_avdp), &avdp))
-	{
-	  grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-	  goto fail;
-	}
+	  if (grub_disk_read (disk, *sblklist << lbshift, 0,
+			      sizeof (struct grub_udf_avdp), &avdp))
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+	      goto fail;
+	    }
 
-      if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP)
-	{
-	  block = U32 (avdp.vds.start);
-	  break;
-	}
+	  if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP &&
+	      U32 (avdp.tag.tag_location) == *sblklist)
+	    {
+	      block = U32 (avdp.vds.start);
+	      break;
+	    }
 
-      sblklist++;
-      if (*sblklist == 0)
-	{
-	  grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-	  goto fail;
+	  sblklist++;
 	}
+
+      if (block)
+	break;
+
+      lbshift++;
+    }
+
+  if (!block)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+      goto fail;
     }
+  data->lbshift = lbshift;
 
   data->npd = data->npm = 0;
   /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD).  */
@@ -577,7 +594,7 @@
     {
       struct grub_udf_tag tag;
 
-      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+      if (grub_disk_read (disk, block << lbshift, 0,
 			  sizeof (struct grub_udf_tag), &tag))
 	{
 	  grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
@@ -593,7 +610,7 @@
 	      goto fail;
 	    }
 
-	  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+	  if (grub_disk_read (disk, block << lbshift, 0,
 			      sizeof (struct grub_udf_pd),
 			      &data->pds[data->npd]))
 	    {
@@ -609,7 +626,7 @@
 
 	  struct grub_udf_partmap *ppm;
 
-	  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+	  if (grub_disk_read (disk, block << lbshift, 0,
 			      sizeof (struct grub_udf_lvd),
 			      &data->lvd))
 	    {
@@ -673,7 +690,7 @@
   if (grub_errno)
     goto fail;
 
-  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+  if (grub_disk_read (disk, block << lbshift, 0,
 		      sizeof (struct grub_udf_fileset), &root_fs))
     {
       grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
