dupfs.c revision 4cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3
186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato/* 286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * dupfs.c --- duplicate a ext2 filesystem handle 386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * 486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * Copyright (C) 1997 Theodore Ts'o. 586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * 686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * %Begin-Header% 786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * This file may be redistributed under the terms of the GNU Public 886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * License. 986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato * %End-Header% 1086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato */ 1186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 1286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <stdio.h> 1386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#if HAVE_UNISTD_H 1486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <unistd.h> 1586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#endif 1686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <stdlib.h> 1786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <time.h> 1886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <string.h> 1986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#ifdef HAVE_ERRNO_H 2086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <errno.h> 2186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#endif 2286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 2386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include <linux/ext2_fs.h> 2486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 2586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato#include "ext2fsP.h" 2686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 2786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onoratoerrcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest) 2886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato{ 2986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato ext2_filsys fs; 3086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato errcode_t retval; 3186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 3286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS); 3386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 3486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs = (ext2_filsys) malloc(sizeof(struct struct_ext2_filsys)); 3586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (!fs) 3686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato return ENOMEM; 3786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 3886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato *fs = *src; 3986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->device_name = 0; 4086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->super = 0; 4186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->group_desc = 0; 4286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->inode_map = 0; 4386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->block_map = 0; 4486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->badblocks = 0; 4586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->dblist = 0; 4686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 4786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato io_channel_bumpcount(fs->io); 4886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (fs->icache) 4986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->icache->refcount++; 5086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 5186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato retval = ENOMEM; 5286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->device_name = malloc(strlen(src->device_name)+1); 5386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (!fs->device_name) 5486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 5586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato strcpy(fs->device_name, src->device_name); 5686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 5786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->super = malloc(SUPERBLOCK_SIZE); 5886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (!fs->super) 5986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 6086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato memcpy(fs->super, src->super, SUPERBLOCK_SIZE); 6186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 6286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->group_desc = malloc(fs->desc_blocks * fs->blocksize); 6386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (!fs->group_desc) 6486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 6586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato memcpy(fs->group_desc, src->group_desc, 6686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato fs->desc_blocks * fs->blocksize); 6786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 6886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (src->inode_map) { 6986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map); 7086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (retval) 7186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 7286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato } 7386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (src->block_map) { 7486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map); 7586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (retval) 7686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 7786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato } 7886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (src->badblocks) { 7986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks); 8086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (retval) 8186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 8286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato } 8386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (src->dblist) { 8486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato retval = ext2fs_copy_dblist(src->dblist, &fs->dblist); 8586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato if (retval) 8686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato goto errout; 8786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato } 8886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato *dest = fs; 8986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato return 0; 9086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onoratoerrout: 9186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato ext2fs_free(fs); 9286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato return retval; 9386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 9486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato} 9586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato 9686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato