Package: mdadm
Version: 2.6.4-1
Severity: minor
Tags: patch

I made an image of 2 disks that are part of a 2 disk raid0.  These images are
320gb in size.  I tried to use mdadm -E to give me some information about
them which resulted in:
# mdadm -E /junk/nail.md0-part1of2.img
mdadm: cannot open /junk/nail.md0-part1of2.img: File too large
# 

I modified the source to use O_LARGEFILE in open which gave me an error
stating that the "device" was not recognised.  mdadm does not stat files to
obtain the size, it only uses ioctl's.  The patch adds O_LARGEFILE and tests
to see if the device is a file and uses that information instead.

This worked for me, but I only modified for -Q and -E.  I did not attempt to
assemble the array.

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.23
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages mdadm depends on:
ii  debconf                       1.5.19     Debian configuration management sy
ii  libc6                         2.7-5      GNU C Library: Shared libraries
ii  lsb-base                      3.1-22     Linux Standard Base 3.1 init scrip
ii  makedev                       2.3.1-75   Creates device files in /dev

Versions of packages mdadm recommends:
ii  exim4-daemon-custom [mail-tra 10:4.63-10 custom exim MTA (v4) daemon with l
ii  module-init-tools             3.2.2-3    tools for managing Linux kernel mo

-- debconf information excluded
diff -ru mdadm-2.6.4-orig/Query.c mdadm-2.6.4/Query.c
--- mdadm-2.6.4-orig/Query.c	2007-10-18 23:59:52.000000000 -0400
+++ mdadm-2.6.4/Query.c	2008-02-02 20:33:30.000000000 -0500
@@ -37,7 +37,7 @@
 	 * whether it is an md device and whether it has 
 	 * a superblock
 	 */
-	int fd = open(dev, O_RDONLY, 0);
+	int fd = open(dev, O_RDONLY | O_LARGEFILE, 0);
 	int vers;
 	int ioctlerr;
 	int superror, superrno;
@@ -101,7 +101,7 @@
 			mddev = get_md_name(info.array.md_minor);
 			disc.number = info.disk.number;
 			activity = "undetected";
-			if (mddev && (fd = open(mddev, O_RDONLY))>=0) {
+			if (mddev && (fd = open(mddev, O_RDONLY | O_LARGEFILE))>=0) {
 				if (md_get_version(fd) >= 9000 &&	
 				    ioctl(fd, GET_ARRAY_INFO, &array)>= 0) {
 					if (ioctl(fd, GET_DISK_INFO, &disc) >= 0 &&
diff -ru mdadm-2.6.4-orig/mdadm.h mdadm-2.6.4/mdadm.h
--- mdadm-2.6.4-orig/mdadm.h	2007-10-18 23:59:53.000000000 -0400
+++ mdadm-2.6.4/mdadm.h	2008-02-02 21:08:30.000000000 -0500
@@ -28,6 +28,7 @@
  */
 
 #define	_GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
 #include	<unistd.h>
 #if !defined(__dietlibc__) && !defined(__KLIBC__)
 extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
diff -ru mdadm-2.6.4-orig/util.c mdadm-2.6.4/util.c
--- mdadm-2.6.4-orig/util.c	2007-10-18 23:59:53.000000000 -0400
+++ mdadm-2.6.4/util.c	2008-02-02 21:10:29.000000000 -0500
@@ -711,6 +711,7 @@
 
 	if (!dev) return -1;
 
+	flags |= O_LARGEFILE;
 	major = strtoul(dev, &e, 0);
 	if (e > dev && *e == ':' && e[1] &&
 	    (minor = strtoul(e+1, &e, 0)) >= 0 &&
@@ -792,6 +793,13 @@
 int get_dev_size(int fd, char *dname, unsigned long long *sizep)
 {
 	unsigned long long ldsize;
+	struct stat st;
+
+	if (fstat(fd, &st) != -1 && S_ISREG(st.st_mode))
+	{
+	 ldsize = (unsigned long long)st.st_size;
+	}
+	else
 #ifdef BLKGETSIZE64
 	if (ioctl(fd, BLKGETSIZE64, &ldsize) != 0)
 #endif

Reply via email to