packages feed

btrfs 0.1.1.1 → 0.1.2.0

raw patch · 14 files changed

+745/−304 lines, 14 filesdep +ansi-terminaldep +linux-file-extentsnew-component:exe:btrfs-print-creation-timePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: ansi-terminal, linux-file-extents

API changes (from Hackage documentation)

- System.Linux.Btrfs: draCompress :: DefragRangeArgs -> Maybe CompressionType
- System.Linux.Btrfs: draExtentThreshold :: DefragRangeArgs -> Word32
- System.Linux.Btrfs: draFlush :: DefragRangeArgs -> Bool
- System.Linux.Btrfs: draLength :: DefragRangeArgs -> FileSize
- System.Linux.Btrfs: draStart :: DefragRangeArgs -> FileSize
- System.Linux.Btrfs: instance Bounded CompressionType
- System.Linux.Btrfs: instance Enum CompressionType
- System.Linux.Btrfs: instance Eq CloneResult
- System.Linux.Btrfs: instance Eq CompressionType
- System.Linux.Btrfs: instance Eq DefragRangeArgs
- System.Linux.Btrfs: instance Eq SearchHeader
- System.Linux.Btrfs: instance Eq SearchKey
- System.Linux.Btrfs: instance Eq SubvolInfo
- System.Linux.Btrfs: instance Read CompressionType
- System.Linux.Btrfs: instance Show CloneResult
- System.Linux.Btrfs: instance Show CompressionType
- System.Linux.Btrfs: instance Show DefragRangeArgs
- System.Linux.Btrfs: instance Show SearchHeader
- System.Linux.Btrfs: instance Show SearchKey
- System.Linux.Btrfs: instance Show SubvolInfo
- System.Linux.Btrfs: instance Storable SameExtentInfoIn
- System.Linux.Btrfs: instance Storable SameExtentInfoOut
- System.Linux.Btrfs: shLen :: SearchHeader -> Word32
- System.Linux.Btrfs: shObjectId :: SearchHeader -> ObjectId
- System.Linux.Btrfs: shOffset :: SearchHeader -> Word64
- System.Linux.Btrfs: shTransId :: SearchHeader -> Word64
- System.Linux.Btrfs: shType :: SearchHeader -> ObjectType
- System.Linux.Btrfs: siCTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs: siCTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs: siGeneration :: SubvolInfo -> Word64
- System.Linux.Btrfs: siLastSnapshot :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs: siOTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs: siOTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs: siPUuid :: SubvolInfo -> Maybe UUID
- System.Linux.Btrfs: siParSnapGen :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs: siRTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs: siRTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs: siReadOnly :: SubvolInfo -> Bool
- System.Linux.Btrfs: siReceivedUuid :: SubvolInfo -> Maybe UUID
- System.Linux.Btrfs: siSTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs: siSTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs: siUuid :: SubvolInfo -> Maybe UUID
- System.Linux.Btrfs: skMaxObjectId :: SearchKey -> ObjectId
- System.Linux.Btrfs: skMaxOffset :: SearchKey -> Word64
- System.Linux.Btrfs: skMaxTransId :: SearchKey -> Word64
- System.Linux.Btrfs: skMaxType :: SearchKey -> ObjectType
- System.Linux.Btrfs: skMinObjectId :: SearchKey -> ObjectId
- System.Linux.Btrfs: skMinOffset :: SearchKey -> Word64
- System.Linux.Btrfs: skMinTransId :: SearchKey -> Word64
- System.Linux.Btrfs: skMinType :: SearchKey -> ObjectType
- System.Linux.Btrfs: skTreeId :: SearchKey -> ObjectId
- System.Linux.Btrfs.ByteString: draCompress :: DefragRangeArgs -> Maybe CompressionType
- System.Linux.Btrfs.ByteString: draExtentThreshold :: DefragRangeArgs -> Word32
- System.Linux.Btrfs.ByteString: draFlush :: DefragRangeArgs -> Bool
- System.Linux.Btrfs.ByteString: draLength :: DefragRangeArgs -> FileSize
- System.Linux.Btrfs.ByteString: draStart :: DefragRangeArgs -> FileSize
- System.Linux.Btrfs.ByteString: instance Bounded CompressionType
- System.Linux.Btrfs.ByteString: instance Enum CompressionType
- System.Linux.Btrfs.ByteString: instance Eq CloneResult
- System.Linux.Btrfs.ByteString: instance Eq CompressionType
- System.Linux.Btrfs.ByteString: instance Eq DefragRangeArgs
- System.Linux.Btrfs.ByteString: instance Eq SearchHeader
- System.Linux.Btrfs.ByteString: instance Eq SearchKey
- System.Linux.Btrfs.ByteString: instance Eq SubvolInfo
- System.Linux.Btrfs.ByteString: instance Read CompressionType
- System.Linux.Btrfs.ByteString: instance Show CloneResult
- System.Linux.Btrfs.ByteString: instance Show CompressionType
- System.Linux.Btrfs.ByteString: instance Show DefragRangeArgs
- System.Linux.Btrfs.ByteString: instance Show SearchHeader
- System.Linux.Btrfs.ByteString: instance Show SearchKey
- System.Linux.Btrfs.ByteString: instance Show SubvolInfo
- System.Linux.Btrfs.ByteString: instance Storable SameExtentInfoIn
- System.Linux.Btrfs.ByteString: instance Storable SameExtentInfoOut
- System.Linux.Btrfs.ByteString: shLen :: SearchHeader -> Word32
- System.Linux.Btrfs.ByteString: shObjectId :: SearchHeader -> ObjectId
- System.Linux.Btrfs.ByteString: shOffset :: SearchHeader -> Word64
- System.Linux.Btrfs.ByteString: shTransId :: SearchHeader -> Word64
- System.Linux.Btrfs.ByteString: shType :: SearchHeader -> ObjectType
- System.Linux.Btrfs.ByteString: siCTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs.ByteString: siCTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs.ByteString: siGeneration :: SubvolInfo -> Word64
- System.Linux.Btrfs.ByteString: siLastSnapshot :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs.ByteString: siOTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs.ByteString: siOTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs.ByteString: siPUuid :: SubvolInfo -> Maybe UUID
- System.Linux.Btrfs.ByteString: siParSnapGen :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs.ByteString: siRTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs.ByteString: siRTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs.ByteString: siReadOnly :: SubvolInfo -> Bool
- System.Linux.Btrfs.ByteString: siReceivedUuid :: SubvolInfo -> Maybe UUID
- System.Linux.Btrfs.ByteString: siSTime :: SubvolInfo -> Maybe UTCTime
- System.Linux.Btrfs.ByteString: siSTransId :: SubvolInfo -> Maybe Word64
- System.Linux.Btrfs.ByteString: siUuid :: SubvolInfo -> Maybe UUID
- System.Linux.Btrfs.ByteString: skMaxObjectId :: SearchKey -> ObjectId
- System.Linux.Btrfs.ByteString: skMaxOffset :: SearchKey -> Word64
- System.Linux.Btrfs.ByteString: skMaxTransId :: SearchKey -> Word64
- System.Linux.Btrfs.ByteString: skMaxType :: SearchKey -> ObjectType
- System.Linux.Btrfs.ByteString: skMinObjectId :: SearchKey -> ObjectId
- System.Linux.Btrfs.ByteString: skMinOffset :: SearchKey -> Word64
- System.Linux.Btrfs.ByteString: skMinTransId :: SearchKey -> Word64
- System.Linux.Btrfs.ByteString: skMinType :: SearchKey -> ObjectType
- System.Linux.Btrfs.ByteString: skTreeId :: SearchKey -> ObjectId
- System.Linux.Btrfs.UUID: instance Eq UUID
- System.Linux.Btrfs.UUID: instance Ord UUID
- System.Linux.Btrfs.UUID: instance Show UUID
- System.Linux.Btrfs.UUID: instance Storable UUID
+ System.Linux.Btrfs: [draCompress] :: DefragRangeArgs -> Maybe CompressionType
+ System.Linux.Btrfs: [draExtentThreshold] :: DefragRangeArgs -> Word32
+ System.Linux.Btrfs: [draFlush] :: DefragRangeArgs -> Bool
+ System.Linux.Btrfs: [draLength] :: DefragRangeArgs -> FileSize
+ System.Linux.Btrfs: [draStart] :: DefragRangeArgs -> FileSize
+ System.Linux.Btrfs: [shLen] :: SearchHeader -> Word32
+ System.Linux.Btrfs: [shObjectId] :: SearchHeader -> ObjectId
+ System.Linux.Btrfs: [shOffset] :: SearchHeader -> Word64
+ System.Linux.Btrfs: [shTransId] :: SearchHeader -> Word64
+ System.Linux.Btrfs: [shType] :: SearchHeader -> ObjectType
+ System.Linux.Btrfs: [siCTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs: [siCTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs: [siGeneration] :: SubvolInfo -> Word64
+ System.Linux.Btrfs: [siLastSnapshot] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs: [siOTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs: [siOTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs: [siPUuid] :: SubvolInfo -> Maybe UUID
+ System.Linux.Btrfs: [siParSnapGen] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs: [siRTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs: [siRTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs: [siReadOnly] :: SubvolInfo -> Bool
+ System.Linux.Btrfs: [siReceivedUuid] :: SubvolInfo -> Maybe UUID
+ System.Linux.Btrfs: [siSTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs: [siSTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs: [siUuid] :: SubvolInfo -> Maybe UUID
+ System.Linux.Btrfs: [skMaxObjectId] :: SearchKey -> ObjectId
+ System.Linux.Btrfs: [skMaxOffset] :: SearchKey -> Word64
+ System.Linux.Btrfs: [skMaxTransId] :: SearchKey -> Word64
+ System.Linux.Btrfs: [skMaxType] :: SearchKey -> ObjectType
+ System.Linux.Btrfs: [skMinObjectId] :: SearchKey -> ObjectId
+ System.Linux.Btrfs: [skMinOffset] :: SearchKey -> Word64
+ System.Linux.Btrfs: [skMinTransId] :: SearchKey -> Word64
+ System.Linux.Btrfs: [skMinType] :: SearchKey -> ObjectType
+ System.Linux.Btrfs: [skTreeId] :: SearchKey -> ObjectId
+ System.Linux.Btrfs: instance Foreign.Storable.Storable System.Linux.Btrfs.SameExtentInfoIn
+ System.Linux.Btrfs: instance Foreign.Storable.Storable System.Linux.Btrfs.SameExtentInfoOut
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.CloneResult
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.CompressionType
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.DefragRangeArgs
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.SearchHeader
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.SearchKey
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.SubvolInfo
+ System.Linux.Btrfs: instance GHC.Enum.Bounded System.Linux.Btrfs.CompressionType
+ System.Linux.Btrfs: instance GHC.Enum.Enum System.Linux.Btrfs.CompressionType
+ System.Linux.Btrfs: instance GHC.Read.Read System.Linux.Btrfs.CompressionType
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.CloneResult
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.CompressionType
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.DefragRangeArgs
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.SearchHeader
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.SearchKey
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.SubvolInfo
+ System.Linux.Btrfs.ByteString: [draCompress] :: DefragRangeArgs -> Maybe CompressionType
+ System.Linux.Btrfs.ByteString: [draExtentThreshold] :: DefragRangeArgs -> Word32
+ System.Linux.Btrfs.ByteString: [draFlush] :: DefragRangeArgs -> Bool
+ System.Linux.Btrfs.ByteString: [draLength] :: DefragRangeArgs -> FileSize
+ System.Linux.Btrfs.ByteString: [draStart] :: DefragRangeArgs -> FileSize
+ System.Linux.Btrfs.ByteString: [shLen] :: SearchHeader -> Word32
+ System.Linux.Btrfs.ByteString: [shObjectId] :: SearchHeader -> ObjectId
+ System.Linux.Btrfs.ByteString: [shOffset] :: SearchHeader -> Word64
+ System.Linux.Btrfs.ByteString: [shTransId] :: SearchHeader -> Word64
+ System.Linux.Btrfs.ByteString: [shType] :: SearchHeader -> ObjectType
+ System.Linux.Btrfs.ByteString: [siCTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs.ByteString: [siCTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs.ByteString: [siGeneration] :: SubvolInfo -> Word64
+ System.Linux.Btrfs.ByteString: [siLastSnapshot] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs.ByteString: [siOTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs.ByteString: [siOTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs.ByteString: [siPUuid] :: SubvolInfo -> Maybe UUID
+ System.Linux.Btrfs.ByteString: [siParSnapGen] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs.ByteString: [siRTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs.ByteString: [siRTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs.ByteString: [siReadOnly] :: SubvolInfo -> Bool
+ System.Linux.Btrfs.ByteString: [siReceivedUuid] :: SubvolInfo -> Maybe UUID
+ System.Linux.Btrfs.ByteString: [siSTime] :: SubvolInfo -> Maybe UTCTime
+ System.Linux.Btrfs.ByteString: [siSTransId] :: SubvolInfo -> Maybe Word64
+ System.Linux.Btrfs.ByteString: [siUuid] :: SubvolInfo -> Maybe UUID
+ System.Linux.Btrfs.ByteString: [skMaxObjectId] :: SearchKey -> ObjectId
+ System.Linux.Btrfs.ByteString: [skMaxOffset] :: SearchKey -> Word64
+ System.Linux.Btrfs.ByteString: [skMaxTransId] :: SearchKey -> Word64
+ System.Linux.Btrfs.ByteString: [skMaxType] :: SearchKey -> ObjectType
+ System.Linux.Btrfs.ByteString: [skMinObjectId] :: SearchKey -> ObjectId
+ System.Linux.Btrfs.ByteString: [skMinOffset] :: SearchKey -> Word64
+ System.Linux.Btrfs.ByteString: [skMinTransId] :: SearchKey -> Word64
+ System.Linux.Btrfs.ByteString: [skMinType] :: SearchKey -> ObjectType
+ System.Linux.Btrfs.ByteString: [skTreeId] :: SearchKey -> ObjectId
+ System.Linux.Btrfs.ByteString: instance Foreign.Storable.Storable System.Linux.Btrfs.ByteString.SameExtentInfoIn
+ System.Linux.Btrfs.ByteString: instance Foreign.Storable.Storable System.Linux.Btrfs.ByteString.SameExtentInfoOut
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.CloneResult
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.CompressionType
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.DefragRangeArgs
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.SearchHeader
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.SearchKey
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.SubvolInfo
+ System.Linux.Btrfs.ByteString: instance GHC.Enum.Bounded System.Linux.Btrfs.ByteString.CompressionType
+ System.Linux.Btrfs.ByteString: instance GHC.Enum.Enum System.Linux.Btrfs.ByteString.CompressionType
+ System.Linux.Btrfs.ByteString: instance GHC.Read.Read System.Linux.Btrfs.ByteString.CompressionType
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.CloneResult
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.CompressionType
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.DefragRangeArgs
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.SearchHeader
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.SearchKey
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.SubvolInfo
+ System.Linux.Btrfs.Time: BtrfsTime :: UTCTime -> BtrfsTime
+ System.Linux.Btrfs.Time: instance Foreign.Storable.Storable System.Linux.Btrfs.Time.BtrfsTime
+ System.Linux.Btrfs.Time: newtype BtrfsTime
+ System.Linux.Btrfs.UUID: instance Foreign.Storable.Storable System.Linux.Btrfs.UUID.UUID
+ System.Linux.Btrfs.UUID: instance GHC.Classes.Eq System.Linux.Btrfs.UUID.UUID
+ System.Linux.Btrfs.UUID: instance GHC.Classes.Ord System.Linux.Btrfs.UUID.UUID
+ System.Linux.Btrfs.UUID: instance GHC.Show.Show System.Linux.Btrfs.UUID.UUID

Files

ChangeLog view
@@ -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.
Data/Word/Endian.hs view
@@ -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
System/Linux/Btrfs.hsc view
@@ -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> 
System/Linux/Btrfs/ByteString.hsc view
@@ -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> 
btrfs.cabal view
@@ -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
examples/btrfs-defrag.hs view
@@ -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")
+ examples/btrfs-print-creation-time.hsc view
@@ -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
include/btrfs/ctree.h view
@@ -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
include/btrfs/extent-cache.h view
@@ -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
include/btrfs/extent_io.h view
@@ -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,
include/btrfs/ioctl.h view
@@ -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, \
include/btrfs/kerncompat.h view
@@ -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
include/btrfs/rbtree.h view
@@ -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 */
− include/missing.h
@@ -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