+ 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, err;
+
+ /* We may create quota structure so we need to reserve enough blocks */
+ reiserfs_write_lock(inode->i_sb);
+ ret =
+ journal_begin(&th, inode->i_sb,
+ 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
+ if (ret)
+ goto out;
+ ret = dquot_initialize(inode, type);
+ err =
+ journal_end(&th, inode->i_sb,
+ 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
+ if (!ret && err)
+ ret = err;
+ out:
+ reiserfs_write_unlock(inode->i_sb);
+ return ret;
+}
+
+static int reiserfs_dquot_drop(struct inode *inode)
+{
+ struct reiserfs_transaction_handle th;
+ int ret, err;
+
+ /* We may delete quota structure so we need to reserve enough blocks */
+ reiserfs_write_lock(inode->i_sb);
+ ret =
+ journal_begin(&th, inode->i_sb,
+ 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
+ if (ret)
+ goto out;
+ ret = dquot_drop(inode);
+ err =
+ journal_end(&th, inode->i_sb,
+ 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
+ if (!ret && err)
+ ret = err;
+ out:
+ reiserfs_write_unlock(inode->i_sb);
+ return ret;
+}
+
+static int reiserfs_write_dquot(struct dquot *dquot)
+{
+ struct reiserfs_transaction_handle th;
+ int ret, err;
+
+ reiserfs_write_lock(dquot->dq_sb);
+ ret =
+ journal_begin(&th, dquot->dq_sb,
+ REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+ if (ret)
+ goto out;
+ ret = dquot_commit(dquot);
+ err =
+ journal_end(&th, dquot->dq_sb,
+ REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+ if (!ret && err)
+ ret = err;
+ out:
+ reiserfs_write_unlock(dquot->dq_sb);
+ return ret;
+}
+
+static int reiserfs_acquire_dquot(struct dquot *dquot)
+{
+ struct reiserfs_transaction_handle th;
+ int ret, err;
+
+ reiserfs_write_lock(dquot->dq_sb);
+ ret =
+ journal_begin(&th, dquot->dq_sb,
+ REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+ if (ret)
+ goto out;
+ ret = dquot_acquire(dquot);
+ err =
+ journal_end(&th, dquot->dq_sb,
+ REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+ if (!ret && err)
+ ret = err;
+ out:
+ reiserfs_write_unlock(dquot->dq_sb);
+ return ret;
+}
+
+static int reiserfs_release_dquot(struct dquot *dquot)
+{
+ struct reiserfs_transaction_handle th;
+ int ret, err;
+
+ reiserfs_write_lock(dquot->dq_sb);
+ ret =
+ journal_begin(&th, dquot->dq_sb,
+ REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+ if (ret)
+ goto out;
+ ret = dquot_release(dquot);
+ err =
+ journal_end(&th, dquot->dq_sb,
+ REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+ if (!ret && err)
+ ret = err;
+ out:
+ 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, err;
+
+ /* Data block + inode block */
+ reiserfs_write_lock(sb);
+ ret = journal_begin(&th, sb, 2);
+ if (ret)
+ goto out;
+ ret = dquot_commit_info(sb, type);
+ err = journal_end(&th, sb, 2);
+ if (!ret && err)
+ ret = err;
+ out:
+ 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)
+{
+ return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
+ REISERFS_SB(sb)->s_jquota_fmt, type);
+}
+
+/*
+ * 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;
+
+ if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
+ return -EINVAL;
+ 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);