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