/*
    reiserfs.c -- libparted / libreiserfs glue
    Copyright (C) 2001, 2002, 2007  Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA

    This is all rather complicated.  There are a few combinations:
	* shared libraries full support
	* dynamic libraries present full support (via dlopen)
	* dynamic libraries absent (full support disabled) (via dlopen)
	* discover only

    We'd love to hear comments...

    So far, we've opted for maximum flexibility for the user.  Is it
    all worth it?
*/

#include <config.h>

#if (HAVE_LIBREISERFS || DYNAMIC_LOADING) && !DISCOVER_ONLY
#	define REISER_FULL_SUPPORT
#endif

#include <uuid/uuid.h>
#include <fcntl.h>
#include <errno.h>

#ifdef DYNAMIC_LOADING
#	include <dlfcn.h>
#endif

#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>

#if ENABLE_NLS
#	include <libintl.h>
#	define _(String) dgettext (PACKAGE, String)
#else
#	define _(String) (String)
#endif

#include "reiserfs.h"
#include "geom_dal.h"

#define REISERFS_BLOCK_SIZES       ((int[2]){512, 0})

static PedSector reiserfs_super_offset[] = { 128, 16, -1 };
static PedFileSystemType* reiserfs_type;

#ifdef DYNAMIC_LOADING
#	define FPTR *
#	define FCLASS static
#else
#	define FPTR
#	define FCLASS extern
#endif

#ifdef DYNAMIC_LOADING

static int libreiserfs_present;

static void *libdal_handle;
static void *libreiserfs_handle;

#endif /* DYNAMIC_LOADING */

#ifdef REISER_FULL_SUPPORT

FCLASS blk_t (FPTR reiserfs_fs_probe) (dal_t *);

FCLASS int (FPTR libreiserfs_exception_type) (reiserfs_exception_t *);
FCLASS int (FPTR libreiserfs_exception_option) (reiserfs_exception_t *);
FCLASS char *(FPTR libreiserfs_exception_message) (reiserfs_exception_t *);
FCLASS void (FPTR libreiserfs_exception_set_handler)
		(int(FPTR)(reiserfs_exception_t *));

FCLASS void (FPTR dal_realize) (dal_t *);
FCLASS size_t (FPTR dal_block_size) (dal_t *);
FCLASS blk_t (FPTR dal_len) (dal_t *);
FCLASS int (FPTR dal_flags) (dal_t *);

FCLASS reiserfs_fs_t* (FPTR reiserfs_fs_open) (dal_t *, dal_t *);
FCLASS reiserfs_fs_t* (FPTR reiserfs_fs_create) (dal_t *, dal_t *,
					  blk_t, blk_t, blk_t, size_t,
					  int, int, const char *,
					  const char *, blk_t,
				          reiserfs_gauge_t *);

FCLASS int (FPTR reiserfs_fs_resize) (reiserfs_fs_t *, blk_t, reiserfs_gauge_t *);
#ifdef HAVE_REISERFS_FS_CHECK
FCLASS int (FPTR reiserfs_fs_check) (reiserfs_fs_t *, reiserfs_gauge_t *);
#endif

FCLASS reiserfs_fs_t *(FPTR reiserfs_fs_copy) (reiserfs_fs_t *, dal_t *,
					reiserfs_gauge_t *);

FCLASS int (FPTR reiserfs_fs_clobber) (dal_t *);
FCLASS void (FPTR reiserfs_fs_close) (reiserfs_fs_t *);

FCLASS int (FPTR reiserfs_fs_is_resizeable) (reiserfs_fs_t *);
FCLASS int (FPTR reiserfs_fs_is_consistent) (reiserfs_fs_t *);

FCLASS blk_t (FPTR reiserfs_fs_min_size) (reiserfs_fs_t *);
FCLASS blk_t (FPTR reiserfs_fs_block_size) (reiserfs_fs_t *);
FCLASS dal_t* (FPTR reiserfs_fs_host_dal) (reiserfs_fs_t *);

FCLASS blk_t (FPTR reiserfs_fs_bitmap_used) (reiserfs_fs_t *);
FCLASS int (FPTR reiserfs_fs_bitmap_check) (reiserfs_fs_t *);

FCLASS reiserfs_gauge_t *(FPTR libreiserfs_gauge_create) (
	char *, reiserfs_gauge_handler_t, void *);

FCLASS void (FPTR libreiserfs_gauge_free) (reiserfs_gauge_t *);

static void gauge_handler(const char *name, unsigned int value, void *data,
			  int determined, int update_header,
			  int update_footer)
{
	PedTimer *timer = (PedTimer *) data;
	ped_timer_set_state_name(timer, name);
	ped_timer_update(timer, 1.0 * value / 100);
}

static PedExceptionOption
exopt_libreiserfs_to_parted(reiserfs_exception_option_t option)
{
	switch (option) {
	case EXCEPTION_UNHANDLED:
		return PED_EXCEPTION_UNHANDLED;
	case EXCEPTION_FIX:
		return PED_EXCEPTION_FIX;
	case EXCEPTION_YES:
		return PED_EXCEPTION_YES;
	case EXCEPTION_NO:
		return PED_EXCEPTION_NO;
	case EXCEPTION_OK:
		return PED_EXCEPTION_OK;
	case EXCEPTION_RETRY:
		return PED_EXCEPTION_RETRY;
	case EXCEPTION_IGNORE:
		return PED_EXCEPTION_IGNORE;
	case EXCEPTION_CANCEL:
		return PED_EXCEPTION_CANCEL;

	default:
		return PED_EXCEPTION_UNHANDLED;
	}
}

static PedExceptionType
extype_libreiserfs_to_parted(reiserfs_exception_type_t type)
{
	switch (type) {
	case EXCEPTION_INFORMATION:
		return PED_EXCEPTION_INFORMATION;
	case EXCEPTION_WARNING:
		return PED_EXCEPTION_WARNING;
	case EXCEPTION_ERROR:
		return PED_EXCEPTION_ERROR;
	case EXCEPTION_FATAL:
		return PED_EXCEPTION_FATAL;
	case EXCEPTION_BUG:
		return PED_EXCEPTION_BUG;
	case EXCEPTION_NO_FEATURE:
		return PED_EXCEPTION_NO_FEATURE;

	default:
		return PED_EXCEPTION_NO_FEATURE;
	}
}

static int exception_handler(reiserfs_exception_t *exception)
{
	int ex_type = libreiserfs_exception_type(exception);
	int ex_option = libreiserfs_exception_option(exception);
	char *ex_message = libreiserfs_exception_message(exception);

	return ped_exception_throw (extype_libreiserfs_to_parted (ex_type),
				    exopt_libreiserfs_to_parted (ex_option),
				    ex_message);
}
#endif /* REISER_FULL_SUPPORT */

static PedGeometry *reiserfs_probe(PedGeometry *geom)
{
	int i;
	reiserfs_super_block_t sb;

	PED_ASSERT(geom != NULL, return NULL);

	for (i = 0; reiserfs_super_offset[i] != -1; i++) {
		if (reiserfs_super_offset[i] >= geom->length)
			continue;
		if (!ped_geometry_read (geom, &sb, reiserfs_super_offset[i], 1))
			continue;

		if (strncmp(REISERFS_SIGNATURE, sb.s_magic,
		            strlen(REISERFS_SIGNATURE)) == 0
		    || strncmp(REISER2FS_SIGNATURE, sb.s_magic,
			       strlen(REISER2FS_SIGNATURE)) == 0
		    || strncmp(REISER3FS_SIGNATURE, sb.s_magic,
			       strlen(REISER3FS_SIGNATURE)) == 0) {
			PedSector block_size;
			PedSector block_count;

			block_size = PED_LE16_TO_CPU(sb.s_blocksize)
					/ PED_SECTOR_SIZE_DEFAULT;
			block_count = PED_LE32_TO_CPU(sb.s_block_count);

			return ped_geometry_new(geom->dev, geom->start,
						block_size * block_count);
		}
	}
	return NULL;
}

#ifndef DISCOVER_ONLY
static int reiserfs_clobber(PedGeometry *geom)
{
	int i;
	char buf[512];

	PED_ASSERT(geom != NULL, return 0);

	memset(buf, 0, 512);
	for (i = 0; reiserfs_super_offset[i] != -1; i++) {
		if (reiserfs_super_offset[i] >= geom->length)
			continue;
		if (!ped_geometry_write
		    (geom, buf, reiserfs_super_offset[i], 1))
			return 0;
	}
	return 1;
}
#endif /* !DISCOVER_ONLY */

#ifdef REISER_FULL_SUPPORT

static PedFileSystem *reiserfs_open(PedGeometry *geom)
{
	PedFileSystem *fs;
	PedGeometry *fs_geom;
	dal_t *dal;
	reiserfs_fs_t *fs_info;

	PED_ASSERT(geom != NULL, return NULL);

	if (!(fs_geom = ped_geometry_duplicate(geom)))
		goto error;

	if (! (dal = geom_dal_create(fs_geom, DEFAULT_BLOCK_SIZE, O_RDONLY)))
		goto error_fs_geom_free;

	/*
	   We are passing NULL as DAL for journal. Therefore we let libreiserfs know, 
	   that journal not available and parted will be working fine for reiserfs 
	   with relocated journal too.
	 */
	if (!(fs = (PedFileSystem *) ped_malloc(sizeof(PedFileSystem))))
		goto error_free_dal;

	if (!(fs_info = reiserfs_fs_open(dal, NULL)))
		goto error_free_fs;

	fs->type = reiserfs_type;
	fs->geom = fs_geom;
	fs->type_specific = (void *) fs_info;

	return fs;

error_free_fs:
	ped_free(fs);
error_free_dal:
	geom_dal_free(dal);
error_fs_geom_free:
	ped_geometry_destroy(fs_geom);
error:
	return NULL;
}

static PedFileSystem *reiserfs_create(PedGeometry *geom, PedTimer *timer)
{
	dal_t *dal;
	uuid_t uuid;
	PedFileSystem *fs;
	PedGeometry *fs_geom;
	reiserfs_fs_t *fs_info;
	reiserfs_gauge_t *gauge = NULL;

	PED_ASSERT(geom != NULL, return NULL);

	fs_geom = ped_geometry_duplicate(geom);

	if (!(dal = geom_dal_create(fs_geom, DEFAULT_BLOCK_SIZE, O_RDWR)))
		goto error_fs_geom_free;

	memset(uuid, 0, sizeof(uuid));
	uuid_generate(uuid);

	ped_timer_reset(timer);
	ped_timer_set_state_name(timer, _("creating"));

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (! (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			goto error_free_dal;
	}

	if (!(fs_info = reiserfs_fs_create(dal, dal, 0, JOURNAL_MAX_TRANS,
					   DEFAULT_JOURNAL_SIZE,
					   DEFAULT_BLOCK_SIZE,
					   FS_FORMAT_3_6, R5_HASH, NULL,
					   (char *) uuid, dal_len(dal),
					   gauge)))
		goto error_free_gauge;

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);

	if (!(fs = (PedFileSystem *) ped_malloc(sizeof(PedFileSystem))))
		goto error_free_fs_info;

	fs->type = reiserfs_type;
	fs->geom = fs_geom;
	fs->type_specific = (void *) fs_info;

	return fs;

error_free_fs_info:
	ped_free(fs_info);
error_free_gauge:
	if (gauge)
		libreiserfs_gauge_free(gauge);
error_free_dal:
	geom_dal_free(dal);
error_fs_geom_free:
	ped_geometry_destroy(fs_geom);
	return NULL;
}

static int reiserfs_close(PedFileSystem *fs)
{
	dal_t *dal;

	PED_ASSERT(fs != NULL, return 0);

	dal = reiserfs_fs_host_dal(fs->type_specific);
	reiserfs_fs_close(fs->type_specific);

	geom_dal_free(dal);
	ped_geometry_sync(fs->geom);

	ped_free(fs);
	return 1;
}

static PedConstraint *reiserfs_get_create_constraint(const PedDevice *dev)
{
	PedGeometry full_dev;
	PedSector min_blks = (SUPER_OFFSET_IN_BYTES / DEFAULT_BLOCK_SIZE)
			     + 2 + DEFAULT_JOURNAL_SIZE + 1 + 100 + 1;

	if (!ped_geometry_init(&full_dev, dev, 0, dev->length - 1))
		return NULL;

	return ped_constraint_new(ped_alignment_any, ped_alignment_any,
				  &full_dev, &full_dev,
				  min_blks * (DEFAULT_BLOCK_SIZE / 512),
				  dev->length);
}

static int reiserfs_check(PedFileSystem *fs, PedTimer *timer)
{
	reiserfs_fs_t *fs_info;
#ifdef HAVE_REISERFS_FS_CHECK
	reiserfs_gauge_t *gauge = NULL;
#endif

	PED_ASSERT(fs != NULL, return 0);

	fs_info = fs->type_specific;

	if (!reiserfs_fs_is_consistent(fs_info)) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("The file system is in an invalid "
				      "state.  Perhaps it is mounted?"));
		return 0;
	}

	if (!reiserfs_fs_is_resizeable(fs_info))
		ped_exception_throw(PED_EXCEPTION_WARNING,
				    PED_EXCEPTION_IGNORE,
				    _("The file system is in old "
				      "(unresizeable) format."));

	if (!reiserfs_fs_bitmap_check(fs_info)) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Invalid free blocks count.  Run "
				      "reiserfsck --check first."));
		return 0;
	}

#ifdef HAVE_REISERFS_FS_CHECK
	ped_timer_reset(timer);
	
	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (!
		    (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			return 0;
	}
		
	ped_timer_set_state_name(timer, _("checking"));
	ped_timer_update(timer, 0.0);

	if (!reiserfs_fs_check(fs_info, gauge)) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Reiserfs tree seems to be corrupted.  "
				      "Run reiserfsck --check first."));
		return 0;
	}
	
	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);
#endif
	
	ped_exception_throw(PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK,
			    _("The reiserfs file system passed a basic check.  "
			      "For a more comprehensive check, run "
			      "reiserfsck --check."));

	return 1;
}

static int reiserfs_resize(PedFileSystem *fs, PedGeometry *geom,
			   PedTimer *timer)
{
	dal_t *dal;
	blk_t fs_len;
	PedSector old_length;
	reiserfs_fs_t *fs_info;
	reiserfs_gauge_t *gauge = NULL;

	PED_ASSERT(fs != NULL, return 0);

	old_length = fs->geom->length;

	PED_ASSERT (fs->geom->dev == geom->dev, return 0);

	if (fs->geom->start != geom->start) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Sorry, can't move the start of "
				      "reiserfs partitions yet."));
		return 0;
	}

	fs_info = fs->type_specific;

	fs_len = (blk_t) (geom->length / (reiserfs_fs_block_size(fs_info) /
					  PED_SECTOR_SIZE_DEFAULT));

	dal = reiserfs_fs_host_dal(fs_info);

	if (dal_flags(dal) && O_RDONLY) {
		if (!geom_dal_reopen(dal, O_RDWR)) {
			ped_exception_throw(PED_EXCEPTION_ERROR,
					    PED_EXCEPTION_CANCEL,
					    _("Couldn't reopen device "
					      "abstraction layer for "
					      "read/write."));
			return 0;
		}
	}

	ped_timer_reset(timer);

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (!
		    (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			return 0;
	}

	if (old_length > geom->length) {

		ped_timer_set_state_name(timer, _("shrinking"));
		ped_timer_update(timer, 0.0);

		if (!reiserfs_fs_resize(fs_info, fs_len, gauge))
			goto error_free_gauge;

		ped_geometry_set_end (fs->geom, geom->end);
		dal_realize(dal);
	} else {
		ped_geometry_set_end (fs->geom, geom->end);
		dal_realize(dal);

		ped_timer_set_state_name(timer, _("expanding"));
		ped_timer_update(timer, 0.0);

		if (!reiserfs_fs_resize(fs_info, fs_len, gauge))
			goto error_free_gauge;
	}

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);

	return 1;

error_free_gauge:
	if (gauge)
		libreiserfs_gauge_free(gauge);
	ped_geometry_set_end (fs->geom, fs->geom->start + old_length - 1);
	return 0;
}

static PedConstraint *reiserfs_get_resize_constraint(const PedFileSystem *
						     fs)
{
	PedDevice *dev;
	PedSector min_size;
	PedGeometry full_disk;
	reiserfs_fs_t *fs_info;
	PedAlignment start_align;
	PedGeometry start_sector;

	PED_ASSERT(fs != NULL, return NULL);

	fs_info = fs->type_specific;
	dev = fs->geom->dev;

	if (!ped_alignment_init(&start_align, fs->geom->start, 0))
		return NULL;
	if (!ped_geometry_init(&full_disk, dev, 0, dev->length - 1))
		return NULL;
	if (!ped_geometry_init(&start_sector, dev, fs->geom->start, 1))
		return NULL;

	/* 
	   Minsize for reiserfs is area occupied by data blocks and 
	   metadata blocks minus free space blocks and minus bitmap 
	   blocks which describes free space blocks.
	 */
	min_size = reiserfs_fs_min_size(fs_info) *
	    (reiserfs_fs_block_size(fs_info) / PED_SECTOR_SIZE_DEFAULT);

	return ped_constraint_new(&start_align, ped_alignment_any,
				  &start_sector, &full_disk, min_size,
				  dev->length);
}

static PedFileSystem *reiserfs_copy(const PedFileSystem *fs,
				    PedGeometry *geom, PedTimer *timer)
{
	dal_t *dal;
	PedGeometry *fs_geom;
	PedFileSystem *new_fs;
	blk_t fs_len, min_needed_blk;

	reiserfs_fs_t *dest_fs, *src_fs;
	reiserfs_gauge_t *gauge = NULL;

	fs_geom = ped_geometry_duplicate(geom);

	if (!(dal = geom_dal_create(fs_geom, DEFAULT_BLOCK_SIZE, O_RDWR))) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Couldn't create reiserfs device "
				      "abstraction handler."));
		goto error_free_fs_geom;
	}

	src_fs = fs->type_specific;

	fs_len =
	    (geom->length / (reiserfs_fs_block_size(src_fs) / PED_SECTOR_SIZE_DEFAULT));
	min_needed_blk = reiserfs_fs_bitmap_used(src_fs);

	if (fs_len <= min_needed_blk) {
		ped_exception_throw(PED_EXCEPTION_ERROR,
				    PED_EXCEPTION_CANCEL,
				    _("Device is too small for %lu blocks."),
				    min_needed_blk);
		goto error_free_dal;
	}

	if (! (new_fs = (PedFileSystem *) ped_malloc(sizeof(PedFileSystem))))
		goto error_free_dal;

	ped_timer_reset(timer);
	ped_timer_set_state_name(timer, _("copying"));
	ped_timer_update(timer, 0.0);

	if (libreiserfs_gauge_create && libreiserfs_gauge_free) {
		if (! (gauge =
		     libreiserfs_gauge_create(NULL, gauge_handler, timer)))
			goto error_free_new_fs;
	}

	if (!(dest_fs = reiserfs_fs_copy(src_fs, dal, gauge)))
		goto error_free_gauge;

	ped_timer_update(timer, 1.0);

	if (gauge)
		libreiserfs_gauge_free(gauge);

	new_fs->type = reiserfs_type;
	new_fs->geom = fs_geom;
	new_fs->type_specific = (void *) dest_fs;

	return new_fs;

error_free_gauge:
	if (gauge)
		libreiserfs_gauge_free(gauge);
error_free_new_fs:
	ped_free(new_fs);
error_free_dal:
	geom_dal_free(dal);
error_free_fs_geom:
	ped_geometry_destroy(fs_geom);
	return NULL;
}

static PedConstraint *reiserfs_get_copy_constraint(const PedFileSystem *fs,
						   const PedDevice *dev)
{
	PedGeometry full_dev;

	PED_ASSERT(fs != NULL, return NULL);
	PED_ASSERT(dev != NULL, return NULL);

	if (!ped_geometry_init(&full_dev, dev, 0, dev->length - 1))
		return NULL;

	return ped_constraint_new(ped_alignment_any, ped_alignment_any,
				  &full_dev, &full_dev,
				  reiserfs_fs_bitmap_used(fs->type_specific),
				  dev->length);
}

#endif /* !REISER_FULL_SUPPORT */

#ifdef DYNAMIC_LOADING

#define INIT_SYM(SYM)	SYM = getsym (libreiserfs_handle, #SYM)

static void *getsym(void *handle, const char *symbol)
{
	void *entry;
	char *error;

	entry = dlsym(handle, symbol);
	if ((error = dlerror()) != NULL) {
		ped_exception_throw(PED_EXCEPTION_WARNING,
				    PED_EXCEPTION_IGNORE,
				    _("Couldn't resolve symbol %s.  "
				      "Error: %s."),
				    symbol, error);
		return NULL;
	}

	return entry;
}

static int reiserfs_ops_interface_version_check(void)
{
	int min_interface_version, max_interface_version;
	int (*libreiserfs_get_max_interface_version) (void);
	int (*libreiserfs_get_min_interface_version) (void);

	INIT_SYM(libreiserfs_get_max_interface_version);
	INIT_SYM(libreiserfs_get_min_interface_version);

	if (!libreiserfs_get_min_interface_version ||
	    !libreiserfs_get_max_interface_version) {
		ped_exception_throw(
			PED_EXCEPTION_WARNING, PED_EXCEPTION_CANCEL,
			_("GNU Parted found an invalid libreiserfs library."));
		return 0;
	}

	min_interface_version = libreiserfs_get_min_interface_version();
	max_interface_version = libreiserfs_get_max_interface_version();

	if (REISERFS_API_VERSION < min_interface_version ||
	    REISERFS_API_VERSION > max_interface_version) {
		ped_exception_throw(
			PED_EXCEPTION_WARNING, PED_EXCEPTION_CANCEL,
			_("GNU Parted has detected libreiserfs interface "
			  "version mismatch.  Found %d-%d, required %d. "
			  "ReiserFS support will be disabled."),
			min_interface_version,
			max_interface_version,
			REISERFS_API_VERSION);
		return 0;
	}

	return 1;
}

static int reiserfs_ops_init(void)
{
	if (!(libreiserfs_handle = dlopen("libreiserfs.so", RTLD_NOW)))
		goto error;

	if (!reiserfs_ops_interface_version_check())
		goto error_free_libreiserfs_handle;

	if (!(libdal_handle = dlopen("libdal.so", RTLD_NOW)))
		goto error_free_libreiserfs_handle;

	INIT_SYM(reiserfs_fs_probe);
	INIT_SYM(libreiserfs_exception_type);

	INIT_SYM(libreiserfs_exception_option);
	INIT_SYM(libreiserfs_exception_message);
	INIT_SYM(libreiserfs_exception_set_handler);

	INIT_SYM(reiserfs_fs_clobber);
	INIT_SYM(reiserfs_fs_open);
	INIT_SYM(reiserfs_fs_create);
	INIT_SYM(reiserfs_fs_resize);
	INIT_SYM(reiserfs_fs_copy);

	INIT_SYM(reiserfs_fs_is_resizeable);
	INIT_SYM(reiserfs_fs_is_consistent);

	INIT_SYM(reiserfs_fs_bitmap_check);
	INIT_SYM(reiserfs_fs_bitmap_used);

	INIT_SYM(reiserfs_fs_min_size);
	INIT_SYM(reiserfs_fs_block_size);

	INIT_SYM(reiserfs_fs_host_dal);
	INIT_SYM(reiserfs_fs_close);

	INIT_SYM(libreiserfs_gauge_create);
	INIT_SYM(libreiserfs_gauge_free);

	INIT_SYM(dal_realize);
	INIT_SYM(dal_flags);

	INIT_SYM(dal_block_size);
	INIT_SYM(dal_len);

	return 1;

error_free_libreiserfs_handle:
	dlclose(libreiserfs_handle);
	libreiserfs_handle = NULL;
error:
	return 0;
}

static void reiserfs_ops_done()
{
	if (libdal_handle)
		dlclose(libdal_handle);
	if (libreiserfs_handle)
		dlclose(libreiserfs_handle);
}
#endif /* DYNAMIC_LOADING */

#define REISER_BLOCK_SIZES ((int[]){512, 1024, 2048, 4096, 8192, 0})

#ifdef REISER_FULL_SUPPORT
static PedFileSystemOps reiserfs_full_ops = {
	probe:		reiserfs_probe,
	clobber:	reiserfs_clobber,
	open:		reiserfs_open,
	create:		reiserfs_create,
	close:		reiserfs_close,
	check:		reiserfs_check,
	copy:		reiserfs_copy,
	resize:		reiserfs_resize,
	get_create_constraint:	reiserfs_get_create_constraint,
	get_resize_constraint:	reiserfs_get_resize_constraint,
	get_copy_constraint:	reiserfs_get_copy_constraint
};

static PedFileSystemType reiserfs_full_type = {
	next:	NULL,
	ops:	&reiserfs_full_ops,
	name:	"reiserfs",
        block_sizes:    REISER_BLOCK_SIZES
};
#endif /* REISER_FULL_SUPPORT */

static PedFileSystemOps reiserfs_simple_ops = {
	probe:		reiserfs_probe,
#ifdef DISCOVER_ONLY
	clobber:	NULL,
#else
	clobber:	reiserfs_clobber,
#endif
	open:		NULL,
	create:		NULL,
	close:		NULL,
	check:		NULL,
	copy:		NULL,
	resize:		NULL,
	get_create_constraint:	NULL,
	get_resize_constraint:	NULL,
	get_copy_constraint:	NULL
};

static PedFileSystemType reiserfs_simple_type = {
	next:	        NULL,
	ops:	        &reiserfs_simple_ops,
	name:	        "reiserfs",
        block_sizes:    REISER_BLOCK_SIZES
};

void ped_file_system_reiserfs_init()
{
#ifdef DYNAMIC_LOADING
	libreiserfs_present = reiserfs_ops_init();
	if (libreiserfs_present) {
		reiserfs_type = &reiserfs_full_type;
		libreiserfs_exception_set_handler(exception_handler);
	} else {
		reiserfs_type = &reiserfs_simple_type;
	}
#else	/* !DYNAMIC_LOADING */
#ifdef REISER_FULL_SUPPORT
	libreiserfs_exception_set_handler(exception_handler);
	reiserfs_type = &reiserfs_full_type;
#else
	reiserfs_type = &reiserfs_simple_type;
#endif
#endif	/* !DYNAMIC_LOADING */
	ped_file_system_type_register(reiserfs_type);
}

void ped_file_system_reiserfs_done()
{
	ped_file_system_type_unregister(reiserfs_type);
#ifdef DYNAMIC_LOADING
	reiserfs_ops_done();
#endif /* DYNAMIC_LOADING */
}
