copy.c: ensure proper alignment of fiemap buffer
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 9 Jun 2010 06:15:07 +0000 (08:15 +0200)
committerJim Meyering <meyering@redhat.com>
Sun, 30 Jan 2011 19:44:11 +0000 (20:44 +0100)
* src/copy.c (fiemap_copy): Ensure that our fiemap buffer
is large enough and well-aligned.
Replace "0LL" with equivalent "0" as 3rd argument to lseek.

src/copy.c

index 6bb0506..1d32913 100644 (file)
@@ -170,11 +170,12 @@ fiemap_copy (int src_fd, int dest_fd, size_t buf_size,
              char const *dst_name, bool *normal_copy_required)
 {
   bool last = false;
-  char fiemap_buf[4096];
-  struct fiemap *fiemap = (struct fiemap *) fiemap_buf;
+  union { struct fiemap f; char c[4096]; } fiemap_buf;
+  struct fiemap *fiemap = &fiemap_buf.f;
   struct fiemap_extent *fm_ext = &fiemap->fm_extents[0];
-  uint32_t count = ((sizeof fiemap_buf - sizeof (*fiemap))
-                    / sizeof (struct fiemap_extent));
+  enum { count = (sizeof fiemap_buf - sizeof *fiemap) / sizeof *fm_ext };
+  verify (count != 0);
+
   off_t last_ext_logical = 0;
   uint64_t last_ext_len = 0;
   uint64_t last_read_size = 0;
@@ -184,7 +185,7 @@ fiemap_copy (int src_fd, int dest_fd, size_t buf_size,
   /* This is required at least to initialize fiemap->fm_start,
      but also serves (in mid 2010) to appease valgrind, which
      appears not to know the semantics of the FIEMAP ioctl. */
-  memset (fiemap_buf, 0, sizeof fiemap_buf);
+  memset (&fiemap_buf, 0, sizeof fiemap_buf);
 
   do
     {
@@ -219,13 +220,13 @@ fiemap_copy (int src_fd, int dest_fd, size_t buf_size,
           off_t ext_logical = fm_ext[i].fe_logical;
           uint64_t ext_len = fm_ext[i].fe_length;
 
-          if (lseek (src_fd, ext_logical, SEEK_SET) < 0LL)
+          if (lseek (src_fd, ext_logical, SEEK_SET) < 0)
             {
               error (0, errno, _("cannot lseek %s"), quote (src_name));
               return false;
             }
 
-          if (lseek (dest_fd, ext_logical, SEEK_SET) < 0LL)
+          if (lseek (dest_fd, ext_logical, SEEK_SET) < 0)
             {
               error (0, errno, _("cannot lseek %s"), quote (dst_name));
               return false;