16cbd5570SChris Mason /* 26cbd5570SChris Mason * Copyright (C) 2007 Oracle. All rights reserved. 36cbd5570SChris Mason * 46cbd5570SChris Mason * This program is free software; you can redistribute it and/or 56cbd5570SChris Mason * modify it under the terms of the GNU General Public 66cbd5570SChris Mason * License v2 as published by the Free Software Foundation. 76cbd5570SChris Mason * 86cbd5570SChris Mason * This program is distributed in the hope that it will be useful, 96cbd5570SChris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of 106cbd5570SChris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 116cbd5570SChris Mason * General Public License for more details. 126cbd5570SChris Mason * 136cbd5570SChris Mason * You should have received a copy of the GNU General Public 146cbd5570SChris Mason * License along with this program; if not, write to the 156cbd5570SChris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 166cbd5570SChris Mason * Boston, MA 021110-1307, USA. 176cbd5570SChris Mason */ 186cbd5570SChris Mason 1958176a96SJosef Bacik #include <linux/sched.h> 2058176a96SJosef Bacik #include <linux/slab.h> 2158176a96SJosef Bacik #include <linux/spinlock.h> 2258176a96SJosef Bacik #include <linux/completion.h> 2358176a96SJosef Bacik #include <linux/buffer_head.h> 2458176a96SJosef Bacik #include <linux/module.h> 2558176a96SJosef Bacik #include <linux/kobject.h> 2658176a96SJosef Bacik 27bae45de0SChris Mason #include "ctree.h" 28bae45de0SChris Mason #include "disk-io.h" 29bae45de0SChris Mason #include "transaction.h" 3058176a96SJosef Bacik 3158176a96SJosef Bacik static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf) 3258176a96SJosef Bacik { 3358176a96SJosef Bacik return snprintf(buf, PAGE_SIZE, "%llu\n", 345f39d397SChris Mason (unsigned long long)btrfs_root_used(&root->root_item)); 3558176a96SJosef Bacik } 3658176a96SJosef Bacik 3758176a96SJosef Bacik static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf) 3858176a96SJosef Bacik { 3958176a96SJosef Bacik return snprintf(buf, PAGE_SIZE, "%llu\n", 405f39d397SChris Mason (unsigned long long)btrfs_root_limit(&root->root_item)); 4158176a96SJosef Bacik } 4258176a96SJosef Bacik 4358176a96SJosef Bacik static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf) 4458176a96SJosef Bacik { 45db94535dSChris Mason 4658176a96SJosef Bacik return snprintf(buf, PAGE_SIZE, "%llu\n", 47db94535dSChris Mason (unsigned long long)btrfs_super_bytes_used(&fs->super_copy)); 4858176a96SJosef Bacik } 4958176a96SJosef Bacik 5058176a96SJosef Bacik static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf) 5158176a96SJosef Bacik { 5258176a96SJosef Bacik return snprintf(buf, PAGE_SIZE, "%llu\n", 53db94535dSChris Mason (unsigned long long)btrfs_super_total_bytes(&fs->super_copy)); 5458176a96SJosef Bacik } 5558176a96SJosef Bacik 5658176a96SJosef Bacik static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf) 5758176a96SJosef Bacik { 5858176a96SJosef Bacik return snprintf(buf, PAGE_SIZE, "%llu\n", 595f39d397SChris Mason (unsigned long long)btrfs_super_sectorsize(&fs->super_copy)); 6058176a96SJosef Bacik } 6158176a96SJosef Bacik 6258176a96SJosef Bacik /* this is for root attrs (subvols/snapshots) */ 6358176a96SJosef Bacik struct btrfs_root_attr { 6458176a96SJosef Bacik struct attribute attr; 6558176a96SJosef Bacik ssize_t (*show)(struct btrfs_root *, char *); 6658176a96SJosef Bacik ssize_t (*store)(struct btrfs_root *, const char *, size_t); 6758176a96SJosef Bacik }; 6858176a96SJosef Bacik 6958176a96SJosef Bacik #define ROOT_ATTR(name, mode, show, store) \ 7058176a96SJosef Bacik static struct btrfs_root_attr btrfs_root_attr_##name = __ATTR(name, mode, show, store) 7158176a96SJosef Bacik 7258176a96SJosef Bacik ROOT_ATTR(blocks_used, 0444, root_blocks_used_show, NULL); 7358176a96SJosef Bacik ROOT_ATTR(block_limit, 0644, root_block_limit_show, NULL); 7458176a96SJosef Bacik 7558176a96SJosef Bacik static struct attribute *btrfs_root_attrs[] = { 7658176a96SJosef Bacik &btrfs_root_attr_blocks_used.attr, 7758176a96SJosef Bacik &btrfs_root_attr_block_limit.attr, 7858176a96SJosef Bacik NULL, 7958176a96SJosef Bacik }; 8058176a96SJosef Bacik 8158176a96SJosef Bacik /* this is for super attrs (actual full fs) */ 8258176a96SJosef Bacik struct btrfs_super_attr { 8358176a96SJosef Bacik struct attribute attr; 8458176a96SJosef Bacik ssize_t (*show)(struct btrfs_fs_info *, char *); 8558176a96SJosef Bacik ssize_t (*store)(struct btrfs_fs_info *, const char *, size_t); 8658176a96SJosef Bacik }; 8758176a96SJosef Bacik 8858176a96SJosef Bacik #define SUPER_ATTR(name, mode, show, store) \ 8958176a96SJosef Bacik static struct btrfs_super_attr btrfs_super_attr_##name = __ATTR(name, mode, show, store) 9058176a96SJosef Bacik 9158176a96SJosef Bacik SUPER_ATTR(blocks_used, 0444, super_blocks_used_show, NULL); 9258176a96SJosef Bacik SUPER_ATTR(total_blocks, 0444, super_total_blocks_show, NULL); 9358176a96SJosef Bacik SUPER_ATTR(blocksize, 0444, super_blocksize_show, NULL); 9458176a96SJosef Bacik 9558176a96SJosef Bacik static struct attribute *btrfs_super_attrs[] = { 9658176a96SJosef Bacik &btrfs_super_attr_blocks_used.attr, 9758176a96SJosef Bacik &btrfs_super_attr_total_blocks.attr, 9858176a96SJosef Bacik &btrfs_super_attr_blocksize.attr, 9958176a96SJosef Bacik NULL, 10058176a96SJosef Bacik }; 10158176a96SJosef Bacik 10258176a96SJosef Bacik static ssize_t btrfs_super_attr_show(struct kobject *kobj, 10358176a96SJosef Bacik struct attribute *attr, char *buf) 10458176a96SJosef Bacik { 10558176a96SJosef Bacik struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info, 10658176a96SJosef Bacik super_kobj); 10758176a96SJosef Bacik struct btrfs_super_attr *a = container_of(attr, 10858176a96SJosef Bacik struct btrfs_super_attr, 10958176a96SJosef Bacik attr); 11058176a96SJosef Bacik 11158176a96SJosef Bacik return a->show ? a->show(fs, buf) : 0; 11258176a96SJosef Bacik } 11358176a96SJosef Bacik 11458176a96SJosef Bacik static ssize_t btrfs_super_attr_store(struct kobject *kobj, 11558176a96SJosef Bacik struct attribute *attr, 11658176a96SJosef Bacik const char *buf, size_t len) 11758176a96SJosef Bacik { 11858176a96SJosef Bacik struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info, 11958176a96SJosef Bacik super_kobj); 12058176a96SJosef Bacik struct btrfs_super_attr *a = container_of(attr, 12158176a96SJosef Bacik struct btrfs_super_attr, 12258176a96SJosef Bacik attr); 12358176a96SJosef Bacik 12458176a96SJosef Bacik return a->store ? a->store(fs, buf, len) : 0; 12558176a96SJosef Bacik } 12658176a96SJosef Bacik 12758176a96SJosef Bacik static ssize_t btrfs_root_attr_show(struct kobject *kobj, 12858176a96SJosef Bacik struct attribute *attr, char *buf) 12958176a96SJosef Bacik { 13058176a96SJosef Bacik struct btrfs_root *root = container_of(kobj, struct btrfs_root, 13158176a96SJosef Bacik root_kobj); 13258176a96SJosef Bacik struct btrfs_root_attr *a = container_of(attr, 13358176a96SJosef Bacik struct btrfs_root_attr, 13458176a96SJosef Bacik attr); 13558176a96SJosef Bacik 13658176a96SJosef Bacik return a->show ? a->show(root, buf) : 0; 13758176a96SJosef Bacik } 13858176a96SJosef Bacik 13958176a96SJosef Bacik static ssize_t btrfs_root_attr_store(struct kobject *kobj, 14058176a96SJosef Bacik struct attribute *attr, 14158176a96SJosef Bacik const char *buf, size_t len) 14258176a96SJosef Bacik { 14358176a96SJosef Bacik struct btrfs_root *root = container_of(kobj, struct btrfs_root, 14458176a96SJosef Bacik root_kobj); 14558176a96SJosef Bacik struct btrfs_root_attr *a = container_of(attr, 14658176a96SJosef Bacik struct btrfs_root_attr, 14758176a96SJosef Bacik attr); 14858176a96SJosef Bacik return a->store ? a->store(root, buf, len) : 0; 14958176a96SJosef Bacik } 15058176a96SJosef Bacik 15158176a96SJosef Bacik static void btrfs_super_release(struct kobject *kobj) 15258176a96SJosef Bacik { 15358176a96SJosef Bacik struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info, 15458176a96SJosef Bacik super_kobj); 15558176a96SJosef Bacik complete(&fs->kobj_unregister); 15658176a96SJosef Bacik } 15758176a96SJosef Bacik 15858176a96SJosef Bacik static void btrfs_root_release(struct kobject *kobj) 15958176a96SJosef Bacik { 16058176a96SJosef Bacik struct btrfs_root *root = container_of(kobj, struct btrfs_root, 16158176a96SJosef Bacik root_kobj); 16258176a96SJosef Bacik complete(&root->kobj_unregister); 16358176a96SJosef Bacik } 16458176a96SJosef Bacik 16558176a96SJosef Bacik static struct sysfs_ops btrfs_super_attr_ops = { 16658176a96SJosef Bacik .show = btrfs_super_attr_show, 16758176a96SJosef Bacik .store = btrfs_super_attr_store, 16858176a96SJosef Bacik }; 16958176a96SJosef Bacik 17058176a96SJosef Bacik static struct sysfs_ops btrfs_root_attr_ops = { 17158176a96SJosef Bacik .show = btrfs_root_attr_show, 17258176a96SJosef Bacik .store = btrfs_root_attr_store, 17358176a96SJosef Bacik }; 17458176a96SJosef Bacik 17558176a96SJosef Bacik static struct kobj_type btrfs_root_ktype = { 17658176a96SJosef Bacik .default_attrs = btrfs_root_attrs, 17758176a96SJosef Bacik .sysfs_ops = &btrfs_root_attr_ops, 17858176a96SJosef Bacik .release = btrfs_root_release, 17958176a96SJosef Bacik }; 18058176a96SJosef Bacik 18158176a96SJosef Bacik static struct kobj_type btrfs_super_ktype = { 18258176a96SJosef Bacik .default_attrs = btrfs_super_attrs, 18358176a96SJosef Bacik .sysfs_ops = &btrfs_super_attr_ops, 18458176a96SJosef Bacik .release = btrfs_super_release, 18558176a96SJosef Bacik }; 18658176a96SJosef Bacik 187e3fe4e71SGreg KH /* /sys/fs/btrfs/ entry */ 188e3fe4e71SGreg KH static struct kset *btrfs_kset; 18958176a96SJosef Bacik 19058176a96SJosef Bacik int btrfs_sysfs_add_super(struct btrfs_fs_info *fs) 19158176a96SJosef Bacik { 19258176a96SJosef Bacik int error; 1936da6abaeSChris Mason char *name; 1946da6abaeSChris Mason char c; 1956da6abaeSChris Mason int len = strlen(fs->sb->s_id) + 1; 1966da6abaeSChris Mason int i; 1976da6abaeSChris Mason 1986da6abaeSChris Mason name = kmalloc(len, GFP_NOFS); 1996da6abaeSChris Mason if (!name) { 2006da6abaeSChris Mason error = -ENOMEM; 2016da6abaeSChris Mason goto fail; 2026da6abaeSChris Mason } 2036da6abaeSChris Mason 2046da6abaeSChris Mason for (i = 0; i < len; i++) { 2056da6abaeSChris Mason c = fs->sb->s_id[i]; 2066da6abaeSChris Mason if (c == '/' || c == '\\') 2076da6abaeSChris Mason c = '!'; 2086da6abaeSChris Mason name[i] = c; 2096da6abaeSChris Mason } 2106da6abaeSChris Mason name[len] = '\0'; 21158176a96SJosef Bacik 212e3fe4e71SGreg KH fs->super_kobj.kset = btrfs_kset; 213e3fe4e71SGreg KH error = kobject_init_and_add(&fs->super_kobj, &btrfs_super_ktype, 214e3fe4e71SGreg KH NULL, "%s", name); 21558176a96SJosef Bacik if (error) 21658176a96SJosef Bacik goto fail; 21758176a96SJosef Bacik 2186da6abaeSChris Mason kfree(name); 21958176a96SJosef Bacik return 0; 22058176a96SJosef Bacik 22158176a96SJosef Bacik fail: 2226da6abaeSChris Mason kfree(name); 22358176a96SJosef Bacik printk(KERN_ERR "btrfs: sysfs creation for super failed\n"); 22458176a96SJosef Bacik return error; 22558176a96SJosef Bacik } 22658176a96SJosef Bacik 22758176a96SJosef Bacik int btrfs_sysfs_add_root(struct btrfs_root *root) 22858176a96SJosef Bacik { 22958176a96SJosef Bacik int error; 23058176a96SJosef Bacik 231e3fe4e71SGreg KH error = kobject_init_and_add(&root->root_kobj, &btrfs_root_ktype, 232e3fe4e71SGreg KH &root->fs_info->super_kobj, 233e3fe4e71SGreg KH "%s", root->name); 23458176a96SJosef Bacik if (error) 23558176a96SJosef Bacik goto fail; 23658176a96SJosef Bacik 23758176a96SJosef Bacik return 0; 23858176a96SJosef Bacik 23958176a96SJosef Bacik fail: 24058176a96SJosef Bacik printk(KERN_ERR "btrfs: sysfs creation for root failed\n"); 24158176a96SJosef Bacik return error; 24258176a96SJosef Bacik } 24358176a96SJosef Bacik 24458176a96SJosef Bacik void btrfs_sysfs_del_root(struct btrfs_root *root) 24558176a96SJosef Bacik { 246e3fe4e71SGreg KH kobject_put(&root->root_kobj); 24758176a96SJosef Bacik wait_for_completion(&root->kobj_unregister); 24858176a96SJosef Bacik } 24958176a96SJosef Bacik 25058176a96SJosef Bacik void btrfs_sysfs_del_super(struct btrfs_fs_info *fs) 25158176a96SJosef Bacik { 252e3fe4e71SGreg KH kobject_put(&fs->super_kobj); 25358176a96SJosef Bacik wait_for_completion(&fs->kobj_unregister); 25458176a96SJosef Bacik } 25558176a96SJosef Bacik 25658176a96SJosef Bacik int btrfs_init_sysfs() 25758176a96SJosef Bacik { 258e3fe4e71SGreg KH btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj); 259e3fe4e71SGreg KH if (!btrfs_kset) 260e3fe4e71SGreg KH return -ENOMEM; 261e3fe4e71SGreg KH return 0; 26258176a96SJosef Bacik } 26358176a96SJosef Bacik 26458176a96SJosef Bacik void btrfs_exit_sysfs() 26558176a96SJosef Bacik { 266e3fe4e71SGreg KH kset_unregister(btrfs_kset); 26758176a96SJosef Bacik } 268