io_manager.c revision a6ce1349539f866334ef3d5758bc2ee44a454acd
146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)/*
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) * io_manager.c --- the I/O manager abstraction
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) */
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <stdio.h>
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string.h>
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if HAVE_UNISTD_H
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <unistd.h>
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <fcntl.h>
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <time.h>
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if HAVE_SYS_STAT_H
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <sys/stat.h>
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if HAVE_SYS_TYPES_H
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <sys/types.h>
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ext2_fs.h"
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ext2fs.h"
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccierrcode_t io_channel_set_options(io_channel channel, const char *opts)
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)	errcode_t retval = 0;
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)	char *next, *ptr, *options, *arg;
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if (!opts)
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		return 0;
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if (!channel->manager->set_option)
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)		return EXT2_ET_INVALID_ARGUMENT;
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)	options = malloc(strlen(opts)+1);
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if (!options)
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch		return EXT2_ET_NO_MEMORY;
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch	strcpy(options, opts);
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	ptr = options;
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	while (ptr && *ptr) {
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		next = strchr(ptr, '&');
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch		if (next)
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch			*next++ = 0;
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		arg = strchr(ptr, '=');
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		if (arg)
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)			*arg++ = 0;
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		retval = (channel->manager->set_option)(channel, ptr, arg);
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		if (retval)
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)			break;
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		ptr = next;
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	}
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	free(options);
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	return retval;
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)errcode_t io_channel_write_byte(io_channel channel, unsigned long offset,
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)				int count, const void *data)
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if (channel->manager->write_byte)
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch		return channel->manager->write_byte(channel, offset,
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)						    count, data);
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	return EXT2_ET_UNIMPLEMENTED;
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)errcode_t io_channel_read_blk64(io_channel channel, unsigned long long block,
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)				 int count, void *data)
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if (channel->manager->read_blk64)
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		return (channel->manager->read_blk64)(channel, block,
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)						      count, data);
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if ((block >> 32) != 0)
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)		return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64;
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	return (channel->manager->read_blk)(channel, (unsigned long) block,
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)					     count, data);
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)errcode_t io_channel_write_blk64(io_channel channel, unsigned long long block,
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)				 int count, const void *data)
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if (channel->manager->write_blk64)
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		return (channel->manager->write_blk64)(channel, block,
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)						       count, data);
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	if ((block >> 32) != 0)
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64;
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	return (channel->manager->write_blk)(channel, (unsigned long) block,
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)					     count, data);
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)