/*
 * 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"

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);
}

