Btrfs: Do delalloc accounting via hooks in the extent_state code
[linux-2.6-block.git] / fs / btrfs / ctree.h
index fd58dd846e61ec66260e274231d1f831f8dd5975..127c86f795d0423f52f621fade50f48c72546afd 100644 (file)
  * Boston, MA 021110-1307, USA.
  */
 
-#ifndef __BTRFS__
-#define __BTRFS__
+#ifndef __BTRFS_CTREE__
+#define __BTRFS_CTREE__
 
+#include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/fs.h>
@@ -26,6 +27,7 @@
 #include <linux/completion.h>
 #include <asm/kmap_types.h>
 #include "bit-radix.h"
+#include "extent_io.h"
 #include "extent_map.h"
 
 struct btrfs_trans_handle;
@@ -35,13 +37,14 @@ extern struct kmem_cache *btrfs_transaction_cachep;
 extern struct kmem_cache *btrfs_bit_radix_cachep;
 extern struct kmem_cache *btrfs_path_cachep;
 
-#define BTRFS_MAGIC "_B2RfS_M"
+#define BTRFS_MAGIC "_B3RfS_M"
 
+#define BTRFS_MAX_LEVEL 8
 #define BTRFS_ROOT_TREE_OBJECTID 1ULL
 #define BTRFS_EXTENT_TREE_OBJECTID 2ULL
 #define BTRFS_FS_TREE_OBJECTID 3ULL
 #define BTRFS_ROOT_TREE_DIR_OBJECTID 4ULL
-#define BTRFS_FIRST_FREE_OBJECTID 5ULL
+#define BTRFS_FIRST_FREE_OBJECTID 256ULL
 
 /*
  * we can actually store much bigger names, but lets not confuse the rest
@@ -53,7 +56,7 @@ extern struct kmem_cache *btrfs_path_cachep;
 #define BTRFS_CSUM_SIZE 32
 /* four bytes for CRC32 */
 #define BTRFS_CRC32_SIZE 4
-#define BTRFS_EMPTY_DIR_SIZE 6
+#define BTRFS_EMPTY_DIR_SIZE 0
 
 #define BTRFS_FT_UNKNOWN       0
 #define BTRFS_FT_REG_FILE      1
@@ -107,7 +110,6 @@ struct btrfs_header {
        u8 level;
 } __attribute__ ((__packed__));
 
-#define BTRFS_MAX_LEVEL 8
 #define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \
                                sizeof(struct btrfs_header)) / \
                                sizeof(struct btrfs_key_ptr))
@@ -206,6 +208,11 @@ struct btrfs_extent_ref {
        __le64 offset;
 } __attribute__ ((__packed__));
 
+struct btrfs_inode_ref {
+       __le16 name_len;
+       /* name goes here */
+} __attribute__ ((__packed__));
+
 struct btrfs_inode_timespec {
        __le64 sec;
        __le32 nsec;
@@ -308,14 +315,17 @@ struct btrfs_fs_info {
        struct btrfs_root *tree_root;
        struct radix_tree_root fs_roots_radix;
 
-       struct extent_map_tree free_space_cache;
-       struct extent_map_tree block_group_cache;
-       struct extent_map_tree pinned_extents;
-       struct extent_map_tree pending_del;
-       struct extent_map_tree extent_ins;
+       struct extent_io_tree free_space_cache;
+       struct extent_io_tree block_group_cache;
+       struct extent_io_tree pinned_extents;
+       struct extent_io_tree pending_del;
+       struct extent_io_tree extent_ins;
 
        u64 generation;
        u64 last_trans_committed;
+       unsigned long mount_opt;
+       u64 max_extent;
+       u64 alloc_start;
        struct btrfs_transaction *running_transaction;
        struct btrfs_super_block super_copy;
        struct extent_buffer *sb_buffer;
@@ -327,13 +337,22 @@ struct btrfs_fs_info {
        struct list_head trans_list;
        struct list_head hashers;
        struct list_head dead_roots;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
+       struct work_struct trans_work;
+#else
        struct delayed_work trans_work;
+#endif
        struct kobject super_kobj;
        struct completion kobj_unregister;
        int do_barriers;
        int closing;
+       unsigned long throttles;
 
        u64 total_pinned;
+       spinlock_t delalloc_lock;
+       spinlock_t new_trans_lock;
+       u64 delalloc_bytes;
+       u64 last_alloc;
 };
 /*
  * in ram representation of the tree.  extent_root is used for all allocations
@@ -348,7 +367,6 @@ struct btrfs_root {
        struct inode *inode;
        struct kobject root_kobj;
        struct completion kobj_unregister;
-       struct rw_semaphore snap_sem;
        u64 objectid;
        u64 last_trans;
 
@@ -371,6 +389,7 @@ struct btrfs_root {
        int defrag_running;
        int defrag_level;
        char *name;
+       int in_sysfs;
 };
 
 /*
@@ -379,7 +398,8 @@ struct btrfs_root {
  * the FS
  */
 #define BTRFS_INODE_ITEM_KEY           1
-#define BTRFS_XATTR_ITEM_KEY           2
+#define BTRFS_INODE_REF_KEY            2
+#define BTRFS_XATTR_ITEM_KEY           8
 /* reserve 2-15 close to the inode for later flexibility */
 
 /*
@@ -423,6 +443,27 @@ struct btrfs_root {
  */
 #define BTRFS_STRING_ITEM_KEY  253
 
+#define BTRFS_MOUNT_NODATASUM          (1 << 0)
+#define BTRFS_MOUNT_NODATACOW          (1 << 1)
+#define BTRFS_MOUNT_NOBARRIER          (1 << 2)
+#define BTRFS_MOUNT_SSD                        (1 << 3)
+
+#define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
+#define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
+#define btrfs_test_opt(root, opt)      ((root)->fs_info->mount_opt & \
+                                        BTRFS_MOUNT_##opt)
+/*
+ * Inode flags
+ */
+#define BTRFS_INODE_NODATASUM          (1 << 0)
+#define BTRFS_INODE_NODATACOW          (1 << 1)
+#define BTRFS_INODE_READONLY           (1 << 2)
+#define btrfs_clear_flag(inode, flag)  (BTRFS_I(inode)->flags &= \
+                                        ~BTRFS_INODE_##flag)
+#define btrfs_set_flag(inode, flag)    (BTRFS_I(inode)->flags |= \
+                                        BTRFS_INODE_##flag)
+#define btrfs_test_flag(inode, flag)   (BTRFS_I(inode)->flags & \
+                                        BTRFS_INODE_##flag)
 /* some macros to generate set/get funcs for the struct fields.  This
  * assumes there is a lefoo_to_cpu for every type, so lets make a simple
  * one for u8:
@@ -485,6 +526,11 @@ BTRFS_SETGET_STACK_FUNCS(block_group_used, struct btrfs_block_group_item,
                         used, 64);
 BTRFS_SETGET_FUNCS(disk_block_group_used, struct btrfs_block_group_item,
                         used, 64);
+BTRFS_SETGET_FUNCS(disk_block_group_flags, struct btrfs_block_group_item,
+                  flags, 8);
+
+/* struct btrfs_inode_ref */
+BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
 
 /* struct btrfs_inode_item */
 BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64);
@@ -544,11 +590,12 @@ BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64);
 BTRFS_SETGET_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64);
 BTRFS_SETGET_FUNCS(ref_offset, struct btrfs_extent_ref, offset, 64);
 
-BTRFS_SETGET_STACK_FUNCS(ref_root, struct btrfs_extent_ref, root, 64);
-BTRFS_SETGET_STACK_FUNCS(ref_generation, struct btrfs_extent_ref,
+BTRFS_SETGET_STACK_FUNCS(stack_ref_root, struct btrfs_extent_ref, root, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_ref_generation, struct btrfs_extent_ref,
                         generation, 64);
-BTRFS_SETGET_STACK_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64);
-BTRFS_SETGET_STACK_FUNCS(ref_offset, struct btrfs_extent_ref, offset, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_ref_objectid, struct btrfs_extent_ref,
+                        objectid, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_ref_offset, struct btrfs_extent_ref, offset, 64);
 
 BTRFS_SETGET_STACK_FUNCS(stack_extent_refs, struct btrfs_extent_item,
                         refs, 32);
@@ -896,16 +943,21 @@ static inline u32 btrfs_level_size(struct btrfs_root *root, int level) {
        ((unsigned long)(btrfs_leaf_data(leaf) + \
        btrfs_item_offset_nr(leaf, slot)))
 
-/* mount option defines and helpers */
-#define BTRFS_MOUNT_SUBVOL             0x000001
-#define btrfs_clear_opt(o, opt)                o &= ~BTRFS_MOUNT_##opt
-#define btrfs_set_opt(o, opt)          o |= BTRFS_MOUNT_##opt
-#define btrfs_test_opt(sb, opt)                (BTRFS_SB(sb)->s_mount_opt & \
-                                        BTRFS_MOUNT_##opt)
+static inline struct dentry *fdentry(struct file *file) {
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
+       return file->f_dentry;
+#else
+       return file->f_path.dentry;
+#endif
+}
+
 /* extent-tree.c */
+u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
+                                 struct btrfs_path *count_path,
+                                 u64 first_extent);
 int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
                         struct btrfs_root *root);
-int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy);
+int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy);
 struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
                                                         btrfs_fs_info *info,
                                                         u64 bytenr);
@@ -914,24 +966,48 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
                                                 *hint, u64 search_start,
                                                 int data, int owner);
 int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
-                      struct btrfs_root *root);
+                      struct btrfs_root *root, u64 owner_objectid);
 struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
                                            struct btrfs_root *root, u32 size,
+                                           u64 root_objectid,
                                            u64 hint, u64 empty_size);
+struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
+                                            struct btrfs_root *root,
+                                            u32 blocksize,
+                                            u64 root_objectid,
+                                            u64 ref_generation,
+                                            u64 first_objectid,
+                                            int level,
+                                            u64 hint,
+                                            u64 empty_size);
+int btrfs_grow_extent_tree(struct btrfs_trans_handle *trans,
+                          struct btrfs_root *root, u64 new_size);
+int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size);
+int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans,
+                                struct btrfs_root *root,
+                                struct btrfs_path *path, u64 bytenr,
+                                u64 root_objectid, u64 ref_generation,
+                                u64 owner, u64 owner_offset);
 int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
-                      struct btrfs_root *root, u64 owner,
-                      u64 num_bytes, u64 empty_size, u64 search_start,
+                      struct btrfs_root *root,
+                      u64 num_bytes, u64 root_objectid, u64 ref_generation,
+                      u64 owner, u64 owner_offset,
+                      u64 empty_size, u64 hint_byte,
                       u64 search_end, struct btrfs_key *ins, int data);
 int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                  struct extent_buffer *buf);
 int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
-                     *root, u64 bytenr, u64 num_bytes, int pin);
+                     *root, u64 bytenr, u64 num_bytes,
+                     u64 root_objectid, u64 ref_generation,
+                     u64 owner_objectid, u64 owner_offset, int pin);
 int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root,
-                              struct extent_map_tree *unpin);
+                              struct extent_io_tree *unpin);
 int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root,
-                               u64 bytenr, u64 num_bytes);
+                               u64 bytenr, u64 num_bytes,
+                               u64 root_objectid, u64 ref_generation,
+                               u64 owner, u64 owner_offset);
 int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                                    struct btrfs_root *root);
 int btrfs_free_block_groups(struct btrfs_fs_info *info);
@@ -941,6 +1017,10 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
                    struct btrfs_root *root, struct extent_buffer *buf,
                    struct extent_buffer *parent, int parent_slot,
                    struct extent_buffer **cow_ret);
+int btrfs_copy_root(struct btrfs_trans_handle *trans,
+                     struct btrfs_root *root,
+                     struct extent_buffer *buf,
+                     struct extent_buffer **cow_ret, u64 new_root_objectid);
 int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
                      *root, struct btrfs_path *path, u32 data_size);
 int btrfs_truncate_item(struct btrfs_trans_handle *trans,
@@ -958,14 +1038,34 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p);
 struct btrfs_path *btrfs_alloc_path(void);
 void btrfs_free_path(struct btrfs_path *p);
 void btrfs_init_path(struct btrfs_path *p);
-int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
-                  struct btrfs_path *path);
+int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_path *path, int slot, int nr);
+
+static inline int btrfs_del_item(struct btrfs_trans_handle *trans,
+                                struct btrfs_root *root,
+                                struct btrfs_path *path)
+{
+       return btrfs_del_items(trans, root, path, path->slots[0], 1);
+}
+
 int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
                      *root, struct btrfs_key *key, void *data, u32 data_size);
-int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
-                           *root, struct btrfs_path *path, struct btrfs_key
-                           *cpu_key, u32 data_size);
+int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
+                            struct btrfs_root *root,
+                            struct btrfs_path *path,
+                            struct btrfs_key *cpu_key, u32 *data_size, int nr);
+
+static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
+                                         struct btrfs_root *root,
+                                         struct btrfs_path *path,
+                                         struct btrfs_key *key,
+                                         u32 data_size)
+{
+       return btrfs_insert_empty_items(trans, root, path, key, &data_size, 1);
+}
+
 int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
+int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
 int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
 int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
                        *root);
@@ -1020,6 +1120,14 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
 int btrfs_find_highest_inode(struct btrfs_root *fs_root, u64 *objectid);
 
 /* inode-item.c */
+int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
+                          struct btrfs_root *root,
+                          const char *name, int name_len,
+                          u64 inode_objectid, u64 ref_objectid);
+int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
+                          struct btrfs_root *root,
+                          const char *name, int name_len,
+                          u64 inode_objectid, u64 ref_objectid);
 int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root,
                             struct btrfs_path *path, u64 objectid);
@@ -1051,9 +1159,15 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root, struct btrfs_path *path,
                        u64 isize);
 /* inode.c */
+unsigned long btrfs_force_ra(struct address_space *mapping,
+                             struct file_ra_state *ra, struct file *file,
+                             pgoff_t offset, pgoff_t last_index);
+int btrfs_check_free_space(struct btrfs_root *root, u64 num_required,
+                          int for_del);
 int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page);
 int btrfs_readpage(struct file *file, struct page *page);
 void btrfs_delete_inode(struct inode *inode);
+void btrfs_put_inode(struct inode *inode);
 void btrfs_read_locked_inode(struct inode *inode);
 int btrfs_write_inode(struct inode *inode, int wait);
 void btrfs_dirty_inode(struct inode *inode);
@@ -1064,6 +1178,8 @@ void btrfs_destroy_cachep(void);
 long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid,
                                struct btrfs_root *root);
+struct inode *btrfs_ilookup(struct super_block *s, u64 objectid,
+                           u64 root_objectid);
 int btrfs_commit_write(struct file *file, struct page *page,
                       unsigned from, unsigned to);
 struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
@@ -1074,6 +1190,7 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans,
                              struct inode *inode);
 /* file.c */
 int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end);
+int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
 extern struct file_operations btrfs_file_operations;
 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
                       struct btrfs_root *root, struct inode *inode,
@@ -1094,4 +1211,6 @@ void btrfs_sysfs_del_super(struct btrfs_fs_info *root);
 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 int btrfs_delete_xattrs(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root, struct inode *inode);
+/* super.c */
+u64 btrfs_parse_size(char *str);
 #endif