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