diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+v0.1.2.0
+
+	* Expose System.Linux.Btrfs.Time.
+	* Add example program that prints the file creation timestamp.
+
 v0.1.1.1
 
 	* Support getting/setting the id of the default subvolume.
diff --git a/Data/Word/Endian.hs b/Data/Word/Endian.hs
--- a/Data/Word/Endian.hs
+++ b/Data/Word/Endian.hs
@@ -3,7 +3,11 @@
 module Data.Word.Endian where
 
 import Data.Word (Word16, Word32, Word64)
+#if MIN_VERSION_base(4,7,0)
+import Data.Word (byteSwap16, byteSwap32, byteSwap64)
+#else
 import Data.Bits (rotateL, unsafeShiftL, unsafeShiftR, (.&.), (.|.))
+#endif
 import Foreign.Ptr (castPtr)
 import Foreign.Storable (Storable(..))
 
@@ -41,16 +45,25 @@
 #endif
 
 invert16 :: Word16 -> Word16
+invert32 :: Word32 -> Word32
+invert64 :: Word64 -> Word64
+
+#if MIN_VERSION_base(4,7,0)
+invert16 = byteSwap16
+{-# INLINE invert16 #-}
+invert32 = byteSwap32
+{-# INLINE invert32 #-}
+invert64 = byteSwap64
+{-# INLINE invert64 #-}
+#else
 invert16 x = x `rotateL` 8
 
-invert32 :: Word32 -> Word32
 invert32 x =
     ((x               ) `unsafeShiftR` 24) .|.
     ((x .&. 0x00ff0000) `unsafeShiftR`  8) .|.
     ((x .&. 0x0000ff00) `unsafeShiftL`  8) .|.
     ((x               ) `unsafeShiftL` 24)
 
-invert64 :: Word64 -> Word64
 invert64 x =
     ((x                       ) `unsafeShiftR` 56) .|.
     ((x .&. 0x00ff000000000000) `unsafeShiftR` 40) .|.
@@ -60,3 +73,4 @@
     ((x .&. 0x0000000000ff0000) `unsafeShiftL` 24) .|.
     ((x .&. 0x000000000000ff00) `unsafeShiftL` 40) .|.
     ((x                       ) `unsafeShiftL` 56)
+#endif
diff --git a/System/Linux/Btrfs.hsc b/System/Linux/Btrfs.hsc
--- a/System/Linux/Btrfs.hsc
+++ b/System/Linux/Btrfs.hsc
@@ -84,20 +84,20 @@
 import Data.IORef
 import Data.Time.Clock (UTCTime)
 import Data.Monoid
-import System.Linux.Btrfs.FilePathLike
+import Prelude
 
 import Foreign
 import Foreign.C.Types
 import Foreign.C.String (CStringLen)
 import Foreign.C.Error
 
+import System.Linux.Btrfs.FilePathLike
 import Data.Word.Endian
 import System.Linux.Btrfs.Time
 import System.Linux.Btrfs.UUID
 
 #include <btrfs/ioctl.h>
 #include <btrfs/ctree.h>
-#include <missing.h>
 
 #include <linux/fs.h>
 
diff --git a/System/Linux/Btrfs/ByteString.hsc b/System/Linux/Btrfs/ByteString.hsc
--- a/System/Linux/Btrfs/ByteString.hsc
+++ b/System/Linux/Btrfs/ByteString.hsc
@@ -84,20 +84,20 @@
 import Data.IORef
 import Data.Time.Clock (UTCTime)
 import Data.Monoid
-import System.Linux.Btrfs.FilePathLike
+import Prelude
 
 import Foreign
 import Foreign.C.Types
 import Foreign.C.String (CStringLen)
 import Foreign.C.Error
 
+import System.Linux.Btrfs.FilePathLike
 import Data.Word.Endian
 import System.Linux.Btrfs.Time
 import System.Linux.Btrfs.UUID
 
 #include <btrfs/ioctl.h>
 #include <btrfs/ctree.h>
-#include <missing.h>
 
 #include <linux/fs.h>
 
diff --git a/btrfs.cabal b/btrfs.cabal
--- a/btrfs.cabal
+++ b/btrfs.cabal
@@ -1,13 +1,13 @@
 name:                btrfs
-version:             0.1.1.1
+version:             0.1.2.0
 synopsis:            Bindings to the btrfs API
 description:
-  This package provides low-level bindings to the btrfs API (i.e. the
+  This package provides bindings to the low-level btrfs API (i.e. the
   @BTRFS_IOC_@* @ioctl@s). Currently, only a subset of the API is
-  supported, including functions needed to work with subvolumes/snapshots
+  supported, including all functions needed to work with subvolumes/snapshots
   as well as file cloning.
   .
-  In order to build this package, @linux-headers@ need to be installed.
+  In order to build this package, @linux-headers@ needs to be installed.
   .
   Warning: btrfs is still considered experimental. This module is also
   experimental and may contain serious bugs that may result in data loss.
@@ -24,7 +24,6 @@
 
 extra-source-files:
   ChangeLog
-  include/missing.h
   include/btrfs/ctree.h
   include/btrfs/extent-cache.h
   include/btrfs/extent_io.h
@@ -45,8 +44,8 @@
 
 library
   exposed-modules:     System.Linux.Btrfs, System.Linux.Btrfs.ByteString,
-                       System.Linux.Btrfs.UUID
-  other-modules:       Data.Word.Endian, System.Linux.Btrfs.Time,
+                       System.Linux.Btrfs.UUID, System.Linux.Btrfs.Time
+  other-modules:       Data.Word.Endian,
                        System.Linux.Btrfs.FilePathLike
   build-depends:       base >=4.6 && <5, unix >=2.6,
                        time >=1.4, bytestring >=0.9
@@ -61,7 +60,8 @@
   if !flag(examples)
     buildable:           False
   else
-    build-depends:       base >=4.6 && <5, btrfs, unix, filepath
+    build-depends:       base >=4.6 && <5, btrfs, unix, filepath,
+                         linux-file-extents, ansi-terminal
     default-language:    Haskell2010
     ghc-options:         -Wall
 
@@ -82,5 +82,16 @@
     buildable:           False
   else
     build-depends:       base >=4.6 && <5, btrfs
+    default-language:    Haskell2010
+    ghc-options:         -Wall
+
+executable btrfs-print-creation-time
+  hs-source-dirs:      examples
+  include-dirs:        include
+  main-is:             btrfs-print-creation-time.hs
+  if !flag(examples)
+    buildable:           False
+  else
+    build-depends:       base >=4.6 && <5, btrfs, unix >=2.6, time >=1.4
     default-language:    Haskell2010
     ghc-options:         -Wall
diff --git a/examples/btrfs-defrag.hs b/examples/btrfs-defrag.hs
--- a/examples/btrfs-defrag.hs
+++ b/examples/btrfs-defrag.hs
@@ -1,41 +1,109 @@
+{-# LANGUAGE RecordWildCards #-}
+
 import Control.Monad
 import Control.Monad.Fix
 import Control.Exception
+import Control.Arrow ((***))
+import Data.Monoid
+import Data.IORef
+import Text.Printf
 import System.Posix
 import System.Environment
 import System.FilePath
 import System.IO
+import System.Linux.FileExtents
+import System.Console.ANSI
 
 import System.Linux.Btrfs
 
 main :: IO ()
 main = do
+    hSetBuffering stdout LineBuffering
+    hSetBuffering stderr LineBuffering
     paths <- getArgs
-    mapM_ defragRec paths
+    statsRef <- newIORef mempty
+    printStats mempty
+    mapM_ (flip traverseTree (defragFile statsRef)) paths
+    putChar '\n'
 
-defragRec :: FilePath -> IO ()
-defragRec path0 =
-    traverseTree path0 $ \path stat ->
-        when (isRegularFile stat) $
-            handleIOExn $ defrag path
+defragFile :: IORef Stats -> FilePath -> FileStatus -> IO ()
+defragFile statsRef path stat
+    | isRegularFile stat = do
+        extBefore <- getExtentCount defReqFlags path Nothing
+        when (extBefore > 1) $ do -- skip files with 1 extent
+            handleIOExn $ defragRange path dra
+            extAfter  <- getExtentCount defReqFlags path Nothing
+            stats <- readIORef statsRef
+            let stats' = stats <> Stats
+                    { stFiles = 1
+                    , stBytes = fromIntegral (fileSize stat)
+                    , stExtentsBefore = fromIntegral extBefore
+                    , stExtentsAfter  = fromIntegral extAfter
+                    }
+            writeIORef statsRef stats'
+            printStats stats'
+    | otherwise = return ()
+  where
+    dra = defaultDefragRangeArgs
+        { draExtentThreshold = 32 * 1024 * 1024
+        , draFlush = True
+        }
 
 traverseTree :: FilePath -> (FilePath -> FileStatus -> IO ()) -> IO ()
 traverseTree path action = do
     stat <- getSymbolicLinkStatus path
     action path stat
-    when (isDirectory stat) $ do
+    when (isDirectory stat) $
         loopDir path $ \s ->
             traverseTree (path </> s) action
 
 loopDir :: FilePath -> (FilePath -> IO ()) -> IO ()
-loopDir path action = do
+loopDir path action =
     bracket (openDirStream path) closeDirStream $ \dir ->
         fix $ \loop -> do
             s <- readDirStream dir
             unless (null s) $ do
-                unless (s == "." || s == "..") $ action s
+                unless (s == "." || s == "..") $
+                    action s
                 loop
 
 handleIOExn :: IO () -> IO ()
 handleIOExn =
-    handle (\e -> hPrint stderr (e ::  IOException))
+    handle $ \e -> do
+        putChar '\r'
+        clearFromCursorToLineEnd
+        hFlush stdout
+        hPrint stderr (e :: IOException)
+
+data Stats = Stats
+    { stFiles :: !Int
+    , stBytes :: !Integer
+    , stExtentsBefore :: !Int
+    , stExtentsAfter  :: !Int
+    }
+
+instance Monoid Stats where
+    mempty = Stats 0 0 0 0
+    mappend (Stats a1 b1 c1 d1) (Stats a2 b2 c2 d2) =
+        Stats (a1 + a2) (b1 + b2) (c1 + c2) (d1 + d2)
+
+printStats :: Stats -> IO ()
+printStats Stats{..} = do
+    printf "\rprocessed: %d file(s)/%s, extents (before/after): %d/%d"
+        stFiles
+        (prettyFileSize stBytes)
+        stExtentsBefore
+        stExtentsAfter
+    clearFromCursorToLineEnd
+    hFlush stdout
+
+prettyFileSize :: Integer -> String
+prettyFileSize s
+    | s < 1024 = printf "%d b" s
+    | s' < 10   = printf "%.2f %ciB" s' c
+    | s' < 100  = printf "%.1f %ciB" s' c
+    | otherwise = printf "%.0f %ciB" s' c
+  where
+    (s', c : _) = until ((< 1024) . fst)
+                        ((/ 1024) *** tail)
+                        (fromIntegral s / 1024 :: Double, "KMGTPEZY")
diff --git a/examples/btrfs-print-creation-time.hsc b/examples/btrfs-print-creation-time.hsc
new file mode 100644
--- /dev/null
+++ b/examples/btrfs-print-creation-time.hsc
@@ -0,0 +1,43 @@
+import System.Environment (getArgs)
+import Control.Monad (forM_)
+import Foreign (peekByteOff)
+import System.Posix (getFileStatus, fileID)
+import Data.Time (UTCTime, utcToLocalZonedTime, zonedTimeToLocalTime)
+
+import System.Linux.Btrfs
+import System.Linux.Btrfs.Time
+
+#include <btrfs/ctree.h>
+
+{-
+Starting with linux 4.0, btrfs records the creation time of inodes ("otime)
+for all newly created inodes. Older kernel wrote 0 (i.e. the unix epoch) in
+that field.
+-}
+
+main :: IO ()
+main = do
+    paths <- getArgs
+    forM_ paths $ \path -> do
+        t <- getOTime path >>= fmap zonedTimeToLocalTime . utcToLocalZonedTime
+        let s = show t
+        putStrLn $ s ++ replicate (30 - length s) ' ' ++ path
+
+getOTime :: FilePath -> IO UTCTime
+getOTime path = do
+    subvolId <- getSubvol path
+    inum <- fmap (fromIntegral . fileID) $ getFileStatus path
+    getOTimeById subvolId inum
+
+getOTimeById :: SubvolId -> InodeNum -> IO UTCTime
+getOTimeById subvolId inum = do
+    findFirstItem "/" sk $ \_ ptr -> do
+        BtrfsTime t <- (#peek struct btrfs_inode_item, otime) ptr
+        return t
+  where
+    sk = defaultSearchKey
+        { skTreeId = subvolId
+        , skMinObjectId = inum, skMinType = objType, skMinOffset = 0
+        , skMaxObjectId = inum, skMaxType = objType, skMaxOffset = 0
+        }
+    objType = #const BTRFS_INODE_ITEM_KEY
diff --git a/include/btrfs/ctree.h b/include/btrfs/ctree.h
--- a/include/btrfs/ctree.h
+++ b/include/btrfs/ctree.h
@@ -16,8 +16,8 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#ifndef __BTRFS__
-#define __BTRFS__
+#ifndef __BTRFS_CTREE_H__
+#define __BTRFS_CTREE_H__
 
 #if BTRFS_FLAT_INCLUDES
 #include "list.h"
@@ -76,6 +76,9 @@
 /* for storing items that use the BTRFS_UUID_KEY* */
 #define BTRFS_UUID_TREE_OBJECTID 9ULL
 
+/* tracks free space in block groups. */
+#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
+
 /* for storing balance parameters in the root tree */
 #define BTRFS_BALANCE_OBJECTID -4ULL
 
@@ -149,7 +152,7 @@
 /* csum types */
 #define BTRFS_CSUM_TYPE_CRC32	0
 
-static int btrfs_csum_sizes[] = { 4, 0 };
+static int btrfs_csum_sizes[] = { 4 };
 
 /* four bytes for CRC32 */
 #define BTRFS_CRC32_SIZE 4
@@ -309,6 +312,8 @@
 #define BTRFS_HEADER_FLAG_RELOC			(1ULL << 1)
 #define BTRFS_SUPER_FLAG_SEEDING		(1ULL << 32)
 #define BTRFS_SUPER_FLAG_METADUMP		(1ULL << 33)
+#define BTRFS_SUPER_FLAG_METADUMP_V2		(1ULL << 34)
+#define BTRFS_SUPER_FLAG_CHANGING_FSID		(1ULL << 35)
 
 #define BTRFS_BACKREF_REV_MAX		256
 #define BTRFS_BACKREF_REV_SHIFT		56
@@ -451,6 +456,8 @@
  * Compat flags that we support.  If any incompat flags are set other than the
  * ones specified below then we will fail to mount
  */
+#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE	(1ULL << 0)
+
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF	(1ULL << 0)
 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL	(1ULL << 1)
 #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS	(1ULL << 2)
@@ -474,9 +481,10 @@
 #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA	(1ULL << 8)
 #define BTRFS_FEATURE_INCOMPAT_NO_HOLES		(1ULL << 9)
 
-
 #define BTRFS_FEATURE_COMPAT_SUPP		0ULL
+
 #define BTRFS_FEATURE_COMPAT_RO_SUPP		0ULL
+
 #define BTRFS_FEATURE_INCOMPAT_SUPP			\
 	(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |		\
 	 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL |	\
@@ -548,9 +556,6 @@
 	 * and to force calls to keep space in the nodes
 	 */
 	unsigned int search_for_split:1;
-	unsigned int keep_locks:1;
-	unsigned int skip_locking:1;
-	unsigned int leave_spinning:1;
 	unsigned int skip_check_block:1;
 };
 
@@ -845,9 +850,10 @@
 #define BTRFS_BLOCK_GROUP_RAID1		(1ULL << 4)
 #define BTRFS_BLOCK_GROUP_DUP		(1ULL << 5)
 #define BTRFS_BLOCK_GROUP_RAID10	(1ULL << 6)
-#define BTRFS_BLOCK_GROUP_RAID5    (1ULL << 7)
-#define BTRFS_BLOCK_GROUP_RAID6    (1ULL << 8)
+#define BTRFS_BLOCK_GROUP_RAID5    	(1ULL << 7)
+#define BTRFS_BLOCK_GROUP_RAID6    	(1ULL << 8)
 #define BTRFS_BLOCK_GROUP_RESERVED	BTRFS_AVAIL_ALLOC_BIT_SINGLE
+#define BTRFS_NR_RAID_TYPES             7
 
 #define BTRFS_BLOCK_GROUP_TYPE_MASK	(BTRFS_BLOCK_GROUP_DATA |    \
 					 BTRFS_BLOCK_GROUP_SYSTEM |  \
@@ -863,12 +869,28 @@
 /* used in struct btrfs_balance_args fields */
 #define BTRFS_AVAIL_ALLOC_BIT_SINGLE	(1ULL << 48)
 
-#define BTRFS_QGROUP_STATUS_OFF			0
-#define BTRFS_QGROUP_STATUS_ON			1
-#define BTRFS_QGROUP_STATUS_SCANNING		2
+/*
+ * GLOBAL_RSV does not exist as a on-disk block group type and is used
+ * internally for exporting info about global block reserve from space infos
+ */
+#define BTRFS_SPACE_INFO_GLOBAL_RSV    (1ULL << 49)
 
-#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT	(1 << 0)
+#define BTRFS_QGROUP_LEVEL_SHIFT		48
 
+static inline u64 btrfs_qgroup_level(u64 qgroupid)
+{
+	return qgroupid >> BTRFS_QGROUP_LEVEL_SHIFT;
+}
+
+static inline u64 btrfs_qgroup_subvid(u64 qgroupid)
+{
+	return qgroupid & ((1ULL << BTRFS_QGROUP_LEVEL_SHIFT) - 1);
+}
+
+#define BTRFS_QGROUP_STATUS_FLAG_ON		(1ULL << 0)
+#define BTRFS_QGROUP_STATUS_FLAG_RESCAN		(1ULL << 1)
+#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT	(1ULL << 2)
+
 struct btrfs_qgroup_status_item {
 	__le64 version;
 	__le64 generation;
@@ -882,6 +904,13 @@
 	__le64 flags;
 } __attribute__ ((__packed__));
 
+struct btrfs_free_space_info {
+	__le32 extent_count;
+	__le32 flags;
+} __attribute__ ((__packed__));
+
+#define BTRFS_FREE_SPACE_USING_BITMAPS (1ULL << 0)
+
 struct btrfs_qgroup_info_item {
 	__le64 generation;
 	__le64 referenced;
@@ -921,6 +950,7 @@
 	struct btrfs_block_group_item item;
 	struct btrfs_space_info *space_info;
 	struct btrfs_free_space_ctl *free_space_ctl;
+	u64 bytes_super;
 	u64 pinned;
 	u64 flags;
 	int cached;
@@ -929,7 +959,7 @@
 
 struct btrfs_extent_ops {
        int (*alloc_extent)(struct btrfs_root *root, u64 num_bytes,
-		           u64 hint_byte, struct btrfs_key *ins);
+			   u64 hint_byte, struct btrfs_key *ins, int metadata);
        int (*free_extent)(struct btrfs_root *root, u64 bytenr,
 		          u64 num_bytes);
 };
@@ -938,7 +968,9 @@
 struct btrfs_fs_devices;
 struct btrfs_fs_info {
 	u8 fsid[BTRFS_FSID_SIZE];
+	u8 *new_fsid;
 	u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
+	u8 *new_chunk_tree_uuid;
 	struct btrfs_root *fs_root;
 	struct btrfs_root *extent_root;
 	struct btrfs_root *tree_root;
@@ -946,6 +978,7 @@
 	struct btrfs_root *dev_root;
 	struct btrfs_root *csum_root;
 	struct btrfs_root *quota_root;
+	struct btrfs_root *free_space_root;
 
 	struct rb_root fs_root_tree;
 
@@ -958,6 +991,7 @@
 	struct extent_io_tree pinned_extents;
 	struct extent_io_tree pending_del;
 	struct extent_io_tree extent_ins;
+	struct extent_io_tree *excluded_extents;
 
 	/* logical->physical extent mapping */
 	struct btrfs_mapping_tree mapping_tree;
@@ -992,6 +1026,8 @@
 	unsigned int on_restoring:1;
 	unsigned int is_chunk_recover:1;
 	unsigned int quota_enabled:1;
+	unsigned int suppress_check_block_errors:1;
+	unsigned int ignore_fsid_mismatch:1;
 
 	int (*free_extent_hook)(struct btrfs_trans_handle *trans,
 				struct btrfs_root *root,
@@ -1000,6 +1036,7 @@
 				int refs_to_drop);
 	struct cache_tree *fsck_extent_cache;
 	struct cache_tree *corrupt_blocks;
+
 };
 
 /*
@@ -1035,6 +1072,16 @@
 	u64 highest_inode;
 	u64 last_inode_alloc;
 
+	/*
+	 * Record orphan data extent ref
+	 *
+	 * TODO: Don't restore things in btrfs_root.
+	 * Directly record it into inode_record, which needs a lot of
+	 * infrastructure change to allow cooperation between extent
+	 * and fs tree scan.
+	 */
+	struct list_head orphan_data_extents;
+
 	/* the dirty list is only used by non-reference counted roots */
 	struct list_head dirty_list;
 	struct rb_node rb_node;
@@ -1124,6 +1171,27 @@
  */
 #define BTRFS_BLOCK_GROUP_ITEM_KEY 192
 
+/*
+ * Every block group is represented in the free space tree by a free space info
+ * item, which stores some accounting information. It is keyed on
+ * (block_group_start, FREE_SPACE_INFO, block_group_length).
+ */
+#define BTRFS_FREE_SPACE_INFO_KEY 198
+
+/*
+ * A free space extent tracks an extent of space that is free in a block group.
+ * It is keyed on (start, FREE_SPACE_EXTENT, length).
+ */
+#define BTRFS_FREE_SPACE_EXTENT_KEY 199
+
+/*
+ * When a block group becomes very fragmented, we convert it to use bitmaps
+ * instead of extents. A free space bitmap is keyed on
+ * (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with
+ * (length / sectorsize) bits.
+ */
+#define BTRFS_FREE_SPACE_BITMAP_KEY 200
+
 #define BTRFS_DEV_EXTENT_KEY	204
 #define BTRFS_DEV_ITEM_KEY	216
 #define BTRFS_CHUNK_ITEM_KEY	228
@@ -1361,6 +1429,11 @@
 BTRFS_SETGET_STACK_FUNCS(block_group_flags,
 			struct btrfs_block_group_item, flags, 64);
 
+/* struct btrfs_free_space_info */
+BTRFS_SETGET_FUNCS(free_space_extent_count, struct btrfs_free_space_info,
+		   extent_count, 32);
+BTRFS_SETGET_FUNCS(free_space_flags, struct btrfs_free_space_info, flags, 32);
+
 /* struct btrfs_inode_ref */
 BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
 BTRFS_SETGET_STACK_FUNCS(stack_inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
@@ -1390,7 +1463,9 @@
 BTRFS_SETGET_STACK_FUNCS(stack_inode_generation,
 			 struct btrfs_inode_item, generation, 64);
 BTRFS_SETGET_STACK_FUNCS(stack_inode_sequence,
-			 struct btrfs_inode_item, generation, 64);
+			 struct btrfs_inode_item, sequence, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_inode_transid,
+			 struct btrfs_inode_item, transid, 64);
 BTRFS_SETGET_STACK_FUNCS(stack_inode_size,
 			 struct btrfs_inode_item, size, 64);
 BTRFS_SETGET_STACK_FUNCS(stack_inode_nbytes,
@@ -1458,6 +1533,9 @@
 		   chunk_offset, 64);
 BTRFS_SETGET_FUNCS(dev_extent_length, struct btrfs_dev_extent, length, 64);
 
+BTRFS_SETGET_STACK_FUNCS(stack_dev_extent_length, struct btrfs_dev_extent,
+			 length, 64);
+
 static inline u8 *btrfs_dev_extent_chunk_tree_uuid(struct btrfs_dev_extent *dev)
 {
 	unsigned long ptr = offsetof(struct btrfs_dev_extent, chunk_tree_uuid);
@@ -2052,6 +2130,15 @@
 BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item,
 		   scan, 64);
 
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_version,
+			 struct btrfs_qgroup_status_item, version, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_generation,
+			 struct btrfs_qgroup_status_item, generation, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_flags,
+			 struct btrfs_qgroup_status_item, flags, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_scan,
+			 struct btrfs_qgroup_status_item, scan, 64);
+
 /* btrfs_qgroup_info_item */
 BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item,
 		   generation, 64);
@@ -2146,6 +2233,13 @@
 	return !!(btrfs_super_incompat_flags(disk_super) & flag);
 }
 
+static inline int btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)
+{
+	struct btrfs_super_block *disk_super;
+	disk_super = fs_info->super_copy;
+	return !!(btrfs_super_compat_ro_flags(disk_super) & flag);
+}
+
 /* helper function to cast into the data area of the leaf. */
 #define btrfs_item_ptr(leaf, slot, type) \
 	((type *)(btrfs_leaf_data(leaf) + \
@@ -2233,6 +2327,14 @@
 			      struct btrfs_inode_item *inode,
 			      u64 file_pos, u64 disk_bytenr,
 			      u64 num_bytes);
+int btrfs_free_block_group(struct btrfs_trans_handle *trans,
+			   struct btrfs_fs_info *fs_info, u64 bytenr, u64 len);
+void free_excluded_extents(struct btrfs_root *root,
+			   struct btrfs_block_group_cache *cache);
+int exclude_super_stripes(struct btrfs_root *root,
+			  struct btrfs_block_group_cache *cache);
+u64 add_new_free_space(struct btrfs_block_group_cache *block_group,
+		       struct btrfs_fs_info *info, u64 start, u64 end);
 /* ctree.c */
 int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2);
 int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
@@ -2250,6 +2352,8 @@
 int btrfs_previous_item(struct btrfs_root *root,
 			struct btrfs_path *path, u64 min_objectid,
 			int type);
+int btrfs_previous_extent_item(struct btrfs_root *root,
+			struct btrfs_path *path, u64 min_objectid);
 int btrfs_cow_block(struct btrfs_trans_handle *trans,
 		    struct btrfs_root *root, struct extent_buffer *buf,
 		    struct extent_buffer *parent, int parent_slot,
@@ -2278,6 +2382,9 @@
 int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
 		      *root, struct btrfs_key *key, struct btrfs_path *p, int
 		      ins_len, int cow);
+int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
+		u64 iobjectid, u64 ioff, u8 key_type,
+		struct btrfs_key *found_key);
 void btrfs_release_path(struct btrfs_path *p);
 void add_root_to_dirty_list(struct btrfs_root *root);
 struct btrfs_path *btrfs_alloc_path(void);
@@ -2310,6 +2417,15 @@
 }
 
 int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
+static inline int btrfs_next_item(struct btrfs_root *root,
+				  struct btrfs_path *p)
+{
+	++p->slots[0];
+	if (p->slots[0] >= btrfs_header_nritems(p->nodes[0]))
+		return btrfs_next_leaf(root, p);
+	return 0;
+}
+
 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);
 void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path,
@@ -2343,6 +2459,15 @@
 					     struct btrfs_path *path, u64 dir,
 					     const char *name, int name_len,
 					     int mod);
+struct btrfs_dir_item *btrfs_lookup_dir_index(struct btrfs_trans_handle *trans,
+					      struct btrfs_root *root,
+					      struct btrfs_path *path, u64 dir,
+					      const char *name, int name_len,
+					      u64 index, int mod);
+int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      struct btrfs_path *path,
+			      struct btrfs_dir_item *di);
 int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans,
 			    struct btrfs_root *root, const char *name,
 			    u16 name_len, const void *data, u16 data_len,
@@ -2363,6 +2488,26 @@
 int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
 		       *root, struct btrfs_path *path,
 		       struct btrfs_key *location, int mod);
+struct btrfs_inode_extref *btrfs_lookup_inode_extref(struct btrfs_trans_handle
+		*trans, struct btrfs_path *path, struct btrfs_root *root,
+		u64 ino, u64 parent_ino, u64 index, const char *name,
+		int namelen, int ins_len);
+int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
+			   struct btrfs_root *root,
+			   const char *name, int name_len,
+			   u64 inode_objectid, u64 ref_objectid,
+			   u64 *index);
+int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      const char *name, int name_len,
+			      u64 inode_objectid, u64 ref_objectid, u64 index);
+struct btrfs_inode_ref *btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
+		struct btrfs_root *root, struct btrfs_path *path,
+		const char *name, int namelen, u64 ino, u64 parent_ino,
+		u64 index, int ins_len);
+int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
+			struct btrfs_root *root, const char *name, int name_len,
+			u64 ino, u64 parent_ino, u64 *index);
 
 /* file-item.c */
 int btrfs_del_csums(struct btrfs_trans_handle *trans,
@@ -2394,4 +2539,30 @@
 		return 1;
 	return 0;
 }
+
+/* inode.c */
+int check_dir_conflict(struct btrfs_root *root, char *name, int namelen,
+		u64 dir, u64 index);
+int btrfs_new_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+		u64 ino, u32 mode);
+int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+		   u64 ino, u64 parent_ino, char *name, int namelen,
+		   u8 type, u64 *index, int add_backref);
+int btrfs_unlink(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+		 u64 ino, u64 parent_ino, u64 index, const char *name,
+		 int namelen, int add_orphan);
+int btrfs_add_orphan_item(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root, struct btrfs_path *path,
+			  u64 ino);
+int btrfs_mkdir(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+		char *name, int namelen, u64 parent_ino, u64 *ino, int mode);
+
+/* file.c */
+int btrfs_get_extent(struct btrfs_trans_handle *trans,
+		     struct btrfs_root *root,
+		     struct btrfs_path *path,
+		     u64 ino, u64 offset, u64 len, int ins_len);
+int btrfs_punch_hole(struct btrfs_trans_handle *trans,
+		     struct btrfs_root *root,
+		     u64 ino, u64 offset, u64 len);
 #endif
diff --git a/include/btrfs/extent-cache.h b/include/btrfs/extent-cache.h
--- a/include/btrfs/extent-cache.h
+++ b/include/btrfs/extent-cache.h
@@ -16,8 +16,8 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#ifndef __EXTENT_CACHE_H__
-#define __EXTENT_CACHE_H__
+#ifndef __BTRFS_EXTENT_CACHE_H__
+#define __BTRFS_EXTENT_CACHE_H__
 
 #if BTRFS_FLAT_INCLUDES
 #include "kerncompat.h"
@@ -41,14 +41,35 @@
 void cache_tree_init(struct cache_tree *tree);
 
 struct cache_extent *first_cache_extent(struct cache_tree *tree);
+struct cache_extent *last_cache_extent(struct cache_tree *tree);
 struct cache_extent *prev_cache_extent(struct cache_extent *pe);
 struct cache_extent *next_cache_extent(struct cache_extent *pe);
 
+/*
+ * Find a cache_extent which covers start.
+ *
+ * If not found, return next cache_extent if possible.
+ */
 struct cache_extent *search_cache_extent(struct cache_tree *tree, u64 start);
+
+/*
+ * Find a cahce_extent which restrictly covers start.
+ *
+ * If not found, return NULL.
+ */
 struct cache_extent *lookup_cache_extent(struct cache_tree *tree,
 					 u64 start, u64 size);
 
+/*
+ * Add an non-overlap extent into cache tree
+ *
+ * If [start, start+size) overlap with existing one, it will return -EEXIST.
+ */
 int add_cache_extent(struct cache_tree *tree, u64 start, u64 size);
+
+/*
+ * Same with add_cache_extent, but with cache_extent strcut.
+ */
 int insert_cache_extent(struct cache_tree *tree, struct cache_extent *pe);
 void remove_cache_extent(struct cache_tree *tree, struct cache_extent *pe);
 
@@ -70,12 +91,31 @@
 
 void free_extent_cache_tree(struct cache_tree *tree);
 
+/*
+ * Search a cache_extent with same objectid, and covers start.
+ *
+ * If not found, return next if possible.
+ */
 struct cache_extent *search_cache_extent2(struct cache_tree *tree,
 					  u64 objectid, u64 start);
+/*
+ * Search a cache_extent with same objectid, and covers the range
+ * [start, start + size)
+ *
+ * If not found, return next cache_extent if possible.
+ */
 struct cache_extent *lookup_cache_extent2(struct cache_tree *tree,
 					  u64 objectid, u64 start, u64 size);
 int add_cache_extent2(struct cache_tree *tree,
 		      u64 objectid, u64 start, u64 size);
 int insert_cache_extent2(struct cache_tree *tree, struct cache_extent *pe);
 
+/*
+ * Insert a cache_extent range [start, start + size).
+ *
+ * This function may merge with existing cache_extent.
+ * NOTE: caller must ensure the inserted range won't cover with any existing
+ * range.
+ */
+int add_merge_cache_extent(struct cache_tree *tree, u64 start, u64 size);
 #endif
diff --git a/include/btrfs/extent_io.h b/include/btrfs/extent_io.h
--- a/include/btrfs/extent_io.h
+++ b/include/btrfs/extent_io.h
@@ -16,8 +16,8 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#ifndef __EXTENTMAP__
-#define __EXTENTMAP__
+#ifndef __BTRFS_EXTENT_IO_H__
+#define __BTRFS_EXTENT_IO_H__
 
 #if BTRFS_FLAT_INCLUDES
 #include "kerncompat.h"
@@ -40,6 +40,7 @@
 #define EXTENT_BUFFER_FILLED (1 << 8)
 #define EXTENT_CSUM (1 << 9)
 #define EXTENT_BAD_TRANSID (1 << 10)
+#define EXTENT_BUFFER_DUMMY (1 << 11)
 #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
 
 #define BLOCK_GROUP_DATA     EXTENT_WRITEBACK
@@ -99,10 +100,28 @@
 		     u64 end, gfp_t mask);
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start,
 		       u64 end, gfp_t mask);
-int extent_buffer_uptodate(struct extent_buffer *eb);
-int set_extent_buffer_uptodate(struct extent_buffer *eb);
-int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
-				struct extent_buffer *eb);
+static inline int set_extent_buffer_uptodate(struct extent_buffer *eb)
+{
+	eb->flags |= EXTENT_UPTODATE;
+	return 0;
+}
+
+static inline int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
+				struct extent_buffer *eb)
+{
+	eb->flags &= ~EXTENT_UPTODATE;
+	return 0;
+}
+
+static inline int extent_buffer_uptodate(struct extent_buffer *eb)
+{
+	if (!eb || IS_ERR(eb))
+		return 0;
+	if (eb->flags & EXTENT_UPTODATE)
+		return 1;
+	return 0;
+}
+
 int set_state_private(struct extent_io_tree *tree, u64 start, u64 xprivate);
 int get_state_private(struct extent_io_tree *tree, u64 start, u64 *xprivate);
 struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
@@ -111,6 +130,7 @@
 					       u64 start);
 struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
 					  u64 bytenr, u32 blocksize);
+struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src);
 void free_extent_buffer(struct extent_buffer *eb);
 int read_extent_from_disk(struct extent_buffer *eb,
 			  unsigned long offset, unsigned long len);
@@ -128,6 +148,8 @@
 			   unsigned long src_offset, unsigned long len);
 void memset_extent_buffer(struct extent_buffer *eb, char c,
 			  unsigned long start, unsigned long len);
+int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
+			   unsigned long nr);
 int set_extent_buffer_dirty(struct extent_buffer *eb);
 int clear_extent_buffer_dirty(struct extent_buffer *eb);
 int read_data_from_disk(struct btrfs_fs_info *info, void *buf, u64 offset,
diff --git a/include/btrfs/ioctl.h b/include/btrfs/ioctl.h
--- a/include/btrfs/ioctl.h
+++ b/include/btrfs/ioctl.h
@@ -16,16 +16,20 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#ifndef __IOCTL_
-#define __IOCTL_
-#include <asm/types.h>
-#include <linux/ioctl.h>
-#include <time.h>
+#ifndef __BTRFS_IOCTL_H__
+#define __BTRFS_IOCTL_H__
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#include <asm/types.h>
+#include <linux/ioctl.h>
+
+#ifndef __user
+#define __user
+#endif
+
 #define BTRFS_IOCTL_MAGIC 0x94
 #define BTRFS_VOL_NAME_MAX 255
 
@@ -41,6 +45,8 @@
 #define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
 #define BTRFS_SUBVOL_RDONLY		(1ULL << 1)
 #define BTRFS_SUBVOL_QGROUP_INHERIT	(1ULL << 2)
+#define BTRFS_FSID_SIZE 16
+#define BTRFS_UUID_SIZE 16
 
 #define BTRFS_QGROUP_INHERIT_SET_LIMITS	(1ULL << 0)
 
@@ -67,7 +73,6 @@
 };
 
 #define BTRFS_SUBVOL_NAME_MAX 4039
-
 struct btrfs_ioctl_vol_args_v2 {
 	__s64 fd;
 	__u64 transid;
@@ -75,32 +80,48 @@
 	union {
 		struct {
 			__u64 size;
-			struct btrfs_qgroup_inherit *qgroup_inherit;
+			struct btrfs_qgroup_inherit __user *qgroup_inherit;
 		};
 		__u64 unused[4];
 	};
 	char name[BTRFS_SUBVOL_NAME_MAX + 1];
 };
 
-#define BTRFS_FSID_SIZE 16
-#define BTRFS_UUID_SIZE 16
-
+/*
+ * structure to report errors and progress to userspace, either as a
+ * result of a finished scrub, a canceled scrub or a progress inquiry
+ */
 struct btrfs_scrub_progress {
-	__u64 data_extents_scrubbed;
-	__u64 tree_extents_scrubbed;
-	__u64 data_bytes_scrubbed;
-	__u64 tree_bytes_scrubbed;
-	__u64 read_errors;
-	__u64 csum_errors;
-	__u64 verify_errors;
-	__u64 no_csum;
-	__u64 csum_discards;
-	__u64 super_errors;
-	__u64 malloc_errors;
-	__u64 uncorrectable_errors;
-	__u64 corrected_errors;
-	__u64 last_physical;
-	__u64 unverified_errors;
+	__u64 data_extents_scrubbed;	/* # of data extents scrubbed */
+	__u64 tree_extents_scrubbed;	/* # of tree extents scrubbed */
+	__u64 data_bytes_scrubbed;	/* # of data bytes scrubbed */
+	__u64 tree_bytes_scrubbed;	/* # of tree bytes scrubbed */
+	__u64 read_errors;		/* # of read errors encountered (EIO) */
+	__u64 csum_errors;		/* # of failed csum checks */
+	__u64 verify_errors;		/* # of occurences, where the metadata
+					 * of a tree block did not match the
+					 * expected values, like generation or
+					 * logical */
+	__u64 no_csum;			/* # of 4k data block for which no csum
+					 * is present, probably the result of
+					 * data written with nodatasum */
+	__u64 csum_discards;		/* # of csum for which no data was found
+					 * in the extent tree. */
+	__u64 super_errors;		/* # of bad super blocks encountered */
+	__u64 malloc_errors;		/* # of internal kmalloc errors. These
+					 * will likely cause an incomplete
+					 * scrub */
+	__u64 uncorrectable_errors;	/* # of errors where either no intact
+					 * copy was found or the writeback
+					 * failed */
+	__u64 corrected_errors;		/* # of errors corrected */
+	__u64 last_physical;		/* last physical address scrubbed. In
+					 * case a scrub was aborted, this can
+					 * be used to restart the scrub */
+	__u64 unverified_errors;	/* # of occurences where a read for a
+					 * full (64k) bio failed, but the re-
+					 * check succeeded for each 4k piece.
+					 * Intermittent error. */
 };
 
 #define BTRFS_SCRUB_READONLY	1
@@ -141,9 +162,11 @@
 #define BTRFS_IOCTL_DEV_REPLACE_CMD_START			0
 #define BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS			1
 #define BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL			2
+#define BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_RESULT		-1
 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR			0
 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED		1
 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED		2
+#define BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS		3
 struct btrfs_ioctl_dev_replace_args {
 	__u64 cmd;	/* in */
 	__u64 result;	/* out */
@@ -169,9 +192,19 @@
 	__u64 max_id;				/* out */
 	__u64 num_devices;			/* out */
 	__u8 fsid[BTRFS_FSID_SIZE];		/* out */
-	__u64 reserved[124];			/* pad to 1k */
+	__u32 nodesize;				/* out */
+	__u32 sectorsize;			/* out */
+	__u32 clone_alignment;			/* out */
+	__u32 reserved32;
+	__u64 reserved[122];			/* pad to 1k */
 };
 
+struct btrfs_ioctl_feature_flags {
+	__u64 compat_flags;
+	__u64 compat_ro_flags;
+	__u64 incompat_flags;
+};
+
 /* balance control ioctl modes */
 #define BTRFS_BALANCE_CTL_PAUSE		1
 #define BTRFS_BALANCE_CTL_CANCEL	2
@@ -183,7 +216,20 @@
  */
 struct btrfs_balance_args {
 	__u64 profiles;
-	__u64 usage;
+
+	/*
+	 * usage filter
+	 * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N'
+	 * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max
+	 */
+	union {
+		__u64 usage;
+		struct {
+			__u32 usage_min;
+			__u32 usage_max;
+		};
+	};
+
 	__u64 devid;
 	__u64 pstart;
 	__u64 pend;
@@ -194,15 +240,29 @@
 
 	__u64 flags;
 
-	__u64 limit;
-
-	__u64 unused[7];
+	/*
+	 * BTRFS_BALANCE_ARGS_LIMIT with value 'limit'
+	 * BTRFS_BALANCE_ARGS_LIMIT_RANGE - the extend version can use minimum
+	 * and maximum
+	 */
+	union {
+		__u64 limit;		/* limit number of processed chunks */
+		struct {
+			__u32 limit_min;
+			__u32 limit_max;
+		};
+	};
+	__u32 stripes_min;
+	__u32 stripes_max;
+	__u64 unused[6];
 } __attribute__ ((__packed__));
 
+/* report balance progress to userspace */
 struct btrfs_balance_progress {
-	__u64 expected;
-	__u64 considered;
-	__u64 completed;
+	__u64 expected;		/* estimated # of chunks that will be
+				 * relocated to fulfill the request */
+	__u64 considered;	/* # of chunks we have considered so far */
+	__u64 completed;	/* # of chunks relocated so far */
 };
 
 #define BTRFS_BALANCE_STATE_RUNNING	(1ULL << 0)
@@ -222,6 +282,13 @@
 	__u64 unused[72];			/* pad to 1k */
 };
 
+#define BTRFS_INO_LOOKUP_PATH_MAX 4080
+struct btrfs_ioctl_ino_lookup_args {
+	__u64 treeid;
+	__u64 objectid;
+	char name[BTRFS_INO_LOOKUP_PATH_MAX];
+};
+
 struct btrfs_ioctl_search_key {
 	/* which root are we searching.  0 is the tree of tree roots */
 	__u64 tree_id;
@@ -277,17 +344,54 @@
 	char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
 };
 
-#define BTRFS_INO_LOOKUP_PATH_MAX 4080
-struct btrfs_ioctl_ino_lookup_args {
-	__u64 treeid;
-	__u64 objectid;
-	char name[BTRFS_INO_LOOKUP_PATH_MAX];
+/*
+ * Extended version of TREE_SEARCH ioctl that can return more than 4k of bytes.
+ * The allocated size of the buffer is set in buf_size.
+ */
+struct btrfs_ioctl_search_args_v2 {
+        struct btrfs_ioctl_search_key key; /* in/out - search parameters */
+        __u64 buf_size;			   /* in - size of buffer
+                                            * out - on EOVERFLOW: needed size
+                                            *       to store item */
+        __u64 buf[0];                      /* out - found items */
 };
 
+/* With a @src_length of zero, the range from @src_offset->EOF is cloned! */
+struct btrfs_ioctl_clone_range_args {
+	__s64 src_fd;
+	__u64 src_offset, src_length;
+	__u64 dest_offset;
+};
+
 /* flags for the defrag range ioctl */
 #define BTRFS_DEFRAG_RANGE_COMPRESS 1
 #define BTRFS_DEFRAG_RANGE_START_IO 2
 
+#define BTRFS_SAME_DATA_DIFFERS	1
+/* For extent-same ioctl */
+struct btrfs_ioctl_same_extent_info {
+	__s64 fd;		/* in - destination file */
+	__u64 logical_offset;	/* in - start of extent in destination */
+	__u64 bytes_deduped;	/* out - total # of bytes we were able
+				 * to dedupe from this file */
+	/* status of this dedupe operation:
+	 * 0 if dedup succeeds
+	 * < 0 for error
+	 * == BTRFS_SAME_DATA_DIFFERS if data differs
+	 */
+	__s32 status;		/* out - see above description */
+	__u32 reserved;
+};
+
+struct btrfs_ioctl_same_args {
+	__u64 logical_offset;	/* in - start of extent in source */
+	__u64 length;		/* in - length of extent */
+	__u16 dest_count;	/* in - total elements in info array */
+	__u16 reserved1;
+	__u32 reserved2;
+	struct btrfs_ioctl_same_extent_info info[0];
+};
+
 struct btrfs_ioctl_defrag_range_args {
 	/* start of the defrag operation */
 	__u64 start;
@@ -355,50 +459,6 @@
 	__u64				inodes;
 };
 
-struct btrfs_ioctl_timespec {
-	__u64 sec;
-	__u32 nsec;
-};
-
-struct btrfs_ioctl_received_subvol_args {
-	char	uuid[BTRFS_UUID_SIZE];	/* in */
-	__u64	stransid;		/* in */
-	__u64	rtransid;		/* out */
-	struct btrfs_ioctl_timespec stime; /* in */
-	struct btrfs_ioctl_timespec rtime; /* out */
-	__u64	flags;			/* in */
-	__u64	reserved[16];		/* in */
-};
-
-/*
- * Caller doesn't want file data in the send stream, even if the
- * search of clone sources doesn't find an extent. UPDATE_EXTENT
- * commands will be sent instead of WRITE commands.
- */
-#define BTRFS_SEND_FLAG_NO_FILE_DATA		0x1
-
-/*
- * Do not add the leading stream header. Used when multiple snapshots
- * are sent back to back.
- */
-#define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER	0x2
-
-/*
- * Omit the command at the end of the stream that indicated the end
- * of the stream. This option is used when multiple snapshots are
- * sent back to back.
- */
-#define BTRFS_SEND_FLAG_OMIT_END_CMD		0x4
-
-struct btrfs_ioctl_send_args {
-	__s64 send_fd;			/* in */
-	__u64 clone_sources_count;	/* in */
-	__u64 *clone_sources;		/* in */
-	__u64 parent_root;		/* in */
-	__u64 flags;			/* in */
-	__u64 reserved[4];		/* in */
-};
-
 enum btrfs_dev_stat_values {
 	/* disk I/O failure stats */
 	BTRFS_DEV_STAT_WRITE_ERRS, /* EIO or EREMOTEIO from lower layers */
@@ -457,7 +517,55 @@
 	__u64 create;
 	__u64 qgroupid;
 };
+struct btrfs_ioctl_timespec {
+	__u64 sec;
+	__u32 nsec;
+};
 
+struct btrfs_ioctl_received_subvol_args {
+	char	uuid[BTRFS_UUID_SIZE];	/* in */
+	__u64	stransid;		/* in */
+	__u64	rtransid;		/* out */
+	struct btrfs_ioctl_timespec stime; /* in */
+	struct btrfs_ioctl_timespec rtime; /* out */
+	__u64	flags;			/* in */
+	__u64	reserved[16];		/* in */
+};
+
+/*
+ * Caller doesn't want file data in the send stream, even if the
+ * search of clone sources doesn't find an extent. UPDATE_EXTENT
+ * commands will be sent instead of WRITE commands.
+ */
+#define BTRFS_SEND_FLAG_NO_FILE_DATA		0x1
+
+/*
+ * Do not add the leading stream header. Used when multiple snapshots
+ * are sent back to back.
+ */
+#define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER	0x2
+
+/*
+ * Omit the command at the end of the stream that indicated the end
+ * of the stream. This option is used when multiple snapshots are
+ * sent back to back.
+ */
+#define BTRFS_SEND_FLAG_OMIT_END_CMD		0x4
+
+#define BTRFS_SEND_FLAG_MASK \
+	(BTRFS_SEND_FLAG_NO_FILE_DATA | \
+	 BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | \
+	 BTRFS_SEND_FLAG_OMIT_END_CMD)
+
+struct btrfs_ioctl_send_args {
+	__s64 send_fd;			/* in */
+	__u64 clone_sources_count;	/* in */
+	__u64 __user *clone_sources;	/* in */
+	__u64 parent_root;		/* in */
+	__u64 flags;			/* in */
+	__u64 reserved[4];		/* in */
+};
+
 /* Error codes as returned by the kernel */
 enum btrfs_err_code {
 	notused,
@@ -507,14 +615,6 @@
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
 				   struct btrfs_ioctl_vol_args)
-
-/* With a @src_length of zero, the range from @src_offset->EOF is cloned! */
-struct btrfs_ioctl_clone_range_args {
-	__s64 src_fd;
-	__u64 src_offset, src_length;
-	__u64 dest_offset;
-};
-
 /* trans start and trans end are dangerous, and only for
  * use by applications that know how to avoid the
  * resulting deadlocks
@@ -530,8 +630,10 @@
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \
 				   struct btrfs_ioctl_vol_args)
+
 #define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \
 				   struct btrfs_ioctl_clone_range_args)
+
 #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \
@@ -540,6 +642,8 @@
 				struct btrfs_ioctl_defrag_range_args)
 #define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
 				   struct btrfs_ioctl_search_args)
+#define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
+				   struct btrfs_ioctl_search_args_v2)
 #define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
 				   struct btrfs_ioctl_ino_lookup_args)
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, __u64)
@@ -571,12 +675,11 @@
 					struct btrfs_ioctl_ino_path_args)
 #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
 					struct btrfs_ioctl_ino_path_args)
-#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, \
-				     struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SET_RECEIVED_SUBVOL _IOWR(BTRFS_IOCTL_MAGIC, 37, \
 				struct btrfs_ioctl_received_subvol_args)
 #define BTRFS_IOC_SEND _IOW(BTRFS_IOCTL_MAGIC, 38, struct btrfs_ioctl_send_args)
-
+#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, \
+				     struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_QUOTA_CTL _IOWR(BTRFS_IOCTL_MAGIC, 40, \
 					struct btrfs_ioctl_quota_ctl_args)
 #define BTRFS_IOC_QGROUP_ASSIGN _IOW(BTRFS_IOCTL_MAGIC, 41, \
@@ -598,6 +701,8 @@
 				      struct btrfs_ioctl_get_dev_stats)
 #define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \
 				    struct btrfs_ioctl_dev_replace_args)
+#define BTRFS_IOC_FILE_EXTENT_SAME _IOWR(BTRFS_IOCTL_MAGIC, 54, \
+					 struct btrfs_ioctl_same_args)
 #define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
                                   struct btrfs_ioctl_feature_flags)
 #define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
diff --git a/include/btrfs/kerncompat.h b/include/btrfs/kerncompat.h
--- a/include/btrfs/kerncompat.h
+++ b/include/btrfs/kerncompat.h
@@ -16,8 +16,8 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#ifndef __KERNCOMPAT
-#define __KERNCOMPAT
+#ifndef __KERNCOMPAT_H__
+#define __KERNCOMPAT_H__
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,6 +30,19 @@
 #include <linux/types.h>
 #include <stdint.h>
 
+#include <features.h>
+
+#ifndef __GLIBC__
+#ifndef BTRFS_DISABLE_BACKTRACE
+#define BTRFS_DISABLE_BACKTRACE
+#endif
+#define __always_inline __inline __attribute__ ((__always_inline__))
+#endif
+
+#ifndef BTRFS_DISABLE_BACKTRACE
+#include <execinfo.h>
+#endif
+
 #define ptr_to_u64(x)	((u64)(uintptr_t)x)
 #define u64_to_ptr(x)	((void *)(uintptr_t)x)
 
@@ -54,7 +67,37 @@
 #define ULONG_MAX       (~0UL)
 #endif
 
+#ifndef BTRFS_DISABLE_BACKTRACE
+#define MAX_BACKTRACE	16
+static inline void print_trace(void)
+{
+	void *array[MAX_BACKTRACE];
+	size_t size;
+
+	size = backtrace(array, MAX_BACKTRACE);
+	backtrace_symbols_fd(array, size, 2);
+}
+
+static inline void assert_trace(const char *assertion, const char *filename,
+			      const char *func, unsigned line, int val)
+{
+	if (val)
+		return;
+	if (assertion)
+		fprintf(stderr, "%s:%d: %s: Assertion `%s` failed.\n",
+			filename, line, func, assertion);
+	else
+		fprintf(stderr, "%s:%d: %s: Assertion failed.\n", filename,
+			line, func);
+	print_trace();
+	exit(1);
+}
+
+#define BUG() assert_trace(NULL, __FILE__, __func__, __LINE__, 0)
+#else
 #define BUG() assert(0)
+#endif
+
 #ifdef __CHECKER__
 #define __force    __attribute__((force))
 #define __bitwise__ __attribute__((bitwise))
@@ -75,6 +118,9 @@
 typedef __u64 u64;
 typedef __u16 u16;
 typedef __u8 u8;
+typedef __s64 s64;
+typedef __s32 s32;
+
 /*
  * Continuing to define __KERNEL__ breaks others parts of the code, so
  * we can just undefine it now that we have the correct headers...
@@ -86,6 +132,8 @@
 typedef unsigned long long u64;
 typedef unsigned char u8;
 typedef unsigned short u16;
+typedef long long s64;
+typedef int s32;
 #endif
 
 
@@ -236,11 +284,23 @@
 #define kzalloc(x, y) calloc(1, x)
 #define kstrdup(x, y) strdup(x)
 #define kfree(x) free(x)
+#define vmalloc(x) malloc(x)
+#define vfree(x) free(x)
 
+#ifndef BTRFS_DISABLE_BACKTRACE
+#define BUG_ON(c) assert_trace(#c, __FILE__, __func__, __LINE__, !(c))
+#else
 #define BUG_ON(c) assert(!(c))
-#define WARN_ON(c) assert(!(c))
-#define	ASSERT(c) assert(c)
+#endif
 
+#define WARN_ON(c) BUG_ON(c)
+
+#ifndef BTRFS_DISABLE_BACKTRACE
+#define	ASSERT(c) assert_trace(#c, __FILE__, __func__, __LINE__, (c))
+#else
+#define ASSERT(c) assert(c)
+#endif
+
 #define container_of(ptr, type, member) ({                      \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 	        (type *)( (char *)__mptr - offsetof(type,member) );})
@@ -250,6 +310,14 @@
 #define __bitwise
 #endif
 
+/* Alignment check */
+#define IS_ALIGNED(x, a)                (((x) & ((typeof(x))(a) - 1)) == 0)
+
+static inline int is_power_of_2(unsigned long n)
+{
+	return (n != 0 && ((n & (n - 1)) == 0));
+}
+
 typedef u16 __bitwise __le16;
 typedef u16 __bitwise __be16;
 typedef u32 __bitwise __le32;
@@ -293,8 +361,14 @@
 #define put_unaligned_le32(val,p) (((struct __una_u32 *)(p))->x = cpu_to_le32(val))
 #define get_unaligned_le64(p) le64_to_cpu(((const struct __una_u64 *)(p))->x)
 #define put_unaligned_le64(val,p) (((struct __una_u64 *)(p))->x = cpu_to_le64(val))
+
+#ifndef true
+#define true 1
+#define false 0
 #endif
 
 #ifndef noinline
 #define noinline
+#endif
+
 #endif
diff --git a/include/btrfs/rbtree.h b/include/btrfs/rbtree.h
--- a/include/btrfs/rbtree.h
+++ b/include/btrfs/rbtree.h
@@ -23,72 +23,7 @@
   I know it's not the cleaner way,  but in C (not in C++) to get
   performances and genericity...
 
-  Some example of insert and search follows here. The search is a plain
-  normal search over an ordered tree. The insert instead must be implemented
-  int two steps: as first thing the code must insert the element in
-  order as a red leaf in the tree, then the support library function
-  rb_insert_color() must be called. Such function will do the
-  not trivial work to rebalance the rbtree if necessary.
-
------------------------------------------------------------------------
-static inline struct page * rb_search_page_cache(struct inode * inode,
-						 unsigned long offset)
-{
-	struct rb_node * n = inode->i_rb_page_cache.rb_node;
-	struct page * page;
-
-	while (n)
-	{
-		page = rb_entry(n, struct page, rb_page_cache);
-
-		if (offset < page->offset)
-			n = n->rb_left;
-		else if (offset > page->offset)
-			n = n->rb_right;
-		else
-			return page;
-	}
-	return NULL;
-}
-
-static inline struct page * __rb_insert_page_cache(struct inode * inode,
-						   unsigned long offset,
-						   struct rb_node * node)
-{
-	struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
-	struct rb_node * parent = NULL;
-	struct page * page;
-
-	while (*p)
-	{
-		parent = *p;
-		page = rb_entry(parent, struct page, rb_page_cache);
-
-		if (offset < page->offset)
-			p = &(*p)->rb_left;
-		else if (offset > page->offset)
-			p = &(*p)->rb_right;
-		else
-			return page;
-	}
-
-	rb_link_node(node, parent, p);
-
-	return NULL;
-}
-
-static inline struct page * rb_insert_page_cache(struct inode * inode,
-						 unsigned long offset,
-						 struct rb_node * node)
-{
-	struct page * ret;
-	if ((ret = __rb_insert_page_cache(inode, offset, node)))
-		goto out;
-	rb_insert_color(node, &inode->i_rb_page_cache);
- out:
-	return ret;
-}
------------------------------------------------------------------------
+  See Documentation/rbtree.txt for documentation and samples.
 */
 
 #ifndef	_LINUX_RBTREE_H
@@ -98,85 +33,86 @@
 #else
 #include <btrfs/kerncompat.h>
 #endif /* BTRFS_FLAT_INCLUDES */
-struct rb_node
-{
-	unsigned long  rb_parent_color;
-#define	RB_RED		0
-#define	RB_BLACK	1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rb_node {
+	unsigned long  __rb_parent_color;
 	struct rb_node *rb_right;
 	struct rb_node *rb_left;
 } __attribute__((aligned(sizeof(long))));
     /* The alignment might seem pointless, but allegedly CRIS needs it */
 
-struct rb_root
-{
+struct rb_root {
 	struct rb_node *rb_node;
 };
 
-#define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
-#define rb_color(r)   ((r)->rb_parent_color & 1)
-#define rb_is_red(r)   (!rb_color(r))
-#define rb_is_black(r) rb_color(r)
-#define rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
-#define rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
 
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
-	rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
-}
-static inline void rb_set_color(struct rb_node *rb, int color)
-{
-	rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
-}
+#define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))
 
 #define RB_ROOT	(struct rb_root) { NULL, }
 #define	rb_entry(ptr, type, member) container_of(ptr, type, member)
 
-#define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
-#define RB_EMPTY_NODE(node)	(rb_parent(node) == node)
-#define RB_CLEAR_NODE(node)	(rb_set_parent(node, node))
+#define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)
 
+/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
+#define RB_EMPTY_NODE(node)  \
+	((node)->__rb_parent_color == (unsigned long)(node))
+#define RB_CLEAR_NODE(node)  \
+	((node)->__rb_parent_color = (unsigned long)(node))
+
+
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
+
 /* Find logical next and previous nodes in a tree */
-extern struct rb_node *rb_next(struct rb_node *);
-extern struct rb_node *rb_prev(struct rb_node *);
-extern struct rb_node *rb_first(struct rb_root *);
-extern struct rb_node *rb_last(struct rb_root *);
+extern struct rb_node *rb_next(const struct rb_node *);
+extern struct rb_node *rb_prev(const struct rb_node *);
+extern struct rb_node *rb_first(const struct rb_root *);
+extern struct rb_node *rb_last(const struct rb_root *);
 
+/* Postorder iteration - always visit the parent after its children */
+extern struct rb_node *rb_first_postorder(const struct rb_root *);
+extern struct rb_node *rb_next_postorder(const struct rb_node *);
+
 /* Fast replacement of a single node without remove/rebalance/add/rebalance */
-extern void rb_replace_node(struct rb_node *victim, struct rb_node *xnew,
+extern void rb_replace_node(struct rb_node *victim, struct rb_node *new_node,
 			    struct rb_root *root);
 
 static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
 				struct rb_node ** rb_link)
 {
-	node->rb_parent_color = (unsigned long )parent;
+	node->__rb_parent_color = (unsigned long)parent;
 	node->rb_left = node->rb_right = NULL;
 
 	*rb_link = node;
 }
 
-/* The common insert/search/free functions */
-typedef int (*rb_compare_nodes)(struct rb_node *node1, struct rb_node *node2);
-typedef int (*rb_compare_keys)(struct rb_node *node, void *key);
-typedef void (*rb_free_node)(struct rb_node *node);
+#define rb_entry_safe(ptr, type, member) \
+	({ typeof(ptr) ____ptr = (ptr); \
+	   ____ptr ? rb_entry(____ptr, type, member) : NULL; \
+	})
 
-int rb_insert(struct rb_root *root, struct rb_node *node,
-	      rb_compare_nodes comp);
-/*
- * In some cases, we need return the next node if we don't find the node we
- * specify. At this time, we can use next_ret.
+/**
+ * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of
+ * given type safe against removal of rb_node entry
+ *
+ * @pos:	the 'type *' to use as a loop cursor.
+ * @n:		another 'type *' to use as temporary storage
+ * @root:	'rb_root *' of the rbtree.
+ * @field:	the name of the rb_node field within 'type'.
  */
-struct rb_node *rb_search(struct rb_root *root, void *key, rb_compare_keys comp,
-			  struct rb_node **next_ret);
-void rb_free_nodes(struct rb_root *root, rb_free_node free_node);
+#define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
+	for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \
+	     pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \
+			typeof(*pos), field); 1; }); \
+	     pos = n)
 
-#define FREE_RB_BASED_TREE(name, free_func)		\
-static void free_##name##_tree(struct rb_root *root)	\
-{							\
-	rb_free_nodes(root, free_func);			\
+#ifdef __cplusplus
 }
+#endif
 
 #endif	/* _LINUX_RBTREE_H */
diff --git a/include/missing.h b/include/missing.h
deleted file mode 100644
--- a/include/missing.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Unfortunately, btrfs/ioctl.h (from btrfs-progs) and linux/btrfs.h (from
- * linux-headers) have some differences. We put here some parts that are
- * missing * from btrfs/ioctl.h.
- */
-
-#ifndef MISSING_H
-#define MISSING_H
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BTRFS_SAME_DATA_DIFFERS	1
-
-struct btrfs_ioctl_same_extent_info {
-	__s64 fd;		/* in - destination file */
-	__u64 logical_offset;	/* in - start of extent in destination */
-	__u64 bytes_deduped;	/* out - total # of bytes we were able
-				 * to dedupe from this file */
-	/* status of this dedupe operation:
-	 * 0 if dedup succeeds
-	 * < 0 for error
-	 * == BTRFS_SAME_DATA_DIFFERS if data differs
-	 */
-	__s32 status;		/* out - see above description */
-	__u32 reserved;
-};
-
-struct btrfs_ioctl_same_args {
-	__u64 logical_offset;	/* in - start of extent in source */
-	__u64 length;		/* in - length of extent */
-	__u16 dest_count;	/* in - total elements in info array */
-	__u16 reserved1;
-	__u32 reserved2;
-	struct btrfs_ioctl_same_extent_info info[0];
-};
-
-#define BTRFS_IOC_FILE_EXTENT_SAME _IOWR(BTRFS_IOCTL_MAGIC, 54, \
-					 struct btrfs_ioctl_same_args)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
