[Ocfs-tools-commits] manish commits r164 - trunk/ocfs2/libocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Jul 19 19:33:06 CDT 2004


Author: manish
Date: 2004-07-19 18:33:03 -0500 (Mon, 19 Jul 2004)
New Revision: 164

Added:
   trunk/ocfs2/libocfs2/getsize.c
Log:
Oops, add getsize.c


Added: trunk/ocfs2/libocfs2/getsize.c
===================================================================
--- trunk/ocfs2/libocfs2/getsize.c	2004-07-19 23:02:06 UTC (rev 163)
+++ trunk/ocfs2/libocfs2/getsize.c	2004-07-19 23:33:03 UTC (rev 164)
@@ -0,0 +1,278 @@
+/*
+ * getsize.c --- get the size of a partition.
+ * 
+ * Copyright (C) 1995, 1995 Theodore Ts'o.
+ * Copyright (C) 2003 VMware, Inc.
+ *
+ * Windows version of ext2fs_get_device_size by Chris Li, VMware.
+ * 
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+/* Modified for OCFS2 by Manish Singh <manish.singh at oracle.com> */
+
+#define HAVE_UNISTD_H 1
+#define HAVE_ERRNO_H 1
+#define HAVE_LINUX_FD_H 1
+#define HAVE_OPEN64 1
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <fcntl.h>
+#ifdef HAVE_LINUX_FD_H
+#include <sys/ioctl.h>
+#include <linux/fd.h>
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#endif /* HAVE_SYS_DISKLABEL_H */
+#ifdef HAVE_SYS_DISK_H
+#include <sys/queue.h> /* for LIST_HEAD */
+#include <sys/disk.h>
+#endif /* HAVE_SYS_DISK_H */
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+
+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
+#define BLKGETSIZE _IO(0x12,96)	/* return device size */
+#endif
+
+#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)	/* return device size in bytes (u64 *arg) */
+#endif
+
+#ifdef APPLE_DARWIN
+#include <sys/ioctl.h>
+#include <sys/disk.h>
+
+#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
+#endif /* APPLE_DARWIN */
+
+#include "ocfs2.h"
+
+#if defined(__CYGWIN__) || defined (WIN32)
+#include "windows.h"
+#include "winioctl.h"
+
+errcode_t ocfs2_get_device_size(const char *file, int blocksize,
+				uint32_t *retblocks)
+{
+	HANDLE dev;
+	PARTITION_INFORMATION pi;
+	DISK_GEOMETRY gi;
+	DWORD retbytes;
+	LARGE_INTEGER filesize;
+
+	dev = CreateFile(file, GENERIC_READ, 
+			 FILE_SHARE_READ | FILE_SHARE_WRITE ,
+                	 NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  NULL); 
+ 
+	if (dev == INVALID_HANDLE_VALUE)
+		return EBADF;
+	if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
+			    &pi, sizeof(PARTITION_INFORMATION),
+			    &pi, sizeof(PARTITION_INFORMATION),
+			    &retbytes, NULL)) {
+
+		*retblocks = pi.PartitionLength.QuadPart / blocksize;
+	
+	} else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
+				&gi, sizeof(DISK_GEOMETRY),
+				&gi, sizeof(DISK_GEOMETRY),
+				&retbytes, NULL)) {
+
+		*retblocks = gi.BytesPerSector *
+			     gi.SectorsPerTrack *
+			     gi.TracksPerCylinder *
+			     gi.Cylinders.QuadPart / blocksize;
+
+	} else if (GetFileSizeEx(dev, &filesize)) {
+		*retblocks = filesize.QuadPart / blocksize;
+	}
+
+	CloseHandle(dev);
+	return 0;
+}
+
+#else
+
+static int valid_offset (int fd, off64_t offset)
+{
+	char ch;
+
+	if (lseek64 (fd, offset, 0) < 0)
+		return 0;
+	if (read (fd, &ch, 1) < 1)
+		return 0;
+	return 1;
+}
+
+/*
+ * Returns the number of blocks in a partition
+ */
+errcode_t ocfs2_get_device_size(const char *file, int blocksize,
+				 uint32_t *retblocks)
+{
+	int	fd;
+	int valid_blkgetsize64 = 1;
+#ifdef __linux__
+	struct 		utsname ut;
+#endif
+	unsigned long long size64;
+	unsigned long	size;
+	off64_t high, low;
+#ifdef FDGETPRM
+	struct floppy_struct this_floppy;
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+	int part;
+	struct disklabel lab;
+	struct partition *pp;
+	char ch;
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+#ifdef HAVE_OPEN64
+	fd = open64(file, O_RDONLY);
+#else
+	fd = open(file, O_RDONLY);
+#endif
+	if (fd < 0)
+		return errno;
+
+#ifdef DKIOCGETBLOCKCOUNT	/* For Apple Darwin */
+	if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
+		if ((sizeof(*retblocks) < sizeof(unsigned long long))
+		    && ((size64 / (blocksize / 512)) > 0xFFFFFFFF))
+			return EFBIG;
+		close(fd);
+		*retblocks = size64 / (blocksize / 512);
+		return 0;
+	}
+#endif
+
+#ifdef BLKGETSIZE64
+#ifdef __linux__
+	if ((uname(&ut) == 0) &&
+	    ((ut.release[0] == '2') && (ut.release[1] == '.') &&
+	     (ut.release[2] < '6') && (ut.release[3] == '.')))
+		valid_blkgetsize64 = 0;
+#endif
+	if (valid_blkgetsize64 &&
+	    ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
+		if ((sizeof(*retblocks) < sizeof(unsigned long long))
+		    && ((size64 / blocksize) > 0xFFFFFFFF))
+			return EFBIG;
+		close(fd);
+		*retblocks = size64 / blocksize;
+		return 0;
+	}
+#endif
+
+#ifdef BLKGETSIZE
+	if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
+		close(fd);
+		*retblocks = size / (blocksize / 512);
+		return 0;
+	}
+#endif
+
+#ifdef FDGETPRM
+	if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
+		close(fd);
+		*retblocks = this_floppy.size / (blocksize / 512);
+		return 0;
+	}
+#endif
+
+#ifdef HAVE_SYS_DISKLABEL_H
+#if defined(DIOCGMEDIASIZE)
+	{
+	    off_t ms;
+	    u_int bs;
+	    if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) {
+		*retblocks = ms / blocksize;
+		return 0;
+	    }
+	}
+#elif defined(DIOCGDINFO)
+	/* old disklabel interface */
+	part = strlen(file) - 1;
+	if (part >= 0) {
+		ch = file[part];
+		if (isdigit(ch))
+			part = 0;
+		else if (ch >= 'a' && ch <= 'h')
+			part = ch - 'a';
+		else
+			part = -1;
+	}
+	if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
+		pp = &lab.d_partitions[part];
+		if (pp->p_size) {
+			close(fd);
+			*retblocks = pp->p_size / (blocksize / 512);
+			return 0;
+		}
+	}
+#endif /* defined(DIOCG*) */
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+	/*
+	 * OK, we couldn't figure it out by using a specialized ioctl,
+	 * which is generally the best way.  So do binary search to
+	 * find the size of the partition.
+	 */
+	low = 0;
+	for (high = 1024; valid_offset (fd, high); high *= 2)
+		low = high;
+	while (low < high - 1)
+	{
+		const off64_t mid = (low + high) / 2;
+
+		if (valid_offset (fd, mid))
+			low = mid;
+		else
+			high = mid;
+	}
+	valid_offset (fd, 0);
+	close(fd);
+	*retblocks = (low + 1) / blocksize;
+	return 0;
+}
+
+#endif /* WIN32 */
+
+#ifdef DEBUG
+int main(int argc, char **argv)
+{
+	uint32_t blocks;
+	int	 retval;
+	
+	if (argc < 2) {
+		fprintf(stderr, "Usage: %s device\n", argv[0]);
+		exit(1);
+	}
+
+	retval = ocfs2_get_device_size(argv[1], 1024, &blocks);
+	if (retval) {
+		com_err(argv[0], retval,
+			"while calling ocfs2_get_device_size");
+		exit(1);
+	}
+	printf("Device %s has %d 1k blocks.\n", argv[1], blocks);
+	exit(0);
+}
+#endif



More information about the Ocfs-tools-commits mailing list