12e635a27SChris Mason #include <linux/module.h> 2e20d96d6SChris Mason #include <linux/buffer_head.h> 32e635a27SChris Mason #include <linux/fs.h> 42e635a27SChris Mason #include <linux/pagemap.h> 52e635a27SChris Mason #include <linux/highmem.h> 62e635a27SChris Mason #include <linux/time.h> 72e635a27SChris Mason #include <linux/init.h> 82e635a27SChris Mason #include <linux/string.h> 92e635a27SChris Mason #include <linux/smp_lock.h> 102e635a27SChris Mason #include <linux/backing-dev.h> 11dee26a9fSChris Mason #include <linux/mpage.h> 1275dfe396SChris Mason #include <linux/swap.h> 1375dfe396SChris Mason #include <linux/writeback.h> 148fd17795SChris Mason #include <linux/statfs.h> 1508607c1bSChris Mason #include <linux/compat.h> 162e635a27SChris Mason #include "ctree.h" 17e20d96d6SChris Mason #include "disk-io.h" 18d5719762SChris Mason #include "transaction.h" 192c90e5d6SChris Mason #include "btrfs_inode.h" 20c5739bbaSChris Mason #include "ioctl.h" 213a686375SChris Mason #include "print-tree.h" 222e635a27SChris Mason 232e635a27SChris Mason #define BTRFS_SUPER_MAGIC 0x9123682E 24e20d96d6SChris Mason 25e20d96d6SChris Mason static struct super_operations btrfs_super_ops; 26e20d96d6SChris Mason 27e20d96d6SChris Mason static void btrfs_put_super (struct super_block * sb) 28e20d96d6SChris Mason { 29e20d96d6SChris Mason struct btrfs_root *root = btrfs_sb(sb); 30e20d96d6SChris Mason int ret; 31e20d96d6SChris Mason 32e20d96d6SChris Mason ret = close_ctree(root); 33e20d96d6SChris Mason if (ret) { 34e20d96d6SChris Mason printk("close ctree returns %d\n", ret); 35e20d96d6SChris Mason } 36e20d96d6SChris Mason sb->s_fs_info = NULL; 37e20d96d6SChris Mason } 382e635a27SChris Mason 392e635a27SChris Mason static int btrfs_fill_super(struct super_block * sb, void * data, int silent) 402e635a27SChris Mason { 412e635a27SChris Mason struct inode * inode; 42e20d96d6SChris Mason struct dentry * root_dentry; 43e20d96d6SChris Mason struct btrfs_super_block *disk_super; 440f7d52f4SChris Mason struct btrfs_root *tree_root; 45d6e4a428SChris Mason struct btrfs_inode *bi; 46*39279cc3SChris Mason int err; 472e635a27SChris Mason 482e635a27SChris Mason sb->s_maxbytes = MAX_LFS_FILESIZE; 492e635a27SChris Mason sb->s_magic = BTRFS_SUPER_MAGIC; 50e20d96d6SChris Mason sb->s_op = &btrfs_super_ops; 512e635a27SChris Mason sb->s_time_gran = 1; 52e20d96d6SChris Mason 530f7d52f4SChris Mason tree_root = open_ctree(sb); 54d98237b3SChris Mason 55*39279cc3SChris Mason if (!tree_root || IS_ERR(tree_root)) { 56e20d96d6SChris Mason printk("btrfs: open_ctree failed\n"); 57e20d96d6SChris Mason return -EIO; 58e20d96d6SChris Mason } 590f7d52f4SChris Mason sb->s_fs_info = tree_root; 600f7d52f4SChris Mason disk_super = tree_root->fs_info->disk_super; 61c5739bbaSChris Mason inode = btrfs_iget_locked(sb, btrfs_super_root_dir(disk_super), 62c5739bbaSChris Mason tree_root); 63d6e4a428SChris Mason bi = BTRFS_I(inode); 64d6e4a428SChris Mason bi->location.objectid = inode->i_ino; 65d6e4a428SChris Mason bi->location.offset = 0; 66d6e4a428SChris Mason bi->location.flags = 0; 670f7d52f4SChris Mason bi->root = tree_root; 68d6e4a428SChris Mason btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY); 69d6e4a428SChris Mason 70*39279cc3SChris Mason if (!inode) { 71*39279cc3SChris Mason err = -ENOMEM; 72*39279cc3SChris Mason goto fail_close; 73*39279cc3SChris Mason } 74e20d96d6SChris Mason if (inode->i_state & I_NEW) { 75e20d96d6SChris Mason btrfs_read_locked_inode(inode); 76e20d96d6SChris Mason unlock_new_inode(inode); 77e20d96d6SChris Mason } 782e635a27SChris Mason 79e20d96d6SChris Mason root_dentry = d_alloc_root(inode); 80e20d96d6SChris Mason if (!root_dentry) { 812e635a27SChris Mason iput(inode); 82*39279cc3SChris Mason err = -ENOMEM; 83*39279cc3SChris Mason goto fail_close; 842e635a27SChris Mason } 85e20d96d6SChris Mason sb->s_root = root_dentry; 8608607c1bSChris Mason btrfs_transaction_queue_work(tree_root, HZ * 30); 872e635a27SChris Mason return 0; 882e635a27SChris Mason 89*39279cc3SChris Mason fail_close: 90*39279cc3SChris Mason close_ctree(tree_root); 91d5719762SChris Mason return err; 92d5719762SChris Mason } 93d5719762SChris Mason 94d5719762SChris Mason static int btrfs_sync_fs(struct super_block *sb, int wait) 95d5719762SChris Mason { 96d5719762SChris Mason struct btrfs_trans_handle *trans; 97d5719762SChris Mason struct btrfs_root *root; 98d5719762SChris Mason int ret; 99d98237b3SChris Mason root = btrfs_sb(sb); 100df2ce34cSChris Mason 101d5719762SChris Mason sb->s_dirt = 0; 102d561c025SChris Mason if (!wait) { 1037cfcc17eSChris Mason filemap_flush(root->fs_info->btree_inode->i_mapping); 104df2ce34cSChris Mason return 0; 105d561c025SChris Mason } 106d561c025SChris Mason mutex_lock(&root->fs_info->fs_mutex); 107d5719762SChris Mason trans = btrfs_start_transaction(root, 1); 108d5719762SChris Mason ret = btrfs_commit_transaction(trans, root); 109d5719762SChris Mason sb->s_dirt = 0; 110d5719762SChris Mason BUG_ON(ret); 111d561c025SChris Mason mutex_unlock(&root->fs_info->fs_mutex); 112d5719762SChris Mason return 0; 113d5719762SChris Mason } 114d5719762SChris Mason 115d561c025SChris Mason static void btrfs_write_super(struct super_block *sb) 116d561c025SChris Mason { 11708607c1bSChris Mason sb->s_dirt = 0; 118d561c025SChris Mason } 119d561c025SChris Mason 1202e635a27SChris Mason static int btrfs_get_sb(struct file_system_type *fs_type, 1212e635a27SChris Mason int flags, const char *dev_name, void *data, struct vfsmount *mnt) 1222e635a27SChris Mason { 1232e635a27SChris Mason return get_sb_bdev(fs_type, flags, dev_name, data, 1242e635a27SChris Mason btrfs_fill_super, mnt); 1252e635a27SChris Mason } 1262e635a27SChris Mason 1278fd17795SChris Mason static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) 1288fd17795SChris Mason { 1298fd17795SChris Mason struct btrfs_root *root = btrfs_sb(dentry->d_sb); 1308fd17795SChris Mason struct btrfs_super_block *disk_super = root->fs_info->disk_super; 1318fd17795SChris Mason 1328fd17795SChris Mason buf->f_namelen = BTRFS_NAME_LEN; 1338fd17795SChris Mason buf->f_blocks = btrfs_super_total_blocks(disk_super); 1348fd17795SChris Mason buf->f_bfree = buf->f_blocks - btrfs_super_blocks_used(disk_super); 1358fd17795SChris Mason buf->f_bavail = buf->f_bfree; 1368fd17795SChris Mason buf->f_bsize = dentry->d_sb->s_blocksize; 1378fd17795SChris Mason buf->f_type = BTRFS_SUPER_MAGIC; 1388fd17795SChris Mason return 0; 1398fd17795SChris Mason } 140b5133862SChris Mason 1412e635a27SChris Mason static struct file_system_type btrfs_fs_type = { 1422e635a27SChris Mason .owner = THIS_MODULE, 1432e635a27SChris Mason .name = "btrfs", 1442e635a27SChris Mason .get_sb = btrfs_get_sb, 1452e635a27SChris Mason .kill_sb = kill_block_super, 1462e635a27SChris Mason .fs_flags = FS_REQUIRES_DEV, 1472e635a27SChris Mason }; 1482e635a27SChris Mason 149e20d96d6SChris Mason static struct super_operations btrfs_super_ops = { 150134e9731SChris Mason .delete_inode = btrfs_delete_inode, 151e20d96d6SChris Mason .put_super = btrfs_put_super, 152e20d96d6SChris Mason .read_inode = btrfs_read_locked_inode, 153d5719762SChris Mason .write_super = btrfs_write_super, 154d5719762SChris Mason .sync_fs = btrfs_sync_fs, 1554730a4bcSChris Mason .write_inode = btrfs_write_inode, 156b5133862SChris Mason .dirty_inode = btrfs_dirty_inode, 1572c90e5d6SChris Mason .alloc_inode = btrfs_alloc_inode, 1582c90e5d6SChris Mason .destroy_inode = btrfs_destroy_inode, 1598fd17795SChris Mason .statfs = btrfs_statfs, 160e20d96d6SChris Mason }; 161e20d96d6SChris Mason 1622e635a27SChris Mason static int __init init_btrfs_fs(void) 1632e635a27SChris Mason { 1642c90e5d6SChris Mason int err; 16508607c1bSChris Mason btrfs_init_transaction_sys(); 166*39279cc3SChris Mason err = btrfs_init_cachep(); 1672c90e5d6SChris Mason if (err) 1682c90e5d6SChris Mason return err; 1692e635a27SChris Mason return register_filesystem(&btrfs_fs_type); 1702e635a27SChris Mason } 1712e635a27SChris Mason 1722e635a27SChris Mason static void __exit exit_btrfs_fs(void) 1732e635a27SChris Mason { 17408607c1bSChris Mason btrfs_exit_transaction_sys(); 175*39279cc3SChris Mason btrfs_destroy_cachep(); 1762e635a27SChris Mason unregister_filesystem(&btrfs_fs_type); 1772e635a27SChris Mason } 1782e635a27SChris Mason 1792e635a27SChris Mason module_init(init_btrfs_fs) 1802e635a27SChris Mason module_exit(exit_btrfs_fs) 1812e635a27SChris Mason 1822e635a27SChris Mason MODULE_LICENSE("GPL"); 183