1a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/* 2a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * dupfs.c --- duplicate a ext2 filesystem handle 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 4bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o * Copyright (C) 1997, 1998, 2001, 2003, 2005 by Theodore Ts'o. 5a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * 6a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 9a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * %End-Header% 10a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */ 11a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 12a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o#include <stdio.h> 134cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 14a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o#include <unistd.h> 154cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 16a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o#include <time.h> 17a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o#include <string.h> 18a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 19b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 20a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o#include "ext2fsP.h" 21a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 22a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest) 23a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{ 24a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_filsys fs; 25a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o errcode_t retval; 26a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 27a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS); 28efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 29c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs); 307b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 317b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 32a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 33a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o *fs = *src; 34a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->device_name = 0; 35a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->super = 0; 36bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o fs->orig_super = 0; 37a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->group_desc = 0; 38a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->inode_map = 0; 39a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->block_map = 0; 40a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->badblocks = 0; 41a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->dblist = 0; 42e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->mmp_buf = 0; 43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->mmp_cmp = 0; 44e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->mmp_fd = -1; 45a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 46a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o io_channel_bumpcount(fs->io); 47a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (fs->icache) 48a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->icache->refcount++; 49a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 50c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(strlen(src->device_name)+1, &fs->device_name); 517b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 52a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 53a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o strcpy(fs->device_name, src->device_name); 54a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 55c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super); 567b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 57a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 58a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o memcpy(fs->super, src->super, SUPERBLOCK_SIZE); 59a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 60bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super); 61bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o if (retval) 62bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o goto errout; 63bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o memcpy(fs->orig_super, src->orig_super, SUPERBLOCK_SIZE); 64bc1b803214dc462efc9307ce0dbe0fc004f8a3e8Theodore Ts'o 65ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize, 66c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &fs->group_desc); 677b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 68a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 69a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o memcpy(fs->group_desc, src->group_desc, 703cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o (size_t) fs->desc_blocks * fs->blocksize); 71a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 72a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (src->inode_map) { 73a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map); 74a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 75a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 76a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o } 77a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (src->block_map) { 78a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map); 79a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 80a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 81a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o } 82a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (src->badblocks) { 83a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks); 84a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 85a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 86a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o } 87a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (src->dblist) { 88a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = ext2fs_copy_dblist(src->dblist, &fs->dblist); 89a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 90a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto errout; 91a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o } 92e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (src->mmp_buf) { 93e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_get_mem(src->blocksize, &fs->mmp_buf); 94e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval) 95e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto errout; 96e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall memcpy(fs->mmp_buf, src->mmp_buf, src->blocksize); 97e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 98e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (src->mmp_fd >= 0) { 99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->mmp_fd = dup(src->mmp_fd); 100e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (fs->mmp_fd < 0) { 101e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = EXT2_ET_MMP_OPEN_DIRECT; 102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto errout; 103e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 105e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (src->mmp_cmp) { 106e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int align = ext2fs_get_dio_alignment(src->mmp_fd); 107e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 108e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_get_memalign(src->blocksize, align, 109e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall &fs->mmp_cmp); 110e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval) 111e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto errout; 112e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall memcpy(fs->mmp_cmp, src->mmp_cmp, src->blocksize); 113e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 114a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o *dest = fs; 115a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return 0; 116a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrout: 117a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2fs_free(fs); 118a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return retval; 119efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 120a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o} 121a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 122