/*
 * 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 = MAX_IN_CORE_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 (*(__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);
