In order to provide generic "discard" function for all e2fsprogs tools add a discard function prototype into struct_io_manager. Specific function for specific io managers can be crated that way. This commit also creates unix_discard function which uses BLKDISCARD ioctl to discard data blocks on the block device and bind it into unit_io_manager structure to be available for all e2fsprogs tools. Note that BLKDISCARD is still Linux specific ioctl, however other unix systems may provide similar functionality. So far the unix_discard() remains linux specific hence is embedded in #ifdef __linux__ macro. Signed-off-by: Lukas Czerner <lczerner@xxxxxxxxxx> --- lib/ext2fs/ext2_io.h | 2 ++ lib/ext2fs/unix_io.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/lib/ext2fs/ext2_io.h b/lib/ext2fs/ext2_io.h index ccc9c8b..d202007 100644 --- a/lib/ext2fs/ext2_io.h +++ b/lib/ext2fs/ext2_io.h @@ -83,6 +83,8 @@ struct struct_io_manager { int count, void *data); errcode_t (*write_blk64)(io_channel channel, unsigned long long block, int count, const void *data); + errcode_t (*discard)(io_channel channel, unsigned long long block, + unsigned long long count, const void *data); long reserved[16]; }; diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index 1df1fdd..5b6cdec 100644 --- a/lib/ext2fs/unix_io.c +++ b/lib/ext2fs/unix_io.c @@ -115,6 +115,8 @@ static errcode_t unix_read_blk64(io_channel channel, unsigned long long block, int count, void *data); static errcode_t unix_write_blk64(io_channel channel, unsigned long long block, int count, const void *data); +static errcode_t unix_discard(io_channel channel, unsigned long long block, + unsigned long long count, const void *data); static struct struct_io_manager struct_unix_manager = { EXT2_ET_MAGIC_IO_MANAGER, @@ -130,6 +132,7 @@ static struct struct_io_manager struct_unix_manager = { unix_get_stats, unix_read_blk64, unix_write_blk64, + unix_discard, }; io_manager unix_io_manager = &struct_unix_manager; @@ -834,3 +837,41 @@ static errcode_t unix_set_option(io_channel channel, const char *option, } return EXT2_ET_INVALID_ARGUMENT; } + +#ifdef __linux__ + +#ifndef BLKDISCARD +#define BLKDISCARD _IO(0x12,119) +#endif + +static errcode_t unix_discard(io_channel channel, unsigned long long block, + unsigned long long count, const void *data) +{ + + struct struct_ext2_filsys *fs; + struct unix_private_data *u_priv; + errcode_t retval = 0; + __uint64_t range[2]; + int blocksize; + + EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); + u_priv = (struct unix_private_data *) channel->private_data; + EXT2_CHECK_MAGIC(u_priv, EXT2_ET_MAGIC_UNIX_IO_CHANNEL); + + fs = (struct struct_ext2_filsys *) data; + if (!fs) + return EXT2_ET_INVALID_ARGUMENT; + + blocksize = EXT2_BLOCK_SIZE(fs->super); + + range[0] = (__uint64_t)(block); + range[1] = (__uint64_t)(count); + range[0] *= (__uint64_t)(blocksize); + range[1] *= (__uint64_t)(blocksize); + + return ioctl(u_priv->dev, BLKDISCARD, &range); +} + +#else +#define unix_discard(channel, block, count) EXT2_ET_UNIMPLEMENTED +#endif -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html