172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V/*
272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * undo_io.c --- This is the undo io manager that copies the old data that
372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * copies the old data being overwritten into a tdb database
472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V *
572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * Copyright IBM Corporation, 2007
672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V *
872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * %Begin-Header%
9543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
10543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
1172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * %End-Header%
1272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V */
1372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
1472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#define _LARGEFILE_SOURCE
1572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#define _LARGEFILE64_SOURCE
1672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
1772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <stdio.h>
1872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <string.h>
1972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#if HAVE_UNISTD_H
2072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <unistd.h>
2172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
2272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#if HAVE_ERRNO_H
2372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <errno.h>
2472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
2572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <fcntl.h>
2672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <time.h>
2772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#ifdef __linux__
2872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <sys/utsname.h>
2972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
3072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#if HAVE_SYS_STAT_H
3172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <sys/stat.h>
3272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
3372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#if HAVE_SYS_TYPES_H
3472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <sys/types.h>
3572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
3672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#if HAVE_SYS_RESOURCE_H
3772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include <sys/resource.h>
3872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
3972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
4072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include "tdb.h"
4172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
4272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include "ext2_fs.h"
4372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#include "ext2fs.h"
4472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
458895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o#ifdef __GNUC__
468895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o#define ATTR(x) __attribute__(x)
478895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o#else
488895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o#define ATTR(x)
498895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o#endif
508895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o
5172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V/*
5272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * For checking structure magic numbers...
5372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V */
5472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
5572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#define EXT2_CHECK_MAGIC(struct, code) \
5672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	  if ((struct)->magic != (code)) return (code)
5772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
5872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstruct undo_private_data {
5972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	int	magic;
6072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	TDB_CONTEXT *tdb;
6172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	char *tdb_file;
6272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
6372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/* The backing io channel */
6472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io_channel real;
6572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
6672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	int tdb_data_size;
6772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	int tdb_written;
6872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
6972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/* to support offset in unix I/O manager */
7072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	ext2_loff_t offset;
7172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V};
7272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
7372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_open(const char *name, int flags, io_channel *channel);
7472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_close(io_channel channel);
7572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_set_blksize(io_channel channel, int blksize);
76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_read_blk64(io_channel channel, unsigned long long block,
77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				 int count, void *data);
78e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_write_blk64(io_channel channel, unsigned long long block,
79e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  int count, const void *data);
8072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_read_blk(io_channel channel, unsigned long block,
8172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			       int count, void *data);
8272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_write_blk(io_channel channel, unsigned long block,
8372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				int count, const void *data);
8472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_flush(io_channel channel);
8572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_write_byte(io_channel channel, unsigned long offset,
8672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				int size, const void *data);
8772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_set_option(io_channel channel, const char *option,
8872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				 const char *arg);
89e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_get_stats(io_channel channel, io_stats *stats);
9072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
9172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic struct struct_io_manager struct_undo_manager = {
9272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_ET_MAGIC_IO_MANAGER,
9372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	"Undo I/O Manager",
9472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_open,
9572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_close,
9672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_set_blksize,
9772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_read_blk,
9872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_write_blk,
9972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_flush,
10072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_write_byte,
101e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	undo_set_option,
102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	undo_get_stats,
103e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	undo_read_blk64,
104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	undo_write_blk64,
10572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V};
10672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
10772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vio_manager undo_io_manager = &struct_undo_manager;
10872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic io_manager undo_io_backing_manager ;
10972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic char *tdb_file;
11072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic int actual_size;
11172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
1128895f43a60269464f654e9d87c28768875cd703aTheodore Ts'ostatic unsigned char mtime_key[] = "filesystem MTIME";
1138895f43a60269464f654e9d87c28768875cd703aTheodore Ts'ostatic unsigned char blksize_key[] = "filesystem BLKSIZE";
1148895f43a60269464f654e9d87c28768875cd703aTheodore Ts'ostatic unsigned char uuid_key[] = "filesystem UUID";
1158895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o
11672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Verrcode_t set_undo_io_backing_manager(io_manager manager)
11772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
11872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
11972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * We may want to do some validation later
12072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
12172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	undo_io_backing_manager = manager;
12272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return 0;
12372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
12472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
12572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Verrcode_t set_undo_io_backup_file(char *file_name)
12672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
12772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_file = strdup(file_name);
12872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
12972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (tdb_file == NULL) {
13072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return EXT2_ET_NO_MEMORY;
13172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
13272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
13372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return 0;
13472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
13572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
13672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t write_file_system_identity(io_channel undo_channel,
13772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V							TDB_CONTEXT *tdb)
13872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
13972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t retval;
14072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct ext2_super_block super;
14172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	TDB_DATA tdb_key, tdb_data;
14272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
14372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io_channel channel;
14472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	int block_size ;
14572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
14672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) undo_channel->private_data;
14772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	channel = data->real;
14872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	block_size = channel->block_size;
14972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
15072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io_channel_set_blksize(channel, SUPERBLOCK_OFFSET);
151e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = io_channel_read_blk64(channel, 1, -SUPERBLOCK_SIZE, &super);
15272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
15372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		goto err_out;
15472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
15572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/* Write to tdb file in the file system byte order */
1568895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	tdb_key.dptr = mtime_key;
1578895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	tdb_key.dsize = sizeof(mtime_key);
15872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_data.dptr = (unsigned char *) &(super.s_mtime);
15972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_data.dsize = sizeof(super.s_mtime);
16072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
16172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = tdb_store(tdb, tdb_key, tdb_data, TDB_INSERT);
16272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval == -1) {
16372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
16472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		goto err_out;
16572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
16672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
1678895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	tdb_key.dptr = uuid_key;
1688895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	tdb_key.dsize = sizeof(uuid_key);
16972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_data.dptr = (unsigned char *)&(super.s_uuid);
17072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_data.dsize = sizeof(super.s_uuid);
17172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
17272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = tdb_store(tdb, tdb_key, tdb_data, TDB_INSERT);
17372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval == -1) {
17472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
17572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
17672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
17772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Verr_out:
17872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io_channel_set_blksize(channel, block_size);
17972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
18072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
18172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
18272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t write_block_size(TDB_CONTEXT *tdb, int block_size)
18372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
18472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t retval;
18572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	TDB_DATA tdb_key, tdb_data;
18672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
1878895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	tdb_key.dptr = blksize_key;
1888895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	tdb_key.dsize = sizeof(blksize_key);
18972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_data.dptr = (unsigned char *)&(block_size);
19072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_data.dsize = sizeof(block_size);
19172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
19272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = tdb_store(tdb, tdb_key, tdb_data, TDB_INSERT);
19372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval == -1) {
19472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
19572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
19672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
19772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
19872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
19972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
20072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_write_tdb(io_channel channel,
201e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				unsigned long long block, int count)
20272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
20372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
2048895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	int size, sz;
205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	unsigned long long block_num, backing_blk_num;
20672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t retval = 0;
20772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	ext2_loff_t offset;
20872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
20972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	TDB_DATA tdb_key, tdb_data;
2108895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	unsigned char *read_ptr;
211e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	unsigned long long end_block;
21272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
21372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
21472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
21572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->tdb == NULL) {
21672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		/*
21772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * Transaction database not initialized
21872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 */
21972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return 0;
22072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
22172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
22272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (count == 1)
22372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		size = channel->block_size;
22472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	else {
22572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (count < 0)
22672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			size = -count;
22772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		else
22872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			size = count * channel->block_size;
22972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
23072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
23172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * Data is stored in tdb database as blocks of tdb_data_size size
23272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * This helps in efficient lookup further.
23372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 *
23472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * We divide the disk to blocks of tdb_data_size.
23572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
23672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	offset = (block * channel->block_size) + data->offset ;
23772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	block_num = offset / data->tdb_data_size;
23872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	end_block = (offset + size) / data->tdb_data_size;
23972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
24072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_transaction_start(data->tdb);
24172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	while (block_num <= end_block ) {
24272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
24372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		tdb_key.dptr = (unsigned char *)&block_num;
24472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		tdb_key.dsize = sizeof(block_num);
24572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		/*
24672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * Check if we have the record already
24772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 */
24872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (tdb_exists(data->tdb, tdb_key)) {
24972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			/* Try the next block */
25072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			block_num++;
25172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			continue;
25272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		}
25372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		/*
25472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * Read one block using the backing I/O manager
25572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * The backing I/O manager block size may be
25672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * different from the tdb_data_size.
25772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * Also we need to recalcuate the block number with respect
25872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 * to the backing I/O manager.
25972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 */
26072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		offset = block_num * data->tdb_data_size;
26172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		backing_blk_num = (offset - data->offset) / channel->block_size;
26272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
26372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		count = data->tdb_data_size +
26472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				((offset - data->offset) % channel->block_size);
26572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = ext2fs_get_mem(count, &read_ptr);
26672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (retval) {
26772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			tdb_transaction_cancel(data->tdb);
26872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			return retval;
26972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		}
27072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
27172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		memset(read_ptr, 0, count);
27272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		actual_size = 0;
27372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if ((count % channel->block_size) == 0)
27472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			sz = count / channel->block_size;
27572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		else
27672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			sz = -count;
277e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_read_blk64(data->real, backing_blk_num,
27872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V					     sz, read_ptr);
27972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (retval) {
28072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			if (retval != EXT2_ET_SHORT_READ) {
28172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				free(read_ptr);
28272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				tdb_transaction_cancel(data->tdb);
28372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				return retval;
28472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			}
28572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			/*
28672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			 * short read so update the record size
28772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			 * accordingly
28872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			 */
28972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			tdb_data.dsize = actual_size;
29072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		} else {
29172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			tdb_data.dsize = data->tdb_data_size;
29272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		}
29372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		tdb_data.dptr = read_ptr +
29472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				((offset - data->offset) % channel->block_size);
29572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#ifdef DEBUG
296e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		printf("Printing with key %lld data %x and size %d\n",
29772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		       block_num,
29872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		       tdb_data.dptr,
29972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		       tdb_data.dsize);
30072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V#endif
30172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (!data->tdb_written) {
30272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			data->tdb_written = 1;
30372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			/* Write the blocksize to tdb file */
30472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			retval = write_block_size(data->tdb,
30572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V						  data->tdb_data_size);
30672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			if (retval) {
30772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				tdb_transaction_cancel(data->tdb);
30872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				retval = EXT2_ET_TDB_ERR_IO;
30972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				free(read_ptr);
31072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				return retval;
31172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			}
31272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		}
31372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = tdb_store(data->tdb, tdb_key, tdb_data, TDB_INSERT);
31472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (retval == -1) {
31572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			/*
31672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			 * TDB_ERR_EXISTS cannot happen because we
31772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			 * have already verified it doesn't exist
31872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			 */
31972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			tdb_transaction_cancel(data->tdb);
32072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			retval = EXT2_ET_TDB_ERR_IO;
32172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			free(read_ptr);
32272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			return retval;
32372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		}
32472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		free(read_ptr);
32572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		/* Next block */
32672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		block_num++;
32772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
32872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	tdb_transaction_commit(data->tdb);
32972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
33072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
33172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
33272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
3338895f43a60269464f654e9d87c28768875cd703aTheodore Ts'ostatic errcode_t undo_io_read_error(io_channel channel ATTR((unused)),
3348895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o				    unsigned long block ATTR((unused)),
3358895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o				    int count ATTR((unused)),
3368895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o				    void *data ATTR((unused)),
3378895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o				    size_t size ATTR((unused)),
3388895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o				    int actual,
3398895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o				    errcode_t error ATTR((unused)))
34072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
34172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	actual_size = actual;
34272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return error;
34372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
34472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
34572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic void undo_err_handler_init(io_channel channel)
34672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
34772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	channel->read_error = undo_io_read_error;
34872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
34972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
35072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_open(const char *name, int flags, io_channel *channel)
35172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
35272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io_channel	io = NULL;
35372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data = NULL;
35472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t	retval;
35572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
35672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (name == 0)
35772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return EXT2_ET_BAD_DEVICE_NAME;
35872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
35972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
360e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		goto cleanup;
36172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	memset(io, 0, sizeof(struct struct_io_channel));
36272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
36372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = ext2fs_get_mem(sizeof(struct undo_private_data), &data);
36472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
36572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		goto cleanup;
36672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
36772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->manager = undo_io_manager;
36872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = ext2fs_get_mem(strlen(name)+1, &io->name);
36972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
37072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		goto cleanup;
37172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
37272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	strcpy(io->name, name);
37372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->private_data = data;
37472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->block_size = 1024;
37572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->read_error = 0;
37672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->write_error = 0;
37772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	io->refcount = 1;
37872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
37972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	memset(data, 0, sizeof(struct undo_private_data));
38072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
38172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
38272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (undo_io_backing_manager) {
38372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = undo_io_backing_manager->open(name, flags,
38472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V						       &data->real);
38572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (retval)
38672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			goto cleanup;
38772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	} else {
38872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		data->real = 0;
38972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
39072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
39172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/* setup the tdb file */
39272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data->tdb = tdb_open(tdb_file, 0, TDB_CLEAR_IF_FIRST,
39372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			     O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
39472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (!data->tdb) {
39572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = errno;
39672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		goto cleanup;
39772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
39872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
39972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
40072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * setup err handler for read so that we know
40172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * when the backing manager fails do short read
40272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
403e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (data->real)
404e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		undo_err_handler_init(data->real);
40572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
40672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	*channel = io;
40772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return 0;
40872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
40972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vcleanup:
410e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (data && data->real)
41172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		io_channel_close(data->real);
41272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data)
41372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		ext2fs_free_mem(&data);
41472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (io)
41572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		ext2fs_free_mem(&io);
41672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
41772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
41872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
41972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_close(io_channel channel)
42072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
42172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
42272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t	retval = 0;
42372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
42472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
42572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
42672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
42772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
42872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (--channel->refcount > 0)
42972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return 0;
43072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/* Before closing write the file system identity */
43172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = write_file_system_identity(channel, data->tdb);
43272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
43372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return retval;
43472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real)
43572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = io_channel_close(data->real);
43672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->tdb)
43772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		tdb_close(data->tdb);
43872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	ext2fs_free_mem(&channel->private_data);
43972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (channel->name)
44072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		ext2fs_free_mem(&channel->name);
44172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	ext2fs_free_mem(&channel);
44272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
44372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
44472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
44572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
44672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_set_blksize(io_channel channel, int blksize)
44772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
44872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
4498895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	errcode_t		retval = 0;
45072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
45172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
45272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
45372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
45472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
45572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real)
45672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = io_channel_set_blksize(data->real, blksize);
45772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
45872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * Set the block size used for tdb
45972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
46072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (!data->tdb_data_size) {
46172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		data->tdb_data_size = blksize;
46272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
46372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	channel->block_size = blksize;
46472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
46572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
46672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
467e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_read_blk64(io_channel channel, unsigned long long block,
46872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			       int count, void *buf)
46972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
4708895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o	errcode_t	retval = 0;
47172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
47272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
47372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
47472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
47572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
47672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
47772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real)
478e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_read_blk64(data->real, block, count, buf);
47972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
48072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
48172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
48272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
483e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_read_blk(io_channel channel, unsigned long block,
484e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       int count, void *buf)
485e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
486e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return undo_read_blk64(channel, block, count, buf);
487e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
488e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
489e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_write_blk64(io_channel channel, unsigned long long block,
49072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				int count, const void *buf)
49172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
49272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
49372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t	retval = 0;
49472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
49572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
49672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
49772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
49872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
49972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * First write the existing content into database
50072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
50172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = undo_write_tdb(channel, block, count);
50272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
50372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		 return retval;
50472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real)
505e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = io_channel_write_blk64(data->real, block, count, buf);
50672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
50772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
50872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
50972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
510e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_write_blk(io_channel channel, unsigned long block,
511e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				int count, const void *buf)
512e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
513e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return undo_write_blk64(channel, block, count, buf);
514e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
515e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
51672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_write_byte(io_channel channel, unsigned long offset,
51772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				 int size, const void *buf)
51872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
51972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
52072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t	retval = 0;
52172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	ext2_loff_t	location;
52272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	unsigned long blk_num, count;;
52372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
52472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
52572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
52672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
52772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
52872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	location = offset + data->offset;
52972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	blk_num = location/channel->block_size;
53072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
53172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * the size specified may spread across multiple blocks
53272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * also make sure we account for the fact that block start
53372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * offset for tdb is different from the backing I/O manager
53472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * due to possible different block size
53572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
53672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	count = (size + (location % channel->block_size) +
53772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			channel->block_size  -1)/channel->block_size;
53872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	retval = undo_write_tdb(channel, blk_num, count);
53972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (retval)
54072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return retval;
54172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real && data->real->manager->write_byte)
54272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = io_channel_write_byte(data->real, offset, size, buf);
54372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
54472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
54572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
54672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
54772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V/*
54872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V * Flush data buffers to disk.
54972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V */
55072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_flush(io_channel channel)
55172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
55272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t	retval = 0;
55372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
55472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
55572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
55672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
55772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
55872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
55972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real)
56072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = io_channel_flush(data->real);
56172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
56272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
56372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
56472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
56572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.Vstatic errcode_t undo_set_option(io_channel channel, const char *option,
56672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V				 const char *arg)
56772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V{
56872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	errcode_t	retval = 0;
56972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	struct undo_private_data *data;
57072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	unsigned long tmp;
57172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	char *end;
57272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
57372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
57472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	data = (struct undo_private_data *) channel->private_data;
57572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
57672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
57772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (!strcmp(option, "tdb_data_size")) {
57872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (!arg)
57972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			return EXT2_ET_INVALID_ARGUMENT;
58072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
58172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		tmp = strtoul(arg, &end, 0);
58272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (*end)
58372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			return EXT2_ET_INVALID_ARGUMENT;
58472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (!data->tdb_data_size || !data->tdb_written) {
58572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			data->tdb_data_size = tmp;
58672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		}
58772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		return 0;
58872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
58972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	/*
59072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * Need to support offset option to work with
59172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 * Unix I/O manager
59272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	 */
59372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (data->real && data->real->manager->set_option) {
59472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		retval = data->real->manager->set_option(data->real,
59572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V							option, arg);
59672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
59772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	if (!retval && !strcmp(option, "offset")) {
59872a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (!arg)
59972a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			return EXT2_ET_INVALID_ARGUMENT;
60072a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V
60172a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		tmp = strtoul(arg, &end, 0);
60272a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		if (*end)
60372a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V			return EXT2_ET_INVALID_ARGUMENT;
60472a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V		data->offset = tmp;
60572a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	}
60672a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V	return retval;
60772a168b59cbabdcfb1fe9db30f3d63f6f9731324Aneesh Kumar K.V}
608e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
609e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic errcode_t undo_get_stats(io_channel channel, io_stats *stats)
610e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
611e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	errcode_t	retval = 0;
612e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	struct undo_private_data *data;
613e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
614e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
615e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	data = (struct undo_private_data *) channel->private_data;
616e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
617e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
618e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (data->real)
619e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = (data->real->manager->get_stats)(data->real, stats);
620e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
621e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return retval;
622e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
623