/*
 * 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 reiserfs_key  MAX_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 = MAX_KEY;
    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 (*(__u32 *)item);
        obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid);
	obj_key.on_disk_key.u.k_offset_v1.k_offset = 0;
	obj_key.on_disk_key.u.k_offset_v1.k_uniqueness = 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;
    __u32 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" */
	    *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 == -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);
