Whamcloud - gitweb
LU-3014 utils: Fix an offset overflow in file_create()
authorLi Wei <wei.g.li@intel.com>
Fri, 22 Mar 2013 06:41:11 +0000 (14:41 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 29 Apr 2013 22:08:56 +0000 (18:08 -0400)
On an x86_64 machine, creating a 3 GB ZFS-based target using a file
VDev failed like this:

  mkfs.lustre FATAL: mkfs.lustre: Unable to truncate backing store:
  Invalid argument

The error, returned by the ftruncate() call in file_create(), was due
to the "int"-type calculation for the "off_t" argument.  The byte
number of 3 GB overflowed the "int" type and became a negative
"off_t".  This patch changes file_create() to take an "__u64" size
instead of an "int" one and adds "_FILE_OFFSET_BITS=64" to the
AM_CPPFLAGS of lustre/utils, so that file VDevs larger than 2 GB can
be created on both 32-bit and 64-bit x86 architectures.

Change-Id: Id7e6bfc963b0ccba8266795ba2bf9832e9c641ba
Signed-off-by: Li Wei <wei.g.li@intel.com>
Reviewed-on: http://review.whamcloud.com/5805
Tested-by: Hudson
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/utils/Makefile.am
lustre/utils/mount_utils.c
lustre/utils/mount_utils.h

index bc8d716..a353557 100644 (file)
@@ -5,7 +5,7 @@ SUBDIRS = gss
 endif
 
 AM_CFLAGS=$(LLCFLAGS)
-AM_CPPFLAGS=$(LLCPPFLAGS) -DLUSTRE_UTILS=1
+AM_CPPFLAGS=$(LLCPPFLAGS) -DLUSTRE_UTILS=1 -D_FILE_OFFSET_BITS=64
 AM_LDFLAGS := -L$(top_builddir)/lnet/utils
 
 LIBPTLCTL := $(top_builddir)/lnet/utils/libptlctl.a \
@@ -124,6 +124,7 @@ llog_reader_DEPENDENCIES := $(LIBPTLCTL)
 lr_reader_SOURCES = lr_reader.c
 
 mount_lustre_SOURCES = mount_lustre.c mount_utils.c mount_utils.h
+mount_lustre_CPPFLAGS = $(AM_CPPFLAGS)
 mount_lustre_LDADD := $(LIBPTLCTL)
 mount_lustre_DEPENDENCIES := $(LIBPTLCTL)
 if LDISKFS_ENABLED
@@ -131,7 +132,7 @@ mount_lustre_SOURCES += mount_utils_ldiskfs.c
 endif
 if ZFS_ENABLED
 mount_lustre_SOURCES += mount_utils_zfs.c
-mount_lustre_CPPFLAGS = -DHAVE_IOCTL_IN_UNISTD_H
+mount_lustre_CPPFLAGS += -DHAVE_IOCTL_IN_UNISTD_H
 mount_lustre_CPPFLAGS += $(EXTRA_LIBZFS_INCLUDE)
 mount_lustre_LDFLAGS = -pthread -rdynamic -ldl
 endif
index 00e5d5c..00400df 100644 (file)
@@ -689,11 +689,23 @@ __u64 get_device_size(char* device)
        return size >> 10;
 }
 
-int file_create(char *path, int size)
+int file_create(char *path, __u64 size)
 {
+       __u64 size_max;
        int ret;
        int fd;
 
+       /*
+        * Since "size" is in KB, the file offset it represents could overflow
+        * off_t.
+        */
+       size_max = (off_t)1 << (_FILE_OFFSET_BITS - 1 - 10);
+       if (size >= size_max) {
+               fprintf(stderr, "%s: %llu KB: Backing store size must be "
+                       "smaller than %llu KB\n", progname, size, size_max);
+               return EFBIG;
+       }
+
        ret = access(path, F_OK);
        if (ret == 0) {
                ret = unlink(path);
index 56d987e..912d0a4 100644 (file)
@@ -131,7 +131,7 @@ int read_local_files(struct mkfs_opts *mop);
 int is_lustre_target(struct mkfs_opts *mop);
 
 /* loopback helper functions */
-int file_create(char *path, int size);
+int file_create(char *path, __u64 size);
 int loop_format(struct mkfs_opts *mop);
 int loop_setup(struct mkfs_opts *mop);
 int loop_cleanup(struct mkfs_opts *mop);