dupfs.c revision 816d2c9cf7fb17fe808a081e076cb558f44ec30d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * dupfs.c --- duplicate a ext2 filesystem handle 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 1997, 1998, 2001, 2003, 2005 by Theodore Ts'o. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %Begin-Header% 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file may be redistributed under the terms of the GNU Library 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * General Public License, version 2. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %End-Header% 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if HAVE_UNISTD_H 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <unistd.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h> 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "ext2_fs.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ext2fsP.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ext2_filsys fs; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcode_t retval; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return retval; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fs = *src; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->device_name = 0; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->super = 0; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->orig_super = 0; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->group_desc = 0; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fs->inode_map = 0; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->block_map = 0; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->badblocks = 0; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->dblist = 0; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->mmp_buf = 0; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->mmp_cmp = 0; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->mmp_fd = -1; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_channel_bumpcount(fs->io); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fs->icache) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->icache->refcount++; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_mem(strlen(src->device_name)+1, &fs->device_name); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(fs->device_name, src->device_name); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(fs->super, src->super, SUPERBLOCK_SIZE); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(fs->orig_super, src->orig_super, SUPERBLOCK_SIZE); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &fs->group_desc); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(fs->group_desc, src->group_desc, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (size_t) fs->desc_blocks * fs->blocksize); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src->inode_map) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src->block_map) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (src->badblocks) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src->dblist) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_copy_dblist(src->dblist, &fs->dblist); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src->mmp_buf) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_mem(src->blocksize, &fs->mmp_buf); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(fs->mmp_buf, src->mmp_buf, src->blocksize); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src->mmp_fd >= 0) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs->mmp_fd = dup(src->mmp_fd); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fs->mmp_fd < 0) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = EXT2_ET_MMP_OPEN_DIRECT; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src->mmp_cmp) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int align = ext2fs_get_dio_alignment(src->mmp_fd); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = ext2fs_get_memalign(src->blocksize, align, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &fs->mmp_cmp); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (retval) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto errout; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(fs->mmp_cmp, src->mmp_cmp, src->blocksize); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dest = fs; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 117errout: 118 ext2fs_free(fs); 119 return retval; 120 121} 122 123