/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/module.h>
#include <linux/kobject.h>

#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(unsigned long long)btrfs_root_used(&root->root_item));
}

static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(unsigned long long)btrfs_root_limit(&root->root_item));
}

static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf)
{

	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(unsigned long long)btrfs_super_bytes_used(&fs->super_copy));
}

static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(unsigned long long)btrfs_super_total_bytes(&fs->super_copy));
}

static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(unsigned long long)btrfs_super_sectorsize(&fs->super_copy));
}

/* this is for root attrs (subvols/snapshots) */
struct btrfs_root_attr {
	struct attribute attr;
	ssize_t (*show)(struct btrfs_root *, char *);
	ssize_t (*store)(struct btrfs_root *, const char *, size_t);
};

#define ROOT_ATTR(name, mode, show, store) \
static struct btrfs_root_attr btrfs_root_attr_##name = __ATTR(name, mode, show, store)

ROOT_ATTR(blocks_used,	0444,	root_blocks_used_show,	NULL);
ROOT_ATTR(block_limit,	0644,	root_block_limit_show,	NULL);

static struct attribute *btrfs_root_attrs[] = {
	&btrfs_root_attr_blocks_used.attr,
	&btrfs_root_attr_block_limit.attr,
	NULL,
};

/* this is for super attrs (actual full fs) */
struct btrfs_super_attr {
	struct attribute attr;
	ssize_t (*show)(struct btrfs_fs_info *, char *);
	ssize_t (*store)(struct btrfs_fs_info *, const char *, size_t);
};

#define SUPER_ATTR(name, mode, show, store) \
static struct btrfs_super_attr btrfs_super_attr_##name = __ATTR(name, mode, show, store)

SUPER_ATTR(blocks_used,		0444,	super_blocks_used_show,		NULL);
SUPER_ATTR(total_blocks,	0444,	super_total_blocks_show,	NULL);
SUPER_ATTR(blocksize,		0444,	super_blocksize_show,		NULL);

static struct attribute *btrfs_super_attrs[] = {
	&btrfs_super_attr_blocks_used.attr,
	&btrfs_super_attr_total_blocks.attr,
	&btrfs_super_attr_blocksize.attr,
	NULL,
};

static ssize_t btrfs_super_attr_show(struct kobject *kobj,
				    struct attribute *attr, char *buf)
{
	struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info,
						super_kobj);
	struct btrfs_super_attr *a = container_of(attr,
						  struct btrfs_super_attr,
						  attr);

	return a->show ? a->show(fs, buf) : 0;
}

static ssize_t btrfs_super_attr_store(struct kobject *kobj,
				     struct attribute *attr,
				     const char *buf, size_t len)
{
	struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info,
						super_kobj);
	struct btrfs_super_attr *a = container_of(attr,
						  struct btrfs_super_attr,
						  attr);

	return a->store ? a->store(fs, buf, len) : 0;
}

static ssize_t btrfs_root_attr_show(struct kobject *kobj,
				    struct attribute *attr, char *buf)
{
	struct btrfs_root *root = container_of(kobj, struct btrfs_root,
						root_kobj);
	struct btrfs_root_attr *a = container_of(attr,
						 struct btrfs_root_attr,
						 attr);

	return a->show ? a->show(root, buf) : 0;
}

static ssize_t btrfs_root_attr_store(struct kobject *kobj,
				     struct attribute *attr,
				     const char *buf, size_t len)
{
	struct btrfs_root *root = container_of(kobj, struct btrfs_root,
						root_kobj);
	struct btrfs_root_attr *a = container_of(attr,
						 struct btrfs_root_attr,
						 attr);
	return a->store ? a->store(root, buf, len) : 0;
}

static void btrfs_super_release(struct kobject *kobj)
{
	struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info,
						super_kobj);
	complete(&fs->kobj_unregister);
}

static void btrfs_root_release(struct kobject *kobj)
{
	struct btrfs_root *root = container_of(kobj, struct btrfs_root,
						root_kobj);
	complete(&root->kobj_unregister);
}

static struct sysfs_ops btrfs_super_attr_ops = {
	.show	= btrfs_super_attr_show,
	.store	= btrfs_super_attr_store,
};

static struct sysfs_ops btrfs_root_attr_ops = {
	.show	= btrfs_root_attr_show,
	.store	= btrfs_root_attr_store,
};

static struct kobj_type btrfs_root_ktype = {
	.default_attrs	= btrfs_root_attrs,
	.sysfs_ops	= &btrfs_root_attr_ops,
	.release	= btrfs_root_release,
};

static struct kobj_type btrfs_super_ktype = {
	.default_attrs	= btrfs_super_attrs,
	.sysfs_ops	= &btrfs_super_attr_ops,
	.release	= btrfs_super_release,
};

/* /sys/fs/btrfs/ entry */
static struct kset *btrfs_kset;

int btrfs_sysfs_add_super(struct btrfs_fs_info *fs)
{
	int error;
	char *name;
	char c;
	int len = strlen(fs->sb->s_id) + 1;
	int i;

	name = kmalloc(len, GFP_NOFS);
	if (!name) {
		error = -ENOMEM;
		goto fail;
	}

	for (i = 0; i < len; i++) {
		c = fs->sb->s_id[i];
		if (c == '/' || c == '\\')
			c = '!';
		name[i] = c;
	}
	name[len] = '\0';

	fs->super_kobj.kset = btrfs_kset;
	error = kobject_init_and_add(&fs->super_kobj, &btrfs_super_ktype,
				     NULL, "%s", name);
	if (error)
		goto fail;

	kfree(name);
	return 0;

fail:
	kfree(name);
	printk(KERN_ERR "btrfs: sysfs creation for super failed\n");
	return error;
}

int btrfs_sysfs_add_root(struct btrfs_root *root)
{
	int error;

	error = kobject_init_and_add(&root->root_kobj, &btrfs_root_ktype,
				     &root->fs_info->super_kobj,
				     "%s", root->name);
	if (error)
		goto fail;

	return 0;

fail:
	printk(KERN_ERR "btrfs: sysfs creation for root failed\n");
	return error;
}

void btrfs_sysfs_del_root(struct btrfs_root *root)
{
	kobject_put(&root->root_kobj);
	wait_for_completion(&root->kobj_unregister);
}

void btrfs_sysfs_del_super(struct btrfs_fs_info *fs)
{
	kobject_put(&fs->super_kobj);
	wait_for_completion(&fs->kobj_unregister);
}

int btrfs_init_sysfs(void)
{
	btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
	if (!btrfs_kset)
		return -ENOMEM;
	return 0;
}

void btrfs_exit_sysfs(void)
{
	kset_unregister(btrfs_kset);
}

#else

int btrfs_sysfs_add_super(struct btrfs_fs_info *fs)
{
	return 0;
}

int btrfs_sysfs_add_root(struct btrfs_root *root)
{
	return 0;
}

void btrfs_sysfs_del_root(struct btrfs_root *root)
{
	return;
}

void btrfs_sysfs_del_super(struct btrfs_fs_info *fs)
{
	return;
}

int btrfs_init_sysfs(void)
{
	return 0;
}

void btrfs_exit_sysfs(void)
{
	return;
}
#endif
