]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/fs/zfs/zfs.c (DVA_OFFSET_TO_PHYS_SECTOR): Make into inline
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 13 Dec 2011 10:33:02 +0000 (11:33 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 13 Dec 2011 10:33:02 +0000 (11:33 +0100)
function.
(ZAP_HASH_IDX): Likewise.
(ZAP_LEAF_HASH_SHIFT): Likewise.
(ZAP_LEAF_HASH_NUMENTRIES): Likewise.
(LEAF_HASH): Likewise.
(ZAP_LEAF_NUMCHUNKS): Likewise.
(ZAP_LEAF_CHUNK): Likewise. Changed pointer arithmetic to preserve
alignment invariants. Return pointer. All users updated.
(ZAP_LEAF_ENTRY): Make into inline function.
(NBBY): Removed.
(xor): LIkewise.
(xor_out): Use grub_crypto_xor.
(dnode_get_path): Use grub_get_unaligned.
(nvlist_find_value): Likewise.
(grub_zfs_nvlist_lookup_uint64): Likewise.
(grub_zfs_nvlist_lookup_string): Likewise.
(get_nvlist_size): Likewise.
(grub_zfs_open): Likewise.
(fill_fs_info): Likewise.
(grub_zfs_dir): Likewise.
* include/grub/zfs/zap_leaf.h (zap_leaf_phys): Adapt to preserve
alignment invariants.
* include/grub/zfs/zio.h (zio_eck_t): Mark as packed as it's not
necessarily aligned.

ChangeLog
grub-core/fs/zfs/zfs.c
include/grub/zfs/zap_leaf.h
include/grub/zfs/zio.h

index be4b26ba2936948ab1fc1a3f9fe92ea36bf0daf7..fa3c04c63cb7511e44413671a2b9b477f6d9ef5d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2011-12-13  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/fs/zfs/zfs.c (DVA_OFFSET_TO_PHYS_SECTOR): Make into inline
+       function.
+       (ZAP_HASH_IDX): Likewise.
+       (ZAP_LEAF_HASH_SHIFT): Likewise.
+       (ZAP_LEAF_HASH_NUMENTRIES): Likewise.
+       (LEAF_HASH): Likewise.
+       (ZAP_LEAF_NUMCHUNKS): Likewise.
+       (ZAP_LEAF_CHUNK): Likewise. Changed pointer arithmetic to preserve
+       alignment invariants. Return pointer. All users updated.
+       (ZAP_LEAF_ENTRY): Make into inline function.
+       (NBBY): Removed.
+       (xor): LIkewise.
+       (xor_out): Use grub_crypto_xor.
+       (dnode_get_path): Use grub_get_unaligned.
+       (nvlist_find_value): Likewise.
+       (grub_zfs_nvlist_lookup_uint64): Likewise.
+       (grub_zfs_nvlist_lookup_string): Likewise.
+       (get_nvlist_size): Likewise.
+       (grub_zfs_open): Likewise.
+       (fill_fs_info): Likewise.
+       (grub_zfs_dir): Likewise.
+       * include/grub/zfs/zap_leaf.h (zap_leaf_phys): Adapt to preserve
+       alignment invariants.
+       * include/grub/zfs/zio.h (zio_eck_t): Mark as packed as it's not
+       necessarily aligned.
+
 2011-12-13  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/net/netbuff.c (grub_netbuff_alloc): Ensure proper alignment.
index 9de2ab586808f2f3f6fdaff102024703b5131a25..534b7d224b3a09d502095a12c919686ee318b118 100644 (file)
@@ -77,14 +77,23 @@ static grub_dl_t my_mod;
 #endif
 
 #define        P2PHASE(x, align)               ((x) & ((align) - 1))
-#define        DVA_OFFSET_TO_PHYS_SECTOR(offset) \
-       ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT)
+
+static inline grub_disk_addr_t
+DVA_OFFSET_TO_PHYS_SECTOR (grub_disk_addr_t offset)
+{
+  return ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT);
+}
 
 /*
  * FAT ZAP data structures
  */
 #define        ZFS_CRC64_POLY 0xC96C5795D7870F42ULL    /* ECMA-182, reflected form */
-#define        ZAP_HASH_IDX(hash, n)   (((n) == 0) ? 0 : ((hash) >> (64 - (n))))
+static inline grub_uint64_t
+ZAP_HASH_IDX (grub_uint64_t hash, grub_uint64_t n)
+{
+  return (((n) == 0) ? 0 : ((hash) >> (64 - (n))));
+}
+
 #define        CHAIN_END       0xffff  /* end of the chunk chain */
 
 /*
@@ -93,37 +102,60 @@ static grub_dl_t my_mod;
  */
 #define        ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
 
-#define        ZAP_LEAF_HASH_SHIFT(bs) (bs - 5)
-#define        ZAP_LEAF_HASH_NUMENTRIES(bs) (1 << ZAP_LEAF_HASH_SHIFT(bs))
-#define        LEAF_HASH(bs, h) \
-       ((ZAP_LEAF_HASH_NUMENTRIES(bs)-1) & \
-       ((h) >> (64 - ZAP_LEAF_HASH_SHIFT(bs)-l->l_hdr.lh_prefix_len)))
+static inline int
+ZAP_LEAF_HASH_SHIFT (int bs)
+{
+  return bs - 5;
+}
+
+static inline int
+ZAP_LEAF_HASH_NUMENTRIES (int bs)
+{
+  return 1 << ZAP_LEAF_HASH_SHIFT(bs);
+}
+
+static inline grub_size_t
+LEAF_HASH (int bs, grub_uint64_t h, zap_leaf_phys_t *l)
+{
+  return ((ZAP_LEAF_HASH_NUMENTRIES (bs)-1)
+         & ((h) >> (64 - ZAP_LEAF_HASH_SHIFT (bs) - l->l_hdr.lh_prefix_len)));
+}
 
 /*
  * The amount of space available for chunks is:
  * block size shift - hash entry size (2) * number of hash
  * entries - header space (2*chunksize)
  */
-#define        ZAP_LEAF_NUMCHUNKS(bs) \
-       (((1<<bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(bs)) / \
-       ZAP_LEAF_CHUNKSIZE - 2)
+static inline int
+ZAP_LEAF_NUMCHUNKS (int bs)
+{
+  return (((1 << bs) - 2 * ZAP_LEAF_HASH_NUMENTRIES (bs)) /
+         ZAP_LEAF_CHUNKSIZE - 2);
+}
 
 /*
  * The chunks start immediately after the hash table.  The end of the
  * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
  * chunk_t.
  */
-#define        ZAP_LEAF_CHUNK(l, bs, idx) \
-       ((zap_leaf_chunk_t *)(l->l_hash + ZAP_LEAF_HASH_NUMENTRIES(bs)))[idx]
-#define        ZAP_LEAF_ENTRY(l, bs, idx) (&ZAP_LEAF_CHUNK(l, bs, idx).l_entry)
+static inline zap_leaf_chunk_t *
+ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx)
+{
+  return &((zap_leaf_chunk_t *) (l->l_entries 
+                                + (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2)
+                                / sizeof (grub_properly_aligned_t)))[idx];
+}
+
+static inline struct zap_leaf_entry *
+ZAP_LEAF_ENTRY(zap_leaf_phys_t *l, int bs, int idx)
+{
+  return &ZAP_LEAF_CHUNK(l, bs, idx)->l_entry;
+}
 
 
 /*
  * Decompression Entry - lzjb
  */
-#ifndef        NBBY
-#define        NBBY    8
-#endif
 
 extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t);
 
@@ -969,14 +1001,6 @@ scan_devices (struct grub_zfs_data *data)
   return GRUB_ERR_NONE;
 }
 
-static inline void
-xor (grub_uint64_t *a, const grub_uint64_t *b, grub_size_t s)
-{
-  s /= sizeof (grub_uint64_t);
-  while (s--)
-    *a++ ^= *b++;
-}
-
 /* x**y.  */
 static grub_uint8_t powx[255 * 2];
 /* Such an s that x**s = y */
@@ -985,17 +1009,15 @@ static const grub_uint8_t poly = 0x1d;
 
 /* perform the operation a ^= b * (x ** (known_idx * recovery_pow) ) */
 static inline void
-xor_out (void *a_in, const void *b_in, grub_size_t s,
+xor_out (grub_uint8_t *a, const grub_uint8_t *b, grub_size_t s,
         int known_idx, int recovery_pow)
 {
   int add;
-  grub_uint8_t *a = a_in;
-  const grub_uint8_t *b = b_in;
 
   /* Simple xor.  */
   if (known_idx == 0 || recovery_pow == 0)
     {
-      xor (a_in, b_in, s);
+      grub_crypto_xor (a, a, b, s);
       return;
     }
   add = (known_idx * recovery_pow) % 255;
@@ -1827,7 +1849,7 @@ zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
 
   while (bseen < array_len)
     {
-      struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array;
+      struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array;
       int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
 
       if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft))
@@ -1851,7 +1873,7 @@ zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft,
 
   while (bseen < array_len)
     {
-      struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array;
+      struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array;
       int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
 
       if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft))
@@ -1887,7 +1909,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
   if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC)
     return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic");
 
-  for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h)], endian);
+  for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian);
        chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian))
     {
 
@@ -1917,7 +1939,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
            return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry");
 
          /* get the uint64_t property value */
-         la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array;
+         la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk)->l_array;
 
          *value = grub_be_to_cpu64 (la->la_array64);
 
@@ -2552,11 +2574,17 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
 
          hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
 
-         if (((grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_TYPE_OFFSET), dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
+         if (((grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp
+                                                        + hdrsize
+                                                        + SA_TYPE_OFFSET),
+                                  dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
            {
              char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET;
              grub_size_t sym_sz = 
-               grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), dnode_path->dn.endian);
+               grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp
+                                                        + hdrsize
+                                                        + SA_SIZE_OFFSET),
+                                  dnode_path->dn.endian);
              char *oldpath = path, *oldpathbuf = path_buf;
              path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
              if (!path_buf)
@@ -3009,22 +3037,22 @@ nvlist_find_value (const char *nvlist, const char *name,
    * Loop thru the nvpair list
    * The XDR representation of an integer is in big-endian byte order.
    */
-  while ((encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvlist)))
+  while ((encode_size = grub_be_to_cpu32 (grub_get_unaligned32 (nvlist))))
     {
       int nelm;
 
       nvpair = nvlist + 4 * 2; /* skip the encode/decode size */
 
-      name_len = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair);
+      name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
       nvpair += 4;
 
       nvp_name = nvpair;
       nvpair = nvpair + ((name_len + 3) & ~3); /* align */
 
-      type = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair);
+      type = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
       nvpair += 4;
 
-      nelm = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair);
+      nelm = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
       if (nelm < 1)
        return grub_error (GRUB_ERR_BAD_FS, "empty nvpair");
 
@@ -3061,7 +3089,7 @@ grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name,
       return 0;
     }
 
-  *out = grub_be_to_cpu64 (*(grub_uint64_t *) nvpair);
+  *out = grub_be_to_cpu64 (grub_get_unaligned64 (nvpair));
   return 1;
 }
 
@@ -3082,7 +3110,7 @@ grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name)
       grub_error (GRUB_ERR_BAD_FS, "invalid string");
       return 0;
     }
-  slen = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair);
+  slen = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
   if (slen > size - 4)
     slen = size - 4;
   ret = grub_malloc (slen + 1);
@@ -3138,7 +3166,7 @@ get_nvlist_size (const char *beg, const char *limit)
   ptr = beg + 8;
 
   while (ptr < limit
-        && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) ptr)))
+        && (encode_size = grub_be_to_cpu32 (grub_get_unaligned32 (ptr))))
     ptr += encode_size;        /* goto the next nvpair */
   ptr += 8;      
   return (ptr > limit) ? -1 : (ptr - beg);
@@ -3453,7 +3481,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
        }
 
       hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
-      file->size = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian);
+      file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian);
     }
   else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE)
     {
@@ -3645,7 +3673,7 @@ fill_fs_info (struct grub_dirhook_info *info,
 
       hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
       info->mtimeset = 1;
-      info->mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
+      info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
     }
 
   if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
@@ -3706,7 +3734,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
 
        hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
        info.mtimeset = 1;
-       info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
+       info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
        info.case_insensitive = data->subvol.case_insensitive;
       }
     
index 5adfdc2900f7d25c7199fe8cdbabe09d0502834a..f2b7cb1da091d0b56b14761341fd5687c0309732 100644 (file)
@@ -69,7 +69,8 @@ typedef struct zap_leaf_phys {
         * with the ZAP_LEAF_CHUNK() macro.
         */
 
-       grub_uint16_t l_hash[1];
+       grub_uint16_t l_hash[0];
+        grub_properly_aligned_t l_entries[0];
 } zap_leaf_phys_t;
 
 typedef union zap_leaf_chunk {
index 8b645c0630dd0422174d44866cfe6a2bbd09b66b..b1c46da3ae837a5f7735984bdf70d2aa87ddfdf8 100644 (file)
@@ -30,7 +30,7 @@
 typedef struct zio_eck {
        grub_uint64_t   zec_magic;      /* for validation, endianness   */
        zio_cksum_t     zec_cksum;      /* 256-bit checksum             */
-} zio_eck_t;
+} __attribute__ ((packed)) zio_eck_t;
 
 /*
  * Gang block headers are self-checksumming and contain an array