/*
 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
 *
 * Trivial changes by Alan Cox to add the LFS fixes
 *
 * Trivial Changes:
 * Rights granted to Hans Reiser to redistribute under other terms providing
 * he accepts all liability including but not limited to patent, fitness
 * for purpose, and direct or indirect claims arising from failure to perform.
 *
 * NO WARRANTY
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
#include <asm/uaccess.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
#include <linux/namespace.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/quotaops.h>

struct file_system_type reiserfs_fs_type;

static const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
static const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
static const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;

int is_reiserfs_3_5 (struct reiserfs_super_block * rs)
{
  return !strncmp (rs->s_v1.s_magic, reiserfs_3_5_magic_string,
		   strlen (reiserfs_3_5_magic_string));
}


int is_reiserfs_3_6 (struct reiserfs_super_block * rs)
{
  return !strncmp (rs->s_v1.s_magic, reiserfs_3_6_magic_string,
 		   strlen (reiserfs_3_6_magic_string));
}


int is_reiserfs_jr (struct reiserfs_super_block * rs)
{
  return !strncmp (rs->s_v1.s_magic, reiserfs_jr_magic_string,
 		   strlen (reiserfs_jr_magic_string));
}


static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs)
{
  return (is_reiserfs_3_5 (rs) || is_reiserfs_3_6 (rs) ||
	  is_reiserfs_jr (rs));
}

static int reiserfs_remount (struct super_block * s, int * flags, char * data);
static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);

static int reiserfs_sync_fs (struct super_block * s, int wait)
{
    if (!(s->s_flags & MS_RDONLY)) {
        struct reiserfs_transaction_handle th;
	reiserfs_write_lock(s);
	if (!journal_begin(&th, s, 1))
            if (!journal_end_sync(&th, s, 1))
                reiserfs_flush_old_commits(s);
	s->s_dirt = 0; /* Even if it's not true.
                        * We'll loop forever in sync_supers otherwise */
	reiserfs_write_unlock(s);
    } else {
        s->s_dirt = 0;
    }
    return 0;
}

static void reiserfs_write_super(struct super_block *s)
{
    reiserfs_sync_fs(s, 1);
}

static void reiserfs_write_super_lockfs (struct super_block * s)
{
  struct reiserfs_transaction_handle th ;
  reiserfs_write_lock(s);
  if (!(s->s_flags & MS_RDONLY)) {
    int err = journal_begin(&th, s, 1) ;
    if (err) {
        reiserfs_block_writes(&th) ;
    } else {
        reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
        journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
        reiserfs_block_writes(&th) ;
        journal_end_sync(&th, s, 1) ;
    }
  }
  s->s_dirt = 0;
  reiserfs_write_unlock(s);
}

static void reiserfs_unlockfs(struct super_block *s) {
  reiserfs_allow_writes(s) ;
}

extern const struct in_core_key  MAX_IN_CORE_KEY;


/* this is used to delete "save link" when there are no items of a
   file it points to. It can either happen if unlink is completed but
   "save unlink" removal, or if file has both unlink and truncate
   pending and as unlink completes first (because key of "save link"
   protecting unlink is bigger that a key lf "save link" which
   protects truncate), so there left no items to make truncate
   completion on */
static int remove_save_link_only (struct super_block * s, struct reiserfs_key * key, int oid_free)
{
    struct reiserfs_transaction_handle th;
    int err;

     /* we are going to do one balancing */
     err = journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
     if (err)
        return err;
 
     reiserfs_delete_solid_item (&th, NULL, key);
     if (oid_free)
        /* removals are protected by direct items */
        reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));

     return journal_end (&th, s, JOURNAL_PER_BALANCE_CNT);
}
 
#ifdef CONFIG_QUOTA
static int reiserfs_quota_on_mount(struct super_block *, int);
#endif
 
/* look for uncompleted unlinks and truncates and complete them */
static int finish_unfinished (struct super_block * s)
{
    INITIALIZE_PATH (path);
    struct cpu_key max_cpu_key, obj_key;
    struct reiserfs_key save_link_key;
    int retval = 0;
    struct item_head * ih;
    struct buffer_head * bh;
    int item_pos;
    char * item;
    int done;
    struct inode * inode;
    int truncate;
#ifdef CONFIG_QUOTA
    int i;
    int ms_active_set;
#endif
 
 
    /* compose key to look for "save" links */
    max_cpu_key.version = KEY_FORMAT_3_5;
    max_cpu_key.on_disk_key.k_dir_id = ~0U;
    max_cpu_key.on_disk_key.k_objectid = ~0U;
    set_cpu_key_k_offset (&max_cpu_key, ~0U);
    max_cpu_key.key_length = 3;

#ifdef CONFIG_QUOTA
    /* Needed for iput() to work correctly and not trash data */
    if (s->s_flags & MS_ACTIVE) {
	    ms_active_set = 0;
    } else {
	    ms_active_set = 1;
	    s->s_flags |= MS_ACTIVE;
    }
    /* Turn on quotas so that they are updated correctly */
    for (i = 0; i < MAXQUOTAS; i++) {
	if (REISERFS_SB(s)->s_qf_names[i]) {
	    int ret = reiserfs_quota_on_mount(s, i);
	    if (ret < 0)
		reiserfs_warning(s, "reiserfs: cannot turn on journalled quota: error %d", ret);
	}
    }
#endif
 
    done = 0;
    REISERFS_SB(s)->s_is_unlinked_ok = 1;
    while (!retval) {
        retval = search_item (s, &max_cpu_key, &path);
        if (retval != ITEM_NOT_FOUND) {
            reiserfs_warning (s, "vs-2140: finish_unfinished: search_by_key returned %d",
                              retval);
            break;
        }
        
        bh = get_last_bh (&path);
        item_pos = get_item_pos (&path);
        if (item_pos != B_NR_ITEMS (bh)) {
            reiserfs_warning (s, "vs-2060: finish_unfinished: wrong position found");
            break;
        }
        item_pos --;
        ih = B_N_PITEM_HEAD (bh, item_pos);
 
        if (le32_to_cpu (ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
            /* there are no "save" links anymore */
            break;
 
        save_link_key = ih->ih_key;
        if (is_indirect_le_ih (ih))
            truncate = 1;
        else
            truncate = 0;
 
        /* reiserfs_iget needs k_dirid and k_objectid only */
        item = B_I_PITEM (bh, ih);
        obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__le32 *)item);
        obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid);
	obj_key.on_disk_key.k_offset = 0;
	obj_key.on_disk_key.k_type = 0;
	
        pathrelse (&path);
 
        inode = reiserfs_iget (s, &obj_key);
        if (!inode) {
            /* the unlink almost completed, it just did not manage to remove
	       "save" link and release objectid */
            reiserfs_warning (s, "vs-2180: finish_unfinished: iget failed for %K",
                              &obj_key);
            retval = remove_save_link_only (s, &save_link_key, 1);
            continue;
        }

	if (!truncate && inode->i_nlink) {
	    /* file is not unlinked */
            reiserfs_warning (s, "vs-2185: finish_unfinished: file %K is not unlinked",
                              &obj_key);
            retval = remove_save_link_only (s, &save_link_key, 0);
            continue;
	}
	DQUOT_INIT(inode);

	if (truncate && S_ISDIR (inode->i_mode) ) {
	    /* We got a truncate request for a dir which is impossible.
	       The only imaginable way is to execute unfinished truncate request
	       then boot into old kernel, remove the file and create dir with
	       the same key. */
	    reiserfs_warning(s, "green-2101: impossible truncate on a directory %k. Please report", INODE_PKEY (inode));
	    retval = remove_save_link_only (s, &save_link_key, 0);
	    truncate = 0;
	    iput (inode); 
	    continue;
	}
 
        if (truncate) {
            REISERFS_I(inode) -> i_flags |= i_link_saved_truncate_mask;
            /* not completed truncate found. New size was committed together
	       with "save" link */
            reiserfs_info (s, "Truncating %k to %Ld ..",
                              INODE_PKEY (inode), inode->i_size);
            reiserfs_truncate_file (inode, 0/*don't update modification time*/);
            retval = remove_save_link (inode, truncate);
        } else {
            REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
            /* not completed unlink (rmdir) found */
            reiserfs_info (s, "Removing %k..", INODE_PKEY (inode));
            /* removal gets completed in iput */
            retval = 0;
        }
 
        iput (inode);
        printk ("done\n");
        done ++;
    }
    REISERFS_SB(s)->s_is_unlinked_ok = 0;
     
#ifdef CONFIG_QUOTA
    /* Turn quotas off */
    for (i = 0; i < MAXQUOTAS; i++) {
            if (sb_dqopt(s)->files[i])
                    vfs_quota_off_mount(s, i);
    }
    if (ms_active_set)
	    /* Restore the flag back */
	    s->s_flags &= ~MS_ACTIVE;
#endif
    pathrelse (&path);
    if (done)
        reiserfs_info (s, "There were %d uncompleted unlinks/truncates. "
                          "Completed\n", done);
    return retval;
}
 
/* to protect file being unlinked from getting lost we "safe" link files
   being unlinked. This link will be deleted in the same transaction with last
   item of file. mounting the filesytem we scan all these links and remove
   files which almost got lost */
void add_save_link (struct reiserfs_transaction_handle * th,
		    struct inode * inode, int truncate)
{
    INITIALIZE_PATH (path);
    int retval;
    struct cpu_key key;
    struct item_head ih;
    __le32 link;

    BUG_ON (!th->t_trans_id);

    /* file can only get one "save link" of each kind */
    RFALSE( truncate && 
	    ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ),
	    "saved link already exists for truncated inode %lx",
	    ( long ) inode -> i_ino );
    RFALSE( !truncate && 
	    ( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ),
	    "saved link already exists for unlinked inode %lx",
	    ( long ) inode -> i_ino );

    /* setup key of "save" link */
    key.version = KEY_FORMAT_3_5;
    key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID;
    key.on_disk_key.k_objectid = inode->i_ino;
    if (!truncate) {
	/* unlink, rmdir, rename */
	set_cpu_key_k_offset (&key, 1 + inode->i_sb->s_blocksize);
	set_cpu_key_k_type (&key, TYPE_DIRECT);

	/* item head of "safe" link */
	make_le_item_head (&ih, &key, key.version, 1 + inode->i_sb->s_blocksize, TYPE_DIRECT,
			   4/*length*/, 0xffff/*free space*/);
    } else {
	/* truncate */
	if (S_ISDIR (inode->i_mode))
	    reiserfs_warning(inode->i_sb, "green-2102: Adding a truncate savelink for a directory %k! Please report", INODE_PKEY(inode));
	set_cpu_key_k_offset (&key, 1);
	set_cpu_key_k_type (&key, TYPE_INDIRECT);

	/* item head of "safe" link */
	make_le_item_head (&ih, &key, key.version, 1, TYPE_INDIRECT,
			   4/*length*/, 0/*free space*/);
    }
    key.key_length = 3;

    /* look for its place in the tree */
    retval = search_item (inode->i_sb, &key, &path);
    if (retval != ITEM_NOT_FOUND) {
	if ( retval != -ENOSPC )
	    reiserfs_warning (inode->i_sb, "vs-2100: add_save_link:"
			  "search_by_key (%K) returned %d", &key, retval);
	pathrelse (&path);
	return;
    }

    /* body of "save" link */
    link = INODE_PKEY (inode)->k_dir_id;

    /* put "save" link inot tree, don't charge quota to anyone */
    retval = reiserfs_insert_item (th, &path, &key, &ih, NULL, (char *)&link);
    if (retval) {
	if (retval != -ENOSPC)
	    reiserfs_warning (inode->i_sb, "vs-2120: add_save_link: insert_item returned %d",
			  retval);
    } else {
	if( truncate )
	    REISERFS_I(inode) -> i_flags |= i_link_saved_truncate_mask;
	else
	    REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
    }
}


/* this opens transaction unlike add_save_link */
int remove_save_link (struct inode * inode, int truncate)
{
    struct reiserfs_transaction_handle th;
    struct reiserfs_key key;
    int err;
 
    /* we are going to do one balancing only */
    err = journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
    if (err)
        return err;
 
    /* setup key of "save" link */
    key.k_dir_id = cpu_to_le32 (MAX_KEY_OBJECTID);
    key.k_objectid = INODE_PKEY (inode)->k_objectid;
    if (!truncate) {
        /* unlink, rmdir, rename */
        set_le_key_k_offset (KEY_FORMAT_3_5, &key,
			     1 + inode->i_sb->s_blocksize);
        set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_DIRECT);
    } else {
        /* truncate */
        set_le_key_k_offset (KEY_FORMAT_3_5, &key, 1);
        set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_INDIRECT);
    }
 
    if( ( truncate && 
          ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ) ) ||
        ( !truncate && 
          ( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ) ) )
	/* don't take quota bytes from anywhere */
	reiserfs_delete_solid_item (&th, NULL, &key);
    if (!truncate) {
	reiserfs_release_objectid (&th, inode->i_ino);
	REISERFS_I(inode) -> i_flags &= ~i_link_saved_unlink_mask;
    } else
	REISERFS_I(inode) -> i_flags &= ~i_link_saved_truncate_mask;
 
    return journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
}


static void reiserfs_put_super (struct super_block * s)
{
  int i;
  struct reiserfs_transaction_handle th ;
  th.t_trans_id = 0;

  if (REISERFS_SB(s)->xattr_root) {
    d_invalidate (REISERFS_SB(s)->xattr_root);
    dput (REISERFS_SB(s)->xattr_root);
  }
  
  if (REISERFS_SB(s)->priv_root) {
    d_invalidate (REISERFS_SB(s)->priv_root);
    dput (REISERFS_SB(s)->priv_root);
  }

  /* change file system state to current state if it was mounted with read-write permissions */
  if (!(s->s_flags & MS_RDONLY)) {
    if (!journal_begin(&th, s, 10)) {
        reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
        set_sb_umount_state( SB_DISK_SUPER_BLOCK(s), REISERFS_SB(s)->s_mount_state );
        journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
    }
  }

  /* note, journal_release checks for readonly mount, and can decide not
  ** to do a journal_end
  */
  journal_release(&th, s) ;

  for (i = 0; i < SB_BMAP_NR (s); i ++)
    brelse (SB_AP_BITMAP (s)[i].bh);

  vfree (SB_AP_BITMAP (s));

  brelse (SB_BUFFER_WITH_SB (s));

  print_statistics (s);

  if (REISERFS_SB(s)->s_kmallocs != 0) {
    reiserfs_warning (s, "vs-2004: reiserfs_put_super: allocated memory left %d",
		      REISERFS_SB(s)->s_kmallocs);
  }

  if (REISERFS_SB(s)->reserved_blocks != 0) {
    reiserfs_warning (s, "green-2005: reiserfs_put_super: reserved blocks left %d",
		      REISERFS_SB(s)->reserved_blocks);
  }

  reiserfs_proc_info_done( s );

  kfree(s->s_fs_info);
  s->s_fs_info = NULL;

  return;
}

static kmem_cache_t * reiserfs_inode_cachep;

static struct inode *reiserfs_alloc_inode(struct super_block *sb)
{
	struct reiserfs_inode_info *ei;
	ei = (struct reiserfs_inode_info *)kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL);
	if (!ei)
		return NULL;
	return &ei->vfs_inode;
}

static void reiserfs_destroy_inode(struct inode *inode)
{
	kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
}

static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
{
	struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *) foo;

	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
	    SLAB_CTOR_CONSTRUCTOR) {
		INIT_LIST_HEAD(&ei->i_prealloc_list) ;
		inode_init_once(&ei->vfs_inode);
		ei->i_acl_access = NULL;
		ei->i_acl_default = NULL;
	}
}
 
static int init_inodecache(void)
{
	reiserfs_inode_cachep = kmem_cache_create("reiser_inode_cache",
					     sizeof(struct reiserfs_inode_info),
					     0, SLAB_RECLAIM_ACCOUNT,
					     init_once, NULL);
	if (reiserfs_inode_cachep == NULL)
		return -ENOMEM;
	return 0;
}

static void destroy_inodecache(void)
{
	if (kmem_cache_destroy(reiserfs_inode_cachep))
		reiserfs_warning (NULL, "reiserfs_inode_cache: not all structures were freed");
}

/* we don't mark inodes dirty, we just log them */
static void reiserfs_dirty_inode (struct inode * inode) {
    struct reiserfs_transaction_handle th ;

    int err = 0;
    if (inode->i_sb->s_flags & MS_RDONLY) {
        reiserfs_warning(inode->i_sb, "clm-6006: writing inode %lu on readonly FS",
	                  inode->i_ino) ;
        return ;
    }
    reiserfs_write_lock(inode->i_sb);

    /* this is really only used for atime updates, so they don't have
    ** to be included in O_SYNC or fsync
    */
    err = journal_begin(&th, inode->i_sb, 1) ;
    if (err) {
        reiserfs_write_unlock (inode->i_sb);
        return;
    }
    reiserfs_update_sd (&th, inode);
    journal_end(&th, inode->i_sb, 1) ;
    reiserfs_write_unlock(inode->i_sb);
}

static void reiserfs_clear_inode (struct inode *inode)
{
    struct posix_acl *acl;

    acl = REISERFS_I(inode)->i_acl_access;
    if (acl && !IS_ERR (acl))
        posix_acl_release (acl);
    REISERFS_I(inode)->i_acl_access = NULL;

    acl = REISERFS_I(inode)->i_acl_default;
    if (acl && !IS_ERR (acl))
        posix_acl_release (acl);
    REISERFS_I(inode)->i_acl_default = NULL;
}

#ifdef CONFIG_QUOTA
static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, size_t, loff_t);
static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t, loff_t);
#endif

static struct super_operations reiserfs_sops =
{
  .alloc_inode = reiserfs_alloc_inode,
  .destroy_inode = reiserfs_destroy_inode,
  .write_inode = reiserfs_write_inode,
  .dirty_inode = reiserfs_dirty_inode,
  .delete_inode = reiserfs_delete_inode,
  .clear_inode  = reiserfs_clear_inode,
  .put_super = reiserfs_put_super,
  .write_super = reiserfs_write_super,
  .sync_fs = reiserfs_sync_fs,
  .write_super_lockfs = reiserfs_write_super_lockfs,
  .unlockfs = reiserfs_unlockfs,
  .statfs = reiserfs_statfs,
  .remount_fs = reiserfs_remount,
#ifdef CONFIG_QUOTA
  .quota_read = reiserfs_quota_read,
  .quota_write = reiserfs_quota_write,
#endif
};

#ifdef CONFIG_QUOTA
#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")

static int reiserfs_dquot_initialize(struct inode *, int);
static int reiserfs_dquot_drop(struct inode *);
static int reiserfs_write_dquot(struct dquot *);
static int reiserfs_acquire_dquot(struct dquot *);
static int reiserfs_release_dquot(struct dquot *);
static int reiserfs_mark_dquot_dirty(struct dquot *);
static int reiserfs_write_info(struct super_block *, int);
static int reiserfs_quota_on(struct super_block *, int, int, char *);

static struct dquot_operations reiserfs_quota_operations =
{
  .initialize = reiserfs_dquot_initialize,
  .drop = reiserfs_dquot_drop,
  .alloc_space = dquot_alloc_space,
  .alloc_inode = dquot_alloc_inode,
  .free_space = dquot_free_space,
  .free_inode = dquot_free_inode,
  .transfer = dquot_transfer,
  .write_dquot = reiserfs_write_dquot,
  .acquire_dquot = reiserfs_acquire_dquot,
  .release_dquot = reiserfs_release_dquot,
  .mark_dirty = reiserfs_mark_dquot_dirty,
  .write_info = reiserfs_write_info,
};

static struct quotactl_ops reiserfs_qctl_operations =
{
  .quota_on = reiserfs_quota_on,
  .quota_off = vfs_quota_off,
  .quota_sync = vfs_quota_sync,
  .get_info = vfs_get_dqinfo,
  .set_info = vfs_set_dqinfo,
  .get_dqblk = vfs_get_dqblk,
  .set_dqblk = vfs_set_dqblk,
};
#endif

static struct export_operations reiserfs_export_ops = {
  .encode_fh = reiserfs_encode_fh,
  .decode_fh = reiserfs_decode_fh,
  .get_parent = reiserfs_get_parent,
  .get_dentry = reiserfs_get_dentry,
} ;

/* this struct is used in reiserfs_getopt () for containing the value for those
   mount options that have values rather than being toggles. */
typedef struct {
    char * value;
    int setmask; /* bitmask which is to set on mount_options bitmask when this
                    value is found, 0 is no bits are to be changed. */
    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this
		    value is found, 0 is no bits are to be changed. This is
		    applied BEFORE setmask */
} arg_desc_t;

/* Set this bit in arg_required to allow empty arguments */
#define REISERFS_OPT_ALLOWEMPTY 31

/* this struct is used in reiserfs_getopt() for describing the set of reiserfs
   mount options */
typedef struct {
    char * option_name;
    int arg_required; /* 0 if argument is not required, not 0 otherwise */
    const arg_desc_t * values; /* list of values accepted by an option */
    int setmask; /* bitmask which is to set on mount_options bitmask when this
                    value is found, 0 is no bits are to be changed. */
    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this
		    value is found, 0 is no bits are to be changed. This is
		    applied BEFORE setmask */
} opt_desc_t;

/* possible values for -o data= */
static const arg_desc_t logging_mode[] = {
    {"ordered", 1<<REISERFS_DATA_ORDERED, (1<<REISERFS_DATA_LOG|1<<REISERFS_DATA_WRITEBACK)},
    {"journal", 1<<REISERFS_DATA_LOG, (1<<REISERFS_DATA_ORDERED|1<<REISERFS_DATA_WRITEBACK)},
    {"writeback", 1<<REISERFS_DATA_WRITEBACK, (1<<REISERFS_DATA_ORDERED|1<<REISERFS_DATA_LOG)},
    {NULL, 0}
};

/* possible values for -o barrier= */
static const arg_desc_t barrier_mode[] = {
    {"none", 1<<REISERFS_BARRIER_NONE, 1<<REISERFS_BARRIER_FLUSH},
    {"flush", 1<<REISERFS_BARRIER_FLUSH, 1<<REISERFS_BARRIER_NONE},
    {NULL, 0}
};

/* possible values for "-o block-allocator=" and bits which are to be set in
   s_mount_opt of reiserfs specific part of in-core super block */
static const arg_desc_t balloc[] = {
    {"noborder", 1<<REISERFS_NO_BORDER, 0},
    {"border", 0, 1<<REISERFS_NO_BORDER},
    {"no_unhashed_relocation", 1<<REISERFS_NO_UNHASHED_RELOCATION, 0},
    {"hashed_relocation", 1<<REISERFS_HASHED_RELOCATION, 0},
    {"test4", 1<<REISERFS_TEST4, 0},
    {"notest4", 0, 1<<REISERFS_TEST4},
    {NULL, 0, 0}
};

static const arg_desc_t tails[] = {
    {"on", 1<<REISERFS_LARGETAIL, 1<<REISERFS_SMALLTAIL},
    {"off", 0, (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},
    {"small", 1<<REISERFS_SMALLTAIL, 1<<REISERFS_LARGETAIL},
    {NULL, 0, 0}
};

static const arg_desc_t error_actions[] = {
    {"panic", 1 << REISERFS_ERROR_PANIC,
              (1 << REISERFS_ERROR_RO | 1 << REISERFS_ERROR_CONTINUE)},
    {"ro-remount", 1 << REISERFS_ERROR_RO,
              (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_CONTINUE)},
#ifdef REISERFS_JOURNAL_ERROR_ALLOWS_NO_LOG
    {"continue", 1 << REISERFS_ERROR_CONTINUE,
              (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_RO)},
#endif
    {NULL, 0, 0},
};

int reiserfs_default_io_size = 128 * 1024; /* Default recommended I/O size is 128k.
					      There might be broken applications that are
					      confused by this. Use nolargeio mount option
					      to get usual i/o size = PAGE_SIZE.
					    */

/* proceed only one option from a list *cur - string containing of mount options
   opts - array of options which are accepted
   opt_arg - if option is found and requires an argument and if it is specifed
   in the input - pointer to the argument is stored here
   bit_flags - if option requires to set a certain bit - it is set here
   return -1 if unknown option is found, opt->arg_required otherwise */
static int reiserfs_getopt ( struct super_block * s, char ** cur, opt_desc_t * opts, char ** opt_arg,
			    unsigned long * bit_flags)
{
    char * p;
    /* foo=bar, 
       ^   ^  ^
       |   |  +-- option_end
       |   +-- arg_start
       +-- option_start
    */
    const opt_desc_t * opt;
    const arg_desc_t * arg;
    
    
    p = *cur;
    
    /* assume argument cannot contain commas */
    *cur = strchr (p, ',');
    if (*cur) {
	*(*cur) = '\0';
	(*cur) ++;
    }

    if ( !strncmp (p, "alloc=", 6) ) {
	/* Ugly special case, probably we should redo options parser so that
	   it can understand several arguments for some options, also so that
	   it can fill several bitfields with option values. */
	if ( reiserfs_parse_alloc_options( s, p + 6) ) {
	    return -1;
	} else {
	    return 0;
	}
    }

 
    /* for every option in the list */
    for (opt = opts; opt->option_name; opt ++) {
	if (!strncmp (p, opt->option_name, strlen (opt->option_name))) {
	    if (bit_flags) {
                if (opt->clrmask == (1 << REISERFS_UNSUPPORTED_OPT))
                    reiserfs_warning (s, "%s not supported.", p);
                else
                    *bit_flags &= ~opt->clrmask;
                if (opt->setmask == (1 << REISERFS_UNSUPPORTED_OPT))
                    reiserfs_warning (s, "%s not supported.", p);
                else
                    *bit_flags |= opt->setmask;
	    }
	    break;
	}
    }
    if (!opt->option_name) {
	reiserfs_warning (s, "unknown mount option \"%s\"", p);
	return -1;
    }
    
    p += strlen (opt->option_name);
    switch (*p) {
    case '=':
	if (!opt->arg_required) {
	    reiserfs_warning (s, "the option \"%s\" does not require an argument",
		    opt->option_name);
	    return -1;
	}
	break;
	
    case 0:
	if (opt->arg_required) {
	    reiserfs_warning (s, "the option \"%s\" requires an argument", opt->option_name);
	    return -1;
	}
	break;
    default:
	reiserfs_warning (s, "head of option \"%s\" is only correct", opt->option_name);
	return -1;
    }

    /* move to the argument, or to next option if argument is not required */
    p ++;
    
    if ( opt->arg_required && !(opt->arg_required & (1<<REISERFS_OPT_ALLOWEMPTY)) && !strlen (p) ) {
	/* this catches "option=," if not allowed */
	reiserfs_warning (s, "empty argument for \"%s\"", opt->option_name);
	return -1;
    }
    
    if (!opt->values) {
	/* *=NULLopt_arg contains pointer to argument */
	*opt_arg = p;
	return opt->arg_required & ~(1<<REISERFS_OPT_ALLOWEMPTY);
    }
    
    /* values possible for this option are listed in opt->values */
    for (arg = opt->values; arg->value; arg ++) {
	if (!strcmp (p, arg->value)) {
	    if (bit_flags) {
		*bit_flags &= ~arg->clrmask;
		*bit_flags |= arg->setmask;
	    }
	    return opt->arg_required;
	}
    }
    
    reiserfs_warning (s, "bad value \"%s\" for option \"%s\"", p, opt->option_name);
    return -1;
}

/* returns 0 if something is wrong in option string, 1 - otherwise */
static int reiserfs_parse_options (struct super_block * s, char * options, /* string given via mount's -o */
				   unsigned long * mount_options,
				   /* after the parsing phase, contains the
				      collection of bitflags defining what
				      mount options were selected. */
				   unsigned long * blocks, /* strtol-ed from NNN of resize=NNN */
				   char ** jdev_name,
				   unsigned int * commit_max_age)
{
    int c;
    char * arg = NULL;
    char * pos;
    opt_desc_t opts[] = {
	/* Compatibility stuff, so that -o notail for old setups still work */
	{"tails",	.arg_required = 't', .values = tails},
	{"notail",	.clrmask = (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},
	{"conv",	.setmask = 1<<REISERFS_CONVERT},
	{"attrs",	.setmask = 1<<REISERFS_ATTRS},
	{"noattrs",	.clrmask = 1<<REISERFS_ATTRS},
#ifdef CONFIG_REISERFS_FS_XATTR
	{"user_xattr",	.setmask = 1<<REISERFS_XATTRS_USER},
	{"nouser_xattr",.clrmask = 1<<REISERFS_XATTRS_USER},
#else
	{"user_xattr",	.setmask = 1<<REISERFS_UNSUPPORTED_OPT},
	{"nouser_xattr",.clrmask = 1<<REISERFS_UNSUPPORTED_OPT},
#endif
#ifdef CONFIG_REISERFS_FS_POSIX_ACL
	{"acl",		.setmask = 1<<REISERFS_POSIXACL},
	{"noacl",	.clrmask = 1<<REISERFS_POSIXACL},
#else
	{"acl",		.setmask = 1<<REISERFS_UNSUPPORTED_OPT},
	{"noacl",	.clrmask = 1<<REISERFS_UNSUPPORTED_OPT},
#endif
	{"nolog",},	 /* This is unsupported */
	{"replayonly",	.setmask = 1<<REPLAYONLY},
	{"block-allocator", .arg_required = 'a', .values = balloc},
	{"data",	.arg_required = 'd', .values = logging_mode},
	{"barrier",	.arg_required = 'b', .values = barrier_mode},
	{"resize",	.arg_required = 'r', .values = NULL},
	{"jdev",	.arg_required = 'j', .values = NULL},
	{"nolargeio",	.arg_required = 'w', .values = NULL},
	{"commit",	.arg_required = 'c', .values = NULL},
	{"usrquota",},
	{"grpquota",},
	{"errors", 	.arg_required = 'e', .values = error_actions},
	{"usrjquota",	.arg_required = 'u'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL},
	{"grpjquota",	.arg_required = 'g'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL},
	{"jqfmt",	.arg_required = 'f', .values = NULL},
	{NULL,}
    };
	
    *blocks = 0;
    if (!options || !*options)
	/* use default configuration: create tails, journaling on, no
	   conversion to newest format */
	return 1;
    
    for (pos = options; pos; ) {
	c = reiserfs_getopt (s, &pos, opts, &arg, mount_options);
	if (c == -1)
	    /* wrong option is given */
	    return 0;
	
	if (c == 'r') {
	    char * p;
	    
	    p = NULL;
	    /* "resize=NNN" or "resize=auto" */

	    if (!strcmp(arg, "auto")) {
		    /* From JFS code, to auto-get the size.*/
		    *blocks = s->s_bdev->bd_inode->i_size >> s->s_blocksize_bits;
	    } else {
		    *blocks = simple_strtoul (arg, &p, 0);
		    if (*p != '\0') {
			/* NNN does not look like a number */
			reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg);
			return 0;
		    }
	    }
	}

	if ( c == 'c' ) {
		char *p = NULL;
		unsigned long val = simple_strtoul (arg, &p, 0);
		/* commit=NNN (time in seconds) */
		if ( *p != '\0' || val >= (unsigned int)-1) {
			reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg);
			return 0;
		}
		*commit_max_age = (unsigned int)val;
	}

	if ( c == 'w' ) {
		char *p=NULL;
		int val = simple_strtoul (arg, &p, 0);

		if ( *p != '\0') {
		    reiserfs_warning (s, "reiserfs_parse_options: non-numeric value %s for nolargeio option", arg);
		    return 0;
		}
		if ( val ) 
		    reiserfs_default_io_size = PAGE_SIZE;
		else
		    reiserfs_default_io_size = 128 * 1024;
	}

	if (c == 'j') {
	    if (arg && *arg && jdev_name) {
		if ( *jdev_name ) { //Hm, already assigned?
		    reiserfs_warning (s, "reiserfs_parse_options: journal device was already  specified to be %s", *jdev_name);
		    return 0;
		}
		*jdev_name = arg;
	    }
	}

#ifdef CONFIG_QUOTA
	if (c == 'u' || c == 'g') {
	    int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;

	    if (sb_any_quota_enabled(s)) {
		reiserfs_warning(s, "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");
		return 0;
	    }
	    if (*arg) {	/* Some filename specified? */
	        if (REISERFS_SB(s)->s_qf_names[qtype] && strcmp(REISERFS_SB(s)->s_qf_names[qtype], arg)) {
		    reiserfs_warning(s, "reiserfs_parse_options: %s quota file already specified.", QTYPE2NAME(qtype));
		    return 0;
		}
		if (strchr(arg, '/')) {
		    reiserfs_warning(s, "reiserfs_parse_options: quotafile must be on filesystem root.");
		    return 0;
		}
	    	REISERFS_SB(s)->s_qf_names[qtype] = kmalloc(strlen(arg)+1, GFP_KERNEL);
		if (!REISERFS_SB(s)->s_qf_names[qtype]) {
		    reiserfs_warning(s, "reiserfs_parse_options: not enough memory for storing quotafile name.");
		    return 0;
		}
		strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
	    }
	    else {
		if (REISERFS_SB(s)->s_qf_names[qtype]) {
		    kfree(REISERFS_SB(s)->s_qf_names[qtype]);
		    REISERFS_SB(s)->s_qf_names[qtype] = NULL;
		}
	    }
	}
	if (c == 'f') {
	    if (!strcmp(arg, "vfsold"))
		REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_OLD;
	    else if (!strcmp(arg, "vfsv0"))
		REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_V0;
	    else {
		reiserfs_warning(s, "reiserfs_parse_options: unknown quota format specified.");
		return 0;
	    }
	}
#else
	if (c == 'u' || c == 'g' || c == 'f') {
	    reiserfs_warning(s, "reiserfs_parse_options: journalled quota options not supported.");
	    return 0;
	}
#endif
    }
    
#ifdef CONFIG_QUOTA
    if (!REISERFS_SB(s)->s_jquota_fmt && (REISERFS_SB(s)->s_qf_names[USRQUOTA] || REISERFS_SB(s)->s_qf_names[GRPQUOTA])) {
	reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified.");
	return 0;
    }
#endif
    return 1;
}

static void switch_data_mode(struct super_block *s, unsigned long mode) {
    REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) |
                                       (1 << REISERFS_DATA_ORDERED) |
				       (1 << REISERFS_DATA_WRITEBACK));
    REISERFS_SB(s)->s_mount_opt |= (1 << mode);
}

static void handle_data_mode(struct super_block *s, unsigned long mount_options)
{
    if (mount_options & (1 << REISERFS_DATA_LOG)) {
        if (!reiserfs_data_log(s)) {
	    switch_data_mode(s, REISERFS_DATA_LOG);
	    reiserfs_info (s, "switching to journaled data mode\n");
	}
    } else if (mount_options & (1 << REISERFS_DATA_ORDERED)) {
        if (!reiserfs_data_ordered(s)) {
	    switch_data_mode(s, REISERFS_DATA_ORDERED);
	    reiserfs_info (s, "switching to ordered data mode\n");
	}
    } else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) {
        if (!reiserfs_data_writeback(s)) {
	    switch_data_mode(s, REISERFS_DATA_WRITEBACK);
	    reiserfs_info (s, "switching to writeback data mode\n");
	}
    }
}

static void handle_barrier_mode(struct super_block *s, unsigned long bits) {
    int flush = (1 << REISERFS_BARRIER_FLUSH);
    int none = (1 << REISERFS_BARRIER_NONE);
    int all_barrier = flush | none;

    if (bits & all_barrier) {
        REISERFS_SB(s)->s_mount_opt &= ~all_barrier;
	if (bits & flush) {
	    REISERFS_SB(s)->s_mount_opt |= flush;
	    printk("reiserfs: enabling write barrier flush mode\n");
	} else if (bits & none) {
	    REISERFS_SB(s)->s_mount_opt |= none;
	    printk("reiserfs: write barriers turned off\n");
	}
   }
}

static void handle_attrs( struct super_block *s )
{
	struct reiserfs_super_block * rs;

	if( reiserfs_attrs( s ) ) {
		rs = SB_DISK_SUPER_BLOCK (s);
		if( old_format_only(s) ) {
			reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" );
			REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
			return;
		}
		if( !( le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared ) ) {
				reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" );
				REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
		}
	}
}

static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
{
  struct reiserfs_super_block * rs;
  struct reiserfs_transaction_handle th ;
  unsigned long blocks;
  unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
  unsigned long safe_mask = 0;
  unsigned int commit_max_age = (unsigned int)-1;
  struct reiserfs_journal *journal = SB_JOURNAL(s);
  int err;
#ifdef CONFIG_QUOTA
  int i;
#endif

  rs = SB_DISK_SUPER_BLOCK (s);

  if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
#ifdef CONFIG_QUOTA
    for (i = 0; i < MAXQUOTAS; i++)
	if (REISERFS_SB(s)->s_qf_names[i]) {
	    kfree(REISERFS_SB(s)->s_qf_names[i]);
	    REISERFS_SB(s)->s_qf_names[i] = NULL;
	}
#endif
    return -EINVAL;
  }
  
  handle_attrs(s);

  /* Add options that are safe here */
  safe_mask |= 1 << REISERFS_SMALLTAIL;
  safe_mask |= 1 << REISERFS_LARGETAIL;
  safe_mask |= 1 << REISERFS_NO_BORDER;
  safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;
  safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
  safe_mask |= 1 << REISERFS_TEST4;
  safe_mask |= 1 << REISERFS_ATTRS;
  safe_mask |= 1 << REISERFS_XATTRS_USER;
  safe_mask |= 1 << REISERFS_POSIXACL;
  safe_mask |= 1 << REISERFS_BARRIER_FLUSH;
  safe_mask |= 1 << REISERFS_BARRIER_NONE;
  safe_mask |= 1 << REISERFS_ERROR_RO;
  safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
  safe_mask |= 1 << REISERFS_ERROR_PANIC;

  /* Update the bitmask, taking care to keep
   * the bits we're not allowed to change here */
  REISERFS_SB(s)->s_mount_opt = (REISERFS_SB(s)->s_mount_opt & ~safe_mask) |  (mount_options & safe_mask);

  if(commit_max_age != 0 && commit_max_age != (unsigned int)-1) {
    journal->j_max_commit_age = commit_max_age;
    journal->j_max_trans_age = commit_max_age;
  }
  else if(commit_max_age == 0)
  {
    /* 0 means restore defaults. */
    journal->j_max_commit_age = journal->j_default_max_commit_age;
    journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
  }

  if(blocks) {
    int rc = reiserfs_resize(s, blocks);
    if (rc != 0)
      return rc;
  }

  if (*mount_flags & MS_RDONLY) {
    reiserfs_xattr_init (s, *mount_flags);
    /* remount read-only */
    if (s->s_flags & MS_RDONLY)
      /* it is read-only already */
      return 0;
    /* try to remount file system with read-only permissions */
    if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
      return 0;
    }

    err = journal_begin(&th, s, 10) ;
    if (err)
        return err;

    /* Mounting a rw partition read-only. */
    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
    set_sb_umount_state( rs, REISERFS_SB(s)->s_mount_state );
    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
  } else {
    /* remount read-write */
    if (!(s->s_flags & MS_RDONLY)) {
	reiserfs_xattr_init (s, *mount_flags);
	return 0; /* We are read-write already */
    }

    if (reiserfs_is_journal_aborted (journal))
	return journal->j_errno;

    handle_data_mode(s, mount_options);
    handle_barrier_mode(s, mount_options);
    REISERFS_SB(s)->s_mount_state = sb_umount_state(rs) ;
    s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
    err = journal_begin(&th, s, 10) ;
    if (err)
	return err;
    
    /* Mount a partition which is read-only, read-write */
    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
    REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
    s->s_flags &= ~MS_RDONLY;
    set_sb_umount_state( rs, REISERFS_ERROR_FS );
    /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
    REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS ;
  }
  /* this will force a full flush of all journal lists */
  SB_JOURNAL(s)->j_must_wait = 1 ;
  err = journal_end(&th, s, 10) ;
  if (err)
    return err;
  s->s_dirt = 0;

  if (!( *mount_flags & MS_RDONLY ) ) {
    finish_unfinished( s );
    reiserfs_xattr_init (s, *mount_flags);
  }

  return 0;
}

/* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk.
 * @sb - superblock for this filesystem
 * @bi - the bitmap info to be loaded. Requires that bi->bh is valid.
 *
 * This routine counts how many free bits there are, finding the first zero
 * as a side effect. Could also be implemented as a loop of test_bit() calls, or
 * a loop of find_first_zero_bit() calls. This implementation is similar to
 * find_first_zero_bit(), but doesn't return after it finds the first bit.
 * Should only be called on fs mount, but should be fairly efficient anyways.
 *
 * bi->first_zero_hint is considered unset if it == 0, since the bitmap itself
 * will * invariably occupt block 0 represented in the bitmap. The only
 * exception to this is when free_count also == 0, since there will be no
 * free blocks at all.
 */

static void load_bitmap_info_data (struct super_block *sb,
                                   struct reiserfs_bitmap_info *bi)
{
    unsigned long *cur = (unsigned long *)bi->bh->b_data;

    while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) {

	/* No need to scan if all 0's or all 1's.
	 * Since we're only counting 0's, we can simply ignore all 1's */
	if (*cur == 0) {
	    if (bi->first_zero_hint == 0) {
		bi->first_zero_hint = ((char *)cur - bi->bh->b_data) << 3;
	    }
	    bi->free_count += sizeof(unsigned long)*8;
	} else if (*cur != ~0L) {
	    int b;
	    for (b = 0; b < sizeof(unsigned long)*8; b++) {
		if (!reiserfs_test_le_bit (b, cur)) {
		    bi->free_count ++;
		    if (bi->first_zero_hint == 0)
			bi->first_zero_hint =
					(((char *)cur - bi->bh->b_data) << 3) + b;
		    }
		}
	    }
	cur ++;
    }

#ifdef CONFIG_REISERFS_CHECK
// This outputs a lot of unneded info on big FSes
//    reiserfs_warning ("bitmap loaded from block %d: %d free blocks",
//		      bi->bh->b_blocknr, bi->free_count);
#endif
}
  
static int read_bitmaps (struct super_block * s)
{
    int i, bmap_nr;

    SB_AP_BITMAP (s) = vmalloc (sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
    if (SB_AP_BITMAP (s) == 0)
	return 1;
    memset (SB_AP_BITMAP (s), 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
    for (i = 0, bmap_nr = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
	 i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
	SB_AP_BITMAP (s)[i].bh = sb_getblk(s, bmap_nr);
	if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
	    ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);
    }
    for (i = 0; i < SB_BMAP_NR(s); i++) {
	wait_on_buffer(SB_AP_BITMAP (s)[i].bh);
	if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
	    reiserfs_warning(s,"sh-2029: reiserfs read_bitmaps: "
			 "bitmap block (#%lu) reading failed",
			 SB_AP_BITMAP(s)[i].bh->b_blocknr);
	    for (i = 0; i < SB_BMAP_NR(s); i++)
		brelse(SB_AP_BITMAP(s)[i].bh);
	    vfree(SB_AP_BITMAP(s));
	    SB_AP_BITMAP(s) = NULL;
	    return 1;
	}
	load_bitmap_info_data (s, SB_AP_BITMAP (s) + i);
    }
    return 0;
}

static int read_old_bitmaps (struct super_block * s)
{
  int i ;
  struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s);
  int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1;  /* first of bitmap blocks */

  /* read true bitmap */
  SB_AP_BITMAP (s) = vmalloc (sizeof (struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
  if (SB_AP_BITMAP (s) == 0)
    return 1;

  memset (SB_AP_BITMAP (s), 0, sizeof (struct reiserfs_buffer_info *) * sb_bmap_nr(rs));

  for (i = 0; i < sb_bmap_nr(rs); i ++) {
    SB_AP_BITMAP (s)[i].bh = sb_bread (s, bmp1 + i);
    if (!SB_AP_BITMAP (s)[i].bh)
      return 1;
    load_bitmap_info_data (s, SB_AP_BITMAP (s) + i);
  }

  return 0;
}

static int read_super_block (struct super_block * s, int offset)
{
    struct buffer_head * bh;
    struct reiserfs_super_block * rs;
    int fs_blocksize;
 

    bh = sb_bread (s, offset / s->s_blocksize);
    if (!bh) {
      reiserfs_warning (s, "sh-2006: read_super_block: "
              "bread failed (dev %s, block %lu, size %lu)",
              reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
      return 1;
    }
 
    rs = (struct reiserfs_super_block *)bh->b_data;
    if (!is_any_reiserfs_magic_string (rs)) {
      brelse (bh);
      return 1;
    }
 
    //
    // ok, reiserfs signature (old or new) found in at the given offset
    //    
    fs_blocksize = sb_blocksize(rs);
    brelse (bh);
    sb_set_blocksize (s, fs_blocksize);
    
    bh = sb_bread (s, offset / s->s_blocksize);
    if (!bh) {
	reiserfs_warning (s, "sh-2007: read_super_block: "
                "bread failed (dev %s, block %lu, size %lu)\n",
                reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
	return 1;
    }
    
    rs = (struct reiserfs_super_block *)bh->b_data;
    if (sb_blocksize(rs) != s->s_blocksize) {
	reiserfs_warning (s, "sh-2011: read_super_block: "
		"can't find a reiserfs filesystem on (dev %s, block %Lu, size %lu)\n",
		reiserfs_bdevname (s), (unsigned long long)bh->b_blocknr, s->s_blocksize);
	brelse (bh);
	return 1;
    }

    if ( rs->s_v1.s_root_block == cpu_to_le32(-1) ) {
       brelse(bh) ;
       reiserfs_warning (s, "Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
              "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
              "get newer reiserfsprogs package");
       return 1;
    }

    SB_BUFFER_WITH_SB (s) = bh;
    SB_DISK_SUPER_BLOCK (s) = rs;

    if (is_reiserfs_jr (rs)) {
	/* magic is of non-standard journal filesystem, look at s_version to
	   find which format is in use */
	if (sb_version(rs) == REISERFS_VERSION_2)
	  reiserfs_warning (s, "read_super_block: found reiserfs format \"3.6\""
		  " with non-standard journal");
	else if (sb_version(rs) == REISERFS_VERSION_1)
	  reiserfs_warning (s, "read_super_block: found reiserfs format \"3.5\""
		  " with non-standard journal");
	else {
	  reiserfs_warning (s, "sh-2012: read_super_block: found unknown "
			    "format \"%u\" of reiserfs with non-standard magic",
			    sb_version(rs));
	return 1;
	}
    }
    else
      /* s_version of standard format may contain incorrect information,
	 so we just look at the magic string */
      reiserfs_info (s, "found reiserfs format \"%s\" with standard journal\n",
	      is_reiserfs_3_5 (rs) ? "3.5" : "3.6");

    s->s_op = &reiserfs_sops;
    s->s_export_op = &reiserfs_export_ops;
#ifdef CONFIG_QUOTA
    s->s_qcop = &reiserfs_qctl_operations;
    s->dq_op = &reiserfs_quota_operations;
#endif

    /* new format is limited by the 32 bit wide i_blocks field, want to
    ** be one full block below that.
    */
    s->s_maxbytes = (512LL << 32) - s->s_blocksize ;
    return 0;
}



/* after journal replay, reread all bitmap and super blocks */
static int reread_meta_blocks(struct super_block *s) {
  int i ;
  ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))) ;
  wait_on_buffer(SB_BUFFER_WITH_SB(s)) ;
  if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
    reiserfs_warning (s, "reread_meta_blocks, error reading the super") ;
    return 1 ;
  }

  for (i = 0; i < SB_BMAP_NR(s) ; i++) {
    ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)) ;
    wait_on_buffer(SB_AP_BITMAP(s)[i].bh) ;
    if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
      reiserfs_warning (s, "reread_meta_blocks, error reading bitmap block number %d at %llu",
        i, (unsigned long long)SB_AP_BITMAP(s)[i].bh->b_blocknr) ;
      return 1 ;
    }
  }
  return 0 ;

}


/////////////////////////////////////////////////////
// hash detection stuff


// if root directory is empty - we set default - Yura's - hash and
// warn about it
// FIXME: we look for only one name in a directory. If tea and yura
// bith have the same value - we ask user to send report to the
// mailing list
static __u32 find_hash_out (struct super_block * s)
{
    int retval;
    struct inode * inode;
    struct cpu_key key;
    INITIALIZE_PATH (path);
    struct reiserfs_dir_entry de;
    __u32 hash = DEFAULT_HASH;

    inode = s->s_root->d_inode;

    do { // Some serious "goto"-hater was there ;)
	u32 teahash, r5hash, yurahash;

	make_cpu_key (&key, inode, ~0, TYPE_DIRENTRY, 3);
	retval = search_by_entry_key (s, &key, &path, &de);
	if (retval == IO_ERROR) {
	    pathrelse (&path);
	    return UNSET_HASH ;
	}
	if (retval == NAME_NOT_FOUND)
	    de.de_entry_num --;
	set_de_name_and_namelen (&de);
	if (deh_offset( &(de.de_deh[de.de_entry_num]) ) == DOT_DOT_OFFSET) {
	    /* allow override in this case */
	    if (reiserfs_rupasov_hash(s)) {
		hash = YURA_HASH ;
	    }
	    reiserfs_warning(s,"FS seems to be empty, autodetect "
	                     "is using the default hash");
	    break;
	}
	r5hash=GET_HASH_VALUE (r5_hash (de.de_name, de.de_namelen));
	teahash=GET_HASH_VALUE (keyed_hash (de.de_name, de.de_namelen));
	yurahash=GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen));
	if ( ( (teahash == r5hash) && (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) ) ||
	     ( (teahash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ||
	     ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
	    reiserfs_warning(s,"Unable to automatically detect hash function. "
			     "Please mount with -o hash={tea,rupasov,r5}",
			     reiserfs_bdevname (s));
	    hash = UNSET_HASH;
	    break;
	}
	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == yurahash)
	    hash = YURA_HASH;
	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == teahash)
	    hash = TEA_HASH;
	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == r5hash)
	    hash = R5_HASH;
	else {
	    reiserfs_warning (s,"Unrecognised hash function");
	    hash = UNSET_HASH;
	}
    } while (0);

    pathrelse (&path);
    return hash;
}

// finds out which hash names are sorted with
static int what_hash (struct super_block * s)
{
    __u32 code;

    code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));

    /* reiserfs_hash_detect() == true if any of the hash mount options
    ** were used.  We must check them to make sure the user isn't
    ** using a bad hash value
    */
    if (code == UNSET_HASH || reiserfs_hash_detect(s))
	code = find_hash_out (s);

    if (code != UNSET_HASH && reiserfs_hash_detect(s)) {
	/* detection has found the hash, and we must check against the 
	** mount options 
	*/
	if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {
	    reiserfs_warning (s, "Error, %s hash detected, "
		   "unable to force rupasov hash", reiserfs_hashname(code)) ;
	    code = UNSET_HASH ;
	} else if (reiserfs_tea_hash(s) && code != TEA_HASH) {
	    reiserfs_warning (s, "Error, %s hash detected, "
		   "unable to force tea hash", reiserfs_hashname(code)) ;
	    code = UNSET_HASH ;
	} else if (reiserfs_r5_hash(s) && code != R5_HASH) {
	    reiserfs_warning (s, "Error, %s hash detected, "
		   "unable to force r5 hash", reiserfs_hashname(code)) ;
	    code = UNSET_HASH ;
	} 
    } else { 
        /* find_hash_out was not called or could not determine the hash */
	if (reiserfs_rupasov_hash(s)) {
	    code = YURA_HASH ;
	} else if (reiserfs_tea_hash(s)) {
	    code = TEA_HASH ;
	} else if (reiserfs_r5_hash(s)) {
	    code = R5_HASH ;
	} 
    }

    /* if we are mounted RW, and we have a new valid hash code, update 
    ** the super
    */
    if (code != UNSET_HASH && 
	!(s->s_flags & MS_RDONLY) && 
        code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {
        set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);
    }
    return code;
}

// return pointer to appropriate function
static hashf_t hash_function (struct super_block * s)
{
    switch (what_hash (s)) {
    case TEA_HASH:
	reiserfs_info (s, "Using tea hash to sort names\n");
	return keyed_hash;
    case YURA_HASH:
	reiserfs_info (s, "Using rupasov hash to sort names\n");
	return yura_hash;
    case R5_HASH:
	reiserfs_info (s, "Using r5 hash to sort names\n");
	return r5_hash;
    }
    return NULL;
}

// this is used to set up correct value for old partitions
static int function2code (hashf_t func)
{
    if (func == keyed_hash)
	return TEA_HASH;
    if (func == yura_hash)
	return YURA_HASH;
    if (func == r5_hash)
	return R5_HASH;

    BUG() ; // should never happen

    return 0;
}

#define SWARN(silent, s, ...)			\
	if (!(silent))				\
		reiserfs_warning (s, __VA_ARGS__)

static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
{
    struct inode *root_inode;
    int j;
    struct reiserfs_transaction_handle th ;
    int old_format = 0;
    unsigned long blocks;
    unsigned int commit_max_age = 0;
    int jinit_done = 0 ;
    struct reiserfs_iget_args args ;
    struct reiserfs_super_block * rs;
    char *jdev_name;
    struct reiserfs_sb_info *sbi;
    int errval = -EINVAL;

    sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
    if (!sbi) {
	errval = -ENOMEM;
	goto error;
    }
    s->s_fs_info = sbi;
    memset (sbi, 0, sizeof (struct reiserfs_sb_info));
    /* Set default values for options: non-aggressive tails, RO on errors */
    REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
    REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO);
    /* no preallocation minimum, be smart in
       reiserfs_file_write instead */
    REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
    /* Preallocate by 16 blocks (17-1) at once */
    REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
    /* Initialize the rwsem for xattr dir */
    init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);

    /* setup default block allocator options */
    reiserfs_init_alloc_options(s);

    jdev_name = NULL;
    if (reiserfs_parse_options (s, (char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name, &commit_max_age) == 0) {
	goto error;
    }

    if (blocks) {
	SWARN (silent, s, "jmacd-7: reiserfs_fill_super: resize option "
	       "for remount only");
	goto error;
    }	

    /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
    if (!read_super_block (s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
      old_format = 1;
    /* try new format (64-th 1k block), which can contain reiserfs super block */
    else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) {
      SWARN(silent, s, "sh-2021: reiserfs_fill_super: can not find reiserfs on %s", reiserfs_bdevname (s));
      goto error;
    }

    rs = SB_DISK_SUPER_BLOCK (s);
    /* Let's do basic sanity check to verify that underlying device is not
       smaller than the filesystem. If the check fails then abort and scream,
       because bad stuff will happen otherwise. */
    if ( s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs)*sb_blocksize(rs)) {
	SWARN (silent, s, "Filesystem on %s cannot be mounted because it is bigger than the device", reiserfs_bdevname(s));
	SWARN(silent, s, "You may need to run fsck or increase size of your LVM partition");
	SWARN(silent, s, "Or may be you forgot to reboot after fdisk when it told you to");
	goto error;
    }

    sbi->s_mount_state = SB_REISERFS_STATE(s);
    sbi->s_mount_state = REISERFS_VALID_FS ;

    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
	SWARN(silent, s, "jmacd-8: reiserfs_fill_super: unable to read bitmap");
	goto error;
    }
#ifdef CONFIG_REISERFS_CHECK
    SWARN (silent, s, "CONFIG_REISERFS_CHECK is set ON");
    SWARN (silent, s, "- it is slow mode for debugging.");
#endif

    /* make data=ordered the default */
    if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) &&
        !reiserfs_data_writeback(s))
    {
         REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED);
    }

    if (reiserfs_data_log(s)) {
        reiserfs_info (s, "using journaled data mode\n");
    } else if (reiserfs_data_ordered(s)) {
        reiserfs_info (s, "using ordered data mode\n");
    } else {
        reiserfs_info (s, "using writeback data mode\n");
    }
    if (reiserfs_barrier_flush(s)) {
    	printk("reiserfs: using flush barriers\n");
    }

    // set_device_ro(s->s_dev, 1) ;
    if( journal_init(s, jdev_name, old_format, commit_max_age) ) {
	SWARN(silent, s, "sh-2022: reiserfs_fill_super: unable to initialize journal space") ;
	goto error ;
    } else {
	jinit_done = 1 ; /* once this is set, journal_release must be called
			 ** if we error out of the mount
			 */
    }
    if (reread_meta_blocks(s)) {
	SWARN(silent, s, "jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init") ;
	goto error ;
    }

    if (replay_only (s))
	goto error;

    if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
        SWARN(silent, s, "clm-7000: Detected readonly device, marking FS readonly") ;
	s->s_flags |= MS_RDONLY ;
    }
    args.objectid = REISERFS_ROOT_OBJECTID ;
    args.dirid = REISERFS_ROOT_PARENT_OBJECTID ;
    root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
    if (!root_inode) {
	SWARN(silent, s, "jmacd-10: reiserfs_fill_super: get root inode failed");
	goto error;
    }

    if (root_inode->i_state & I_NEW) {
	reiserfs_read_locked_inode(root_inode, &args);
	unlock_new_inode(root_inode);
    }

    s->s_root = d_alloc_root(root_inode);  
    if (!s->s_root) {
	iput(root_inode);
	goto error;
    }

    // define and initialize hash function
    sbi->s_hash_function = hash_function (s);
    if (sbi->s_hash_function == NULL) {
      dput(s->s_root) ;
      s->s_root = NULL ;
      goto error ;
    }

    if (is_reiserfs_3_5 (rs) || (is_reiserfs_jr (rs) && SB_VERSION (s) == REISERFS_VERSION_1))
	set_bit(REISERFS_3_5, &(sbi->s_properties));
    else
	set_bit(REISERFS_3_6, &(sbi->s_properties));
    
    if (!(s->s_flags & MS_RDONLY)) {

	errval = journal_begin(&th, s, 1) ;
        if (errval) {
	    dput (s->s_root);
	    s->s_root = NULL;
	    goto error;
        }
	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;

        set_sb_umount_state( rs, REISERFS_ERROR_FS );
	set_sb_fs_state (rs, 0);
	
	if (old_format_only(s)) {
	  /* filesystem of format 3.5 either with standard or non-standard
	     journal */
	  if (convert_reiserfs (s)) {
	    /* and -o conv is given */
	    if(!silent)
	      reiserfs_info (s,"converting 3.5 filesystem to the 3.6 format") ;

	    if (is_reiserfs_3_5 (rs))
	      /* put magic string of 3.6 format. 2.2 will not be able to
		 mount this filesystem anymore */
	      memcpy (rs->s_v1.s_magic, reiserfs_3_6_magic_string,
		      sizeof (reiserfs_3_6_magic_string));

	    set_sb_version(rs,REISERFS_VERSION_2);
	    reiserfs_convert_objectid_map_v1(s) ;
	    set_bit(REISERFS_3_6, &(sbi->s_properties));
	    clear_bit(REISERFS_3_5, &(sbi->s_properties));
	  } else if (!silent){
	    reiserfs_info (s, "using 3.5.x disk format\n") ;
	  }
	}

	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
	errval = journal_end(&th, s, 1) ;
	if (errval) {
	    dput (s->s_root);
	    s->s_root = NULL;
	    goto error;
	}

	if ((errval = reiserfs_xattr_init (s, s->s_flags))) {
	    dput (s->s_root);
	    s->s_root = NULL;
	    goto error;
	}

	/* look for files which were to be removed in previous session */
	finish_unfinished (s);
    } else {
	if ( old_format_only(s) && !silent) {
	    reiserfs_info (s, "using 3.5.x disk format\n") ;
	}

	if ((errval = reiserfs_xattr_init (s, s->s_flags))) {
	    dput (s->s_root);
	    s->s_root = NULL;
	    goto error;
	}
    }
    // mark hash in super block: it could be unset. overwrite should be ok
    set_sb_hash_function_code( rs, function2code(sbi->s_hash_function ) );

    handle_attrs( s );

    reiserfs_proc_info_init( s );

    init_waitqueue_head (&(sbi->s_wait));
    spin_lock_init(&sbi->bitmap_lock);

    return (0);

 error:
    if (jinit_done) { /* kill the commit thread, free journal ram */
	journal_release_error(NULL, s) ;
    }
    if (SB_DISK_SUPER_BLOCK (s)) {
	for (j = 0; j < SB_BMAP_NR (s); j ++) {
	    if (SB_AP_BITMAP (s))
		brelse (SB_AP_BITMAP (s)[j].bh);
	}
	if (SB_AP_BITMAP (s))
	    vfree (SB_AP_BITMAP (s));
    }
    if (SB_BUFFER_WITH_SB (s))
	brelse(SB_BUFFER_WITH_SB (s));
#ifdef CONFIG_QUOTA
    for (j = 0; j < MAXQUOTAS; j++) {
	if (sbi->s_qf_names[j])
	    kfree(sbi->s_qf_names[j]);
    }
#endif
    if (sbi != NULL) {
	kfree(sbi);
    }

    s->s_fs_info = NULL;
    return errval;
}


static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf)
{
  struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
  
  buf->f_namelen = (REISERFS_MAX_NAME (s->s_blocksize));
  buf->f_bfree   = sb_free_blocks(rs);
  buf->f_bavail  = buf->f_bfree;
  buf->f_blocks  = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
  buf->f_bsize   = s->s_blocksize;
  /* changed to accommodate gcc folks.*/
  buf->f_type    =  REISERFS_SUPER_MAGIC;
  return 0;
}

#ifdef CONFIG_QUOTA
static int reiserfs_dquot_initialize(struct inode *inode, int type)
{
    struct reiserfs_transaction_handle th;
    int ret;

    /* We may create quota structure so we need to reserve enough blocks */
    reiserfs_write_lock(inode->i_sb);
    journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
    ret = dquot_initialize(inode, type);
    journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
    reiserfs_write_unlock(inode->i_sb);
    return ret;
}

static int reiserfs_dquot_drop(struct inode *inode)
{
    struct reiserfs_transaction_handle th;
    int ret;

    /* We may delete quota structure so we need to reserve enough blocks */
    reiserfs_write_lock(inode->i_sb);
    journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
    ret = dquot_drop(inode);
    journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
    reiserfs_write_unlock(inode->i_sb);
    return ret;
}

static int reiserfs_write_dquot(struct dquot *dquot)
{
    struct reiserfs_transaction_handle th;
    int ret;

    reiserfs_write_lock(dquot->dq_sb);
    journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS);
    ret = dquot_commit(dquot);
    journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS);
    reiserfs_write_unlock(dquot->dq_sb);
    return ret;
}

static int reiserfs_acquire_dquot(struct dquot *dquot)
{
    struct reiserfs_transaction_handle th;
    int ret;

    reiserfs_write_lock(dquot->dq_sb);
    journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
    ret = dquot_acquire(dquot);
    journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
    reiserfs_write_unlock(dquot->dq_sb);
    return ret;
}

static int reiserfs_release_dquot(struct dquot *dquot)
{
    struct reiserfs_transaction_handle th;
    int ret;

    reiserfs_write_lock(dquot->dq_sb);
    journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
    ret = dquot_release(dquot);
    journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
    reiserfs_write_unlock(dquot->dq_sb);
    return ret;
}

static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
{
    /* Are we journalling quotas? */
    if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
        REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
	dquot_mark_dquot_dirty(dquot);
	return reiserfs_write_dquot(dquot);
    }
    else
	return dquot_mark_dquot_dirty(dquot);
}

static int reiserfs_write_info(struct super_block *sb, int type)
{
    struct reiserfs_transaction_handle th;
    int ret;

    /* Data block + inode block */
    reiserfs_write_lock(sb);
    journal_begin(&th, sb, 2);
    ret = dquot_commit_info(sb, type);
    journal_end(&th, sb, 2);
    reiserfs_write_unlock(sb);
    return ret;
}

/*
 * Turn on quotas during mount time - we need to find
 * the quota file and such...
 */
static int reiserfs_quota_on_mount(struct super_block *sb, int type)
{
    int err;
    struct dentry *dentry;
    struct qstr name = { .name = REISERFS_SB(sb)->s_qf_names[type],
                         .hash = 0,
                         .len = strlen(REISERFS_SB(sb)->s_qf_names[type])};

    dentry = lookup_hash(&name, sb->s_root);
    if (IS_ERR(dentry))
            return PTR_ERR(dentry);
    err = vfs_quota_on_mount(type, REISERFS_SB(sb)->s_jquota_fmt, dentry);
    /* Now invalidate and put the dentry - quota got its own reference
     * to inode and dentry has at least wrong hash so we had better
     * throw it away */
    d_invalidate(dentry);
    dput(dentry);
    return err;
}

/*
 * Standard function to be called on quota_on
 */
static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
{
    int err;
    struct nameidata nd;

    err = path_lookup(path, LOOKUP_FOLLOW, &nd);
    if (err)
        return err;
    /* Quotafile not on the same filesystem? */
    if (nd.mnt->mnt_sb != sb) {
	path_release(&nd);
        return -EXDEV;
    }
    /* We must not pack tails for quota files on reiserfs for quota IO to work */
    if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {
	reiserfs_warning(sb, "reiserfs: Quota file must have tail packing disabled.");
	path_release(&nd);
	return -EINVAL;
    }
    /* Not journalling quota? No more tests needed... */
    if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
        !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
	path_release(&nd);
        return vfs_quota_on(sb, type, format_id, path);
    }
    /* Quotafile not of fs root? */
    if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
	reiserfs_warning(sb, "reiserfs: Quota file not on filesystem root. "
                             "Journalled quota will not work.");
    path_release(&nd);
    return vfs_quota_on(sb, type, format_id, path);
}

/* Read data from quotafile - avoid pagecache and such because we cannot afford
 * acquiring the locks... As quota files are never truncated and quota code
 * itself serializes the operations (and noone else should touch the files)
 * we don't have to be afraid of races */
static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
				   size_t len, loff_t off)
{
    struct inode *inode = sb_dqopt(sb)->files[type];
    unsigned long blk = off >> sb->s_blocksize_bits;
    int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
    size_t toread;
    struct buffer_head tmp_bh, *bh;
    loff_t i_size = i_size_read(inode);

    if (off > i_size)
	return 0;
    if (off+len > i_size)
	len = i_size-off;
    toread = len;
    while (toread > 0) {
	tocopy = sb->s_blocksize - offset < toread ? sb->s_blocksize - offset : toread;
	tmp_bh.b_state = 0;
	/* Quota files are without tails so we can safely use this function */
	reiserfs_write_lock(sb);
	err = reiserfs_get_block(inode, blk, &tmp_bh, 0);
	reiserfs_write_unlock(sb);
	if (err)
	    return err;
	if (!buffer_mapped(&tmp_bh))    /* A hole? */
	    memset(data, 0, tocopy);
	else {
	    bh = sb_bread(sb, tmp_bh.b_blocknr);
	    if (!bh)
		return -EIO;
	    memcpy(data, bh->b_data+offset, tocopy);
	    brelse(bh);
	}
	offset = 0;
	toread -= tocopy;
	data += tocopy;
	blk++;
    }
    return len;
}

/* Write to quotafile (we know the transaction is already started and has
 * enough credits) */
static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
				    const char *data, size_t len, loff_t off)
{
    struct inode *inode = sb_dqopt(sb)->files[type];
    unsigned long blk = off >> sb->s_blocksize_bits;
    int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
    int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
    size_t towrite = len;
    struct buffer_head tmp_bh, *bh;

    down(&inode->i_sem);
    while (towrite > 0) {
	tocopy = sb->s_blocksize - offset < towrite ?
	         sb->s_blocksize - offset : towrite;
	tmp_bh.b_state = 0;
	err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
	if (err)
	    goto out;
	if (offset || tocopy != sb->s_blocksize)
	    bh = sb_bread(sb, tmp_bh.b_blocknr);
	else
	    bh = sb_getblk(sb, tmp_bh.b_blocknr);
	if (!bh) {
	    err = -EIO;
	    goto out;
	}
	lock_buffer(bh);
	memcpy(bh->b_data+offset, data, tocopy);
	flush_dcache_page(bh->b_page);
	set_buffer_uptodate(bh);
	unlock_buffer(bh);
	reiserfs_prepare_for_journal(sb, bh, 1);
	journal_mark_dirty(current->journal_info, sb, bh);
	if (!journal_quota)
		reiserfs_add_ordered_list(inode, bh);
	brelse(bh);
	offset = 0;
	towrite -= tocopy;
	data += tocopy;
	blk++;
    }
out:
    if (len == towrite)
	return err;
    if (inode->i_size < off+len-towrite)
	i_size_write(inode, off+len-towrite);
    inode->i_version++;
    inode->i_mtime = inode->i_ctime = CURRENT_TIME;
    mark_inode_dirty(inode);
    up(&inode->i_sem);
    return len - towrite;
}

#endif

static struct super_block*
get_super_block (struct file_system_type *fs_type, int flags,
		 const char *dev_name, void *data)
{
	return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super);
}

static int __init
init_reiserfs_fs ( void )
{
	int ret;

	if ((ret = init_inodecache ())) {
		return ret;
	}

        if ((ret = reiserfs_xattr_register_handlers ()))
            goto failed_reiserfs_xattr_register_handlers;

	reiserfs_proc_info_global_init ();
	reiserfs_proc_register_global ("version", reiserfs_global_version_in_proc);

        ret = register_filesystem (& reiserfs_fs_type);

	if (ret == 0) {
		return 0;
	}

        reiserfs_xattr_unregister_handlers ();

failed_reiserfs_xattr_register_handlers:
	reiserfs_proc_unregister_global ("version");
	reiserfs_proc_info_global_done ();
	destroy_inodecache ();

	return ret;
}

static void __exit
exit_reiserfs_fs ( void )
{
        reiserfs_xattr_unregister_handlers ();
	reiserfs_proc_unregister_global ("version");
	reiserfs_proc_info_global_done ();
        unregister_filesystem (& reiserfs_fs_type);
	destroy_inodecache ();
}

struct file_system_type reiserfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "reiserfs",
	.get_sb		= get_super_block,
	.kill_sb	= kill_block_super,
	.fs_flags	= FS_REQUIRES_DEV,
};

MODULE_DESCRIPTION ("ReiserFS journaled filesystem");
MODULE_AUTHOR      ("Hans Reiser <reiser@namesys.com>");
MODULE_LICENSE     ("GPL");

module_init (init_reiserfs_fs);
module_exit (exit_reiserfs_fs);
