1 /* 2 * getsectsize.c --- get the sector size of a device. 3 * 4 * Copyright (C) 1995, 1995 Theodore Ts'o. 5 * Copyright (C) 2003 VMware, Inc. 6 * 7 * %Begin-Header% 8 * This file may be redistributed under the terms of the GNU Library 9 * General Public License, version 2. 10 * %End-Header% 11 */ 12 13 #ifndef _LARGEFILE_SOURCE 14 #define _LARGEFILE_SOURCE 15 #endif 16 #ifndef _LARGEFILE64_SOURCE 17 #define _LARGEFILE64_SOURCE 18 #endif 19 20 #include "config.h" 21 #include <stdio.h> 22 #if HAVE_UNISTD_H 23 #include <unistd.h> 24 #endif 25 #if HAVE_ERRNO_H 26 #include <errno.h> 27 #endif 28 #include <fcntl.h> 29 #ifdef HAVE_SYS_DISK_H 30 #include <sys/disk.h> 31 #endif 32 #ifdef HAVE_LINUX_FD_H 33 #include <sys/ioctl.h> 34 #include <linux/fd.h> 35 #endif 36 37 #if defined(__linux__) && defined(_IO) 38 #if !defined(BLKSSZGET) 39 #define BLKSSZGET _IO(0x12,104)/* get block device sector size */ 40 #endif 41 #if !defined(BLKPBSZGET) 42 #define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */ 43 #endif 44 #endif 45 46 #include "ext2_fs.h" 47 #include "ext2fs.h" 48 49 /* 50 * Returns the logical sector size of a device 51 */ 52 errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize) 53 { 54 int fd; 55 56 fd = ext2fs_open_file(file, O_RDONLY, 0); 57 if (fd < 0) 58 return errno; 59 60 #ifdef BLKSSZGET 61 if (ioctl(fd, BLKSSZGET, sectsize) >= 0) { 62 close(fd); 63 return 0; 64 } 65 #endif 66 #ifdef DIOCGSECTORSIZE 67 if (ioctl(fd, DIOCGSECTORSIZE, sectsize) >= 0) { 68 close(fd); 69 return 0; 70 } 71 #endif 72 *sectsize = 0; 73 close(fd); 74 return 0; 75 } 76 77 /* 78 * Return desired alignment for direct I/O 79 */ 80 int ext2fs_get_dio_alignment(int fd) 81 { 82 int align = 0; 83 84 #ifdef BLKSSZGET 85 if (ioctl(fd, BLKSSZGET, &align) < 0) 86 align = 0; 87 #endif 88 #ifdef DIOCGSECTORSIZE 89 if (align <= 0 && 90 ioctl(fd, DIOCGSECTORSIZE, &align) < 0) 91 align = 0; 92 #endif 93 94 #ifdef _SC_PAGESIZE 95 if (align <= 0) 96 align = sysconf(_SC_PAGESIZE); 97 #endif 98 #ifdef HAVE_GETPAGESIZE 99 if (align <= 0) 100 align = getpagesize(); 101 #endif 102 if (align <= 0) 103 align = 4096; 104 105 return align; 106 } 107 108 /* 109 * Returns the physical sector size of a device 110 */ 111 errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize) 112 { 113 int fd; 114 115 fd = ext2fs_open_file(file, O_RDONLY, 0); 116 if (fd < 0) 117 return errno; 118 119 #ifdef BLKPBSZGET 120 if (ioctl(fd, BLKPBSZGET, sectsize) >= 0) { 121 close(fd); 122 return 0; 123 } 124 #endif 125 #ifdef DIOCGSECTORSIZE 126 /* This isn't really the physical sector size, but FreeBSD 127 * doesn't seem to have this concept. */ 128 if (ioctl(fd, DIOCGSECTORSIZE, sectsize) >= 0) { 129 close(fd); 130 return 0; 131 } 132 #endif 133 *sectsize = 0; 134 close(fd); 135 return 0; 136 }