}
/*
+ * Return desired alignment for direct I/O
+ */
+int ext2fs_get_dio_alignment(int fd)
+{
+ int align = 0;
+
+#ifdef BLKSSZGET
+ if (ioctl(fd, BLKSSZGET, &align) < 0)
+ align = 0;
+#endif
+
+#ifdef _SC_PAGESIZE
+ if (align <= 0)
+ align = sysconf(_SC_PAGESIZE);
+#endif
+#ifdef HAVE_GETPAGESIZE
+ if (align <= 0)
+ align = getpagesize();
+#endif
+ if (align <= 0)
+ align = 4096;
+
+ return align;
+}
+
+/*
* Returns the physical sector size of a device
*/
errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize)
#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
-static int mmp_pagesize(void)
-{
-#ifdef _SC_PAGESIZE
- int sysval = sysconf(_SC_PAGESIZE);
- if (sysval > 0)
- return sysval;
-#endif /* _SC_PAGESIZE */
-#ifdef HAVE_GETPAGESIZE
- return getpagesize();
-#else
- return 4096;
-#endif
-}
-
#ifndef O_DIRECT
#define O_DIRECT 0
#endif
(mmp_blk >= fs->super->s_blocks_count))
return EXT2_ET_MMP_BAD_BLOCK;
- if (fs->mmp_cmp == NULL) {
- /* O_DIRECT in linux 2.4: page aligned
- * O_DIRECT in linux 2.6: sector aligned
- * A filesystem cannot be created with blocksize < sector size,
- * or with blocksize > page_size. */
- int bufsize = fs->blocksize;
-
- if (bufsize < mmp_pagesize())
- bufsize = mmp_pagesize();
- retval = ext2fs_get_memalign(bufsize, bufsize, &fs->mmp_cmp);
- if (retval)
- return retval;
- }
-
/* ext2fs_open() reserves fd0,1,2 to avoid stdio collision, so checking
* mmp_fd <= 0 is OK to validate that the fd is valid. This opens its
* own fd to read the MMP block to ensure that it is using O_DIRECT,
}
}
+ if (fs->mmp_cmp == NULL) {
+ int align = ext2fs_get_dio_alignment(fs->mmp_fd);
+
+ retval = ext2fs_get_memalign(fs->blocksize, align,
+ &fs->mmp_cmp);
+ if (retval)
+ return retval;
+ }
+
if (ext2fs_llseek(fs->mmp_fd, mmp_blk * fs->blocksize, SEEK_SET) !=
mmp_blk * fs->blocksize) {
retval = EXT2_ET_LLSEEK_FAILED;
#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */
#endif
-#if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
-#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
-#endif
-
#undef ALIGN_DEBUG
#include "ext2_fs.h"
if (flags & IO_FLAG_EXCLUSIVE)
open_flags |= O_EXCL;
#if defined(O_DIRECT)
- if (flags & IO_FLAG_DIRECT_IO)
+ if (flags & IO_FLAG_DIRECT_IO) {
open_flags |= O_DIRECT;
+ io->align = ext2fs_get_dio_alignment(data->dev);
+ }
#elif defined(F_NOCACHE)
- if (flags & IO_FLAG_DIRECT_IO)
+ if (flags & IO_FLAG_DIRECT_IO) {
f_nocache = F_NOCACHE;
+ io->align = 4096;
+ }
#endif
data->flags = flags;
io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
}
-#ifdef BLKSSZGET
- if (flags & IO_FLAG_DIRECT_IO) {
- if (ioctl(data->dev, BLKSSZGET, &io->align) != 0)
- io->align = io->block_size;
- }
-#endif
-
#ifdef BLKDISCARDZEROES
ioctl(data->dev, BLKDISCARDZEROES, &zeroes);
if (zeroes)
* Some operating systems require that the buffers be aligned,
* regardless of O_DIRECT
*/
- io->align = 512;
+ if (!io->align)
+ io->align = 512;
#endif