io->refcount = 1;
io->flags = 0;
+ if (safe_getenv("UNIX_IO_NOZEROOUT"))
+ io->flags |= CHANNEL_FLAGS_NOZEROOUT;
+
memset(data, 0, sizeof(struct unix_private_data));
data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
data->io_stats.num_fields = 2;
* zero.
*/
if (ext2fs_fstat(data->dev, &st) == 0) {
- if (ext2fsP_is_disk_device(st.st_mode))
+ if (ext2fsP_is_disk_device(st.st_mode)) {
+#ifdef BLKDISCARDZEROES
+ int zeroes = 0;
+
+ if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 &&
+ zeroes)
+ io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
+#endif
io->flags |= CHANNEL_FLAGS_BLOCK_DEVICE;
- else
+ } else {
io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
+ }
}
-#ifdef BLKDISCARDZEROES
- {
- int zeroes = 0;
- if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 &&
- zeroes)
- io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
- }
-#endif
-
#if defined(__CYGWIN__)
/*
* Some operating systems require that the buffers be aligned,
unsigned long long count)
{
struct unix_private_data *data;
- int ret;
+ int ret = EOPNOTSUPP;
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
data = (struct unix_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+ if (channel->flags & CHANNEL_FLAGS_NODISCARD)
+ goto unimplemented;
+
if (channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE) {
#ifdef BLKDISCARD
__u64 range[2];
#endif
}
if (ret < 0) {
- if (errno == EOPNOTSUPP)
+ if (errno == EOPNOTSUPP) {
+ channel->flags |= CHANNEL_FLAGS_NODISCARD;
goto unimplemented;
+ }
return errno;
}
return 0;
data = (struct unix_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
- if (safe_getenv("UNIX_IO_NOZEROOUT"))
- goto unimplemented;
-
if (!(channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE)) {
/* Regular file, try to use truncate/punch/zero. */
struct stat statbuf;
}
}
+ if (channel->flags & CHANNEL_FLAGS_NOZEROOUT)
+ goto unimplemented;
+
ret = __unix_zeroout(data->dev,
(off_t)(block) * channel->block_size + data->offset,
(off_t)(count) * channel->block_size);
err:
if (ret < 0) {
- if (errno == EOPNOTSUPP)
+ if (errno == EOPNOTSUPP) {
+ channel->flags |= CHANNEL_FLAGS_NOZEROOUT;
goto unimplemented;
+ }
return errno;
}
return 0;