From: Li Wei Date: Fri, 22 Mar 2013 06:41:11 +0000 (+0800) Subject: LU-3014 utils: Fix an offset overflow in file_create() X-Git-Tag: 2.3.65~47 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=980a7dfbbca1af55d8631063e739416eef595f88 LU-3014 utils: Fix an offset overflow in file_create() 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 Reviewed-on: http://review.whamcloud.com/5805 Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Andreas Dilger --- diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index bc8d716..a353557 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -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 diff --git a/lustre/utils/mount_utils.c b/lustre/utils/mount_utils.c index 00e5d5c..00400df 100644 --- a/lustre/utils/mount_utils.c +++ b/lustre/utils/mount_utils.c @@ -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); diff --git a/lustre/utils/mount_utils.h b/lustre/utils/mount_utils.h index 56d987e..912d0a4 100644 --- a/lustre/utils/mount_utils.h +++ b/lustre/utils/mount_utils.h @@ -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);