packages feed

btrfs 0.1.2.3 → 0.2.0.0

raw patch · 14 files changed

+988/−321 lines, 14 filesdep ~basedep ~unixnew-component:exe:btrfs-joinPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, unix

API changes (from Hackage documentation)

- System.Linux.Btrfs: LZO :: CompressionType
- System.Linux.Btrfs: Zlib :: CompressionType
- 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.ByteString: LZO :: CompressionType
- System.Linux.Btrfs.ByteString: Zlib :: CompressionType
- 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: compressLZO :: CompressionType
+ System.Linux.Btrfs: compressNone :: CompressionType
+ System.Linux.Btrfs: compressZlib :: CompressionType
+ System.Linux.Btrfs: compressZstd :: CompressionType
+ System.Linux.Btrfs: data FSInfo
+ System.Linux.Btrfs: fsiCloneAlignment :: FSInfo -> FileSize
+ System.Linux.Btrfs: fsiDeviceCount :: FSInfo -> Word64
+ System.Linux.Btrfs: fsiNodeSize :: FSInfo -> FileSize
+ System.Linux.Btrfs: fsiSectorSize :: FSInfo -> FileSize
+ System.Linux.Btrfs: fsiUuid :: FSInfo -> UUID
+ System.Linux.Btrfs: getFSInfo :: FilePath -> IO FSInfo
+ System.Linux.Btrfs: getFSInfoFd :: Fd -> IO FSInfo
+ System.Linux.Btrfs: getFSLabel :: FilePath -> IO FilePath
+ System.Linux.Btrfs: getFSLabelFd :: Fd -> IO FilePath
+ System.Linux.Btrfs: instance GHC.Classes.Eq System.Linux.Btrfs.FSInfo
+ System.Linux.Btrfs: instance GHC.Show.Show System.Linux.Btrfs.FSInfo
+ System.Linux.Btrfs: setFSLabel :: FilePath -> FilePath -> IO ()
+ System.Linux.Btrfs: setFSLabelFd :: Fd -> FilePath -> IO ()
+ System.Linux.Btrfs.ByteString: compressLZO :: CompressionType
+ System.Linux.Btrfs.ByteString: compressNone :: CompressionType
+ System.Linux.Btrfs.ByteString: compressZlib :: CompressionType
+ System.Linux.Btrfs.ByteString: compressZstd :: CompressionType
+ System.Linux.Btrfs.ByteString: data FSInfo
+ System.Linux.Btrfs.ByteString: fsiCloneAlignment :: FSInfo -> FileSize
+ System.Linux.Btrfs.ByteString: fsiDeviceCount :: FSInfo -> Word64
+ System.Linux.Btrfs.ByteString: fsiNodeSize :: FSInfo -> FileSize
+ System.Linux.Btrfs.ByteString: fsiSectorSize :: FSInfo -> FileSize
+ System.Linux.Btrfs.ByteString: fsiUuid :: FSInfo -> UUID
+ System.Linux.Btrfs.ByteString: getFSInfo :: RawFilePath -> IO FSInfo
+ System.Linux.Btrfs.ByteString: getFSInfoFd :: Fd -> IO FSInfo
+ System.Linux.Btrfs.ByteString: getFSLabel :: RawFilePath -> IO RawFilePath
+ System.Linux.Btrfs.ByteString: getFSLabelFd :: Fd -> IO RawFilePath
+ System.Linux.Btrfs.ByteString: instance GHC.Classes.Eq System.Linux.Btrfs.ByteString.FSInfo
+ System.Linux.Btrfs.ByteString: instance GHC.Show.Show System.Linux.Btrfs.ByteString.FSInfo
+ System.Linux.Btrfs.ByteString: setFSLabel :: RawFilePath -> RawFilePath -> IO ()
+ System.Linux.Btrfs.ByteString: setFSLabelFd :: Fd -> RawFilePath -> IO ()
- System.Linux.Btrfs: DefragRangeArgs :: FileSize -> FileSize -> Word32 -> Maybe CompressionType -> Bool -> DefragRangeArgs
+ System.Linux.Btrfs: DefragRangeArgs :: FileSize -> FileSize -> Word32 -> CompressionType -> Bool -> DefragRangeArgs
- System.Linux.Btrfs: [draCompress] :: DefragRangeArgs -> Maybe CompressionType
+ System.Linux.Btrfs: [draCompress] :: DefragRangeArgs -> CompressionType
- System.Linux.Btrfs.ByteString: DefragRangeArgs :: FileSize -> FileSize -> Word32 -> Maybe CompressionType -> Bool -> DefragRangeArgs
+ System.Linux.Btrfs.ByteString: DefragRangeArgs :: FileSize -> FileSize -> Word32 -> CompressionType -> Bool -> DefragRangeArgs
- System.Linux.Btrfs.ByteString: [draCompress] :: DefragRangeArgs -> Maybe CompressionType
+ System.Linux.Btrfs.ByteString: [draCompress] :: DefragRangeArgs -> CompressionType

Files

− ChangeLog
@@ -1,26 +0,0 @@-v0.1.2.3--	* System.Linux.Btrfs.UUID.fromString did not handle all malformed-	UUIDs correctly.--v0.1.2.2--	* Fix compilation error when libcap is not installed.--v0.1.2.1--	* Support cloneRangeIfSame on read-only subvolumes (requires-	CAP_SYS_ADMIN).--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.--v0.1.1.0--	* Support defraging file ranges.
+ ChangeLog.md view
@@ -0,0 +1,40 @@+#### 0.2.0.0 *2018-10-25*++	* Implement getFSInfo.+	* Remove an ugly hack that was used to block signals while defrag was running.+	* Support Zstd compression.+	* Make CompressionType abstract.+	* Fix handling of filenames that are not valid according to the current locale.+	* Deprecate System.Linux.Btrfs.ByteString.+	* Support getting/setting file system labels.++#### 0.1.2.3 *2017-01-30*++	* System.Linux.Btrfs.UUID.fromString did not handle all malformed+	UUIDs correctly.++#### 0.1.2.2 *2016-11-15*++	* Fix compilation error when libcap is not installed.++#### 0.1.2.1 *2016-11-13*++	* Support cloneRangeIfSame on read-only subvolumes (requires+	CAP_SYS_ADMIN).++#### 0.1.2.0 *2016-02-23*++	* Expose System.Linux.Btrfs.Time.+	* Add example program that prints the file creation timestamp.++#### 0.1.1.1 *2014-10-05*++	* Support getting/setting the id of the default subvolume.++#### 0.1.1.0 *2014-10-05*++	* Support defraging file ranges.++#### 0.1.0.0 *2014-09-01*++	* Initial public release.
System/Linux/Btrfs.hsc view
@@ -16,13 +16,18 @@ #if BTRFS_RAW_PATHS ##define FILEPATH RawFilePath module System.Linux.Btrfs.ByteString+{-# DEPRECATED "This module is deprecated and will be removed in a\+ future version of this library. Please leave a comment on\+ https://github.com/redneb/hs-btrfs/issues/5 if you think that is\+ should not be removed." #-} #else ##define FILEPATH FilePath module System.Linux.Btrfs #endif     (     -- * Basic types-      FileSize, ObjectType, ObjectId, InodeNum, SubvolId, CompressionType(..)+      FileSize, ObjectType, ObjectId, InodeNum, SubvolId+    , CompressionType, compressNone, compressZlib, compressLZO, compressZstd     -- * File cloning/deduplication     , cloneFd, clone, cloneNew     , cloneRangeFd, cloneRange@@ -48,10 +53,26 @@     , getSubvolByReceivedUuidFd, getSubvolByReceivedUuid     , getDefaultSubvolFd, getDefaultSubvol     , setDefaultSubvolFd, setDefaultSubvol-    -- * Defragging+    -- * Defrag+    -- | There is a limitation in the kernel whereby a defrag operation+    -- will be silently aborted when the calling process receives any+    -- signal. This does not play well with GHC's rts which in some+    -- cases uses signals as a way to preempt haskell threads. So in order+    -- to use 'defrag' or 'defragRange', you must compile your program with+    -- GHC >=8.2 and the use the threaded runtime which does not use+    -- signals anymore. Alternatively, for older versions of GHC, you can+    -- use something like the @withRTSSignalsBlocked@ function from+    -- <http://www.serpentine.com/blog/2010/09/04/dealing-with-fragile-c-libraries-e-g-mysql-from-haskell/ here>.     , defragFd, defrag     , DefragRangeArgs(..), defaultDefragRangeArgs     , defragRangeFd, defragRange+    -- * File system info+    , FSInfo+    , fsiDeviceCount, fsiUuid, fsiNodeSize, fsiSectorSize, fsiCloneAlignment+    , getFSInfoFd, getFSInfo+    -- * File system label+    , getFSLabelFd, getFSLabel+    , setFSLabelFd, setFSLabel     -- * Sync     , syncFd, sync     , startSyncFd, startSync@@ -77,7 +98,6 @@ import System.Posix.Types import System.Posix.IO hiding (openFd) import System.Posix.Files-import System.Posix.Signals import System.IO.Error import Control.Exception import Control.Monad@@ -117,9 +137,23 @@  type SubvolId = ObjectId -data CompressionType = Zlib | LZO-    deriving (Show, Read, Eq, Enum, Bounded)+newtype CompressionType = CompressionType Word32+    deriving Eq +instance Show CompressionType where+    show t+        | t == compressNone = "compressNone"+        | t == compressZlib = "compressZlib"+        | t == compressLZO  = "compressLZO"+        | t == compressZstd = "compressZstd"+        | otherwise = error "unknown compression type"++compressNone, compressZlib, compressLZO, compressZstd :: CompressionType+compressNone = CompressionType (#const BTRFS_COMPRESS_NONE)+compressZlib = CompressionType (#const BTRFS_COMPRESS_ZLIB)+compressLZO  = CompressionType (#const BTRFS_COMPRESS_LZO)+compressZstd = CompressionType (#const BTRFS_COMPRESS_ZSTD)+ --------------------------------------------------------------------------------  cloneFd :: Fd -> Fd -> IO ()@@ -164,7 +198,8 @@             ioctl_fast dstFd (#const BTRFS_IOC_CLONE_RANGE) cra  -- | Clones a range of bytes from a file to another file. All ranges must--- be block-aligned.+-- be block-aligned (the block size can be obtained using 'getFSInfo' and+-- 'fsiCloneAlignment'). -- -- Note: calls the @BTRFS_IOC_CLONE_RANGE@/@FICLONERANGE@ @ioctl@. cloneRange@@ -697,7 +732,7 @@     l <- treeSearchListFd fd sk $ \_ ptr -> do         LE16 nameLen <- (#peek struct btrfs_dir_item, name_len) ptr         let cName = ptr `plusPtr` (#size struct btrfs_dir_item)-        name <- peekCStringLen (cName, fromIntegral nameLen)+        name <- peekFilePathLen (cName, fromIntegral nameLen)         if name /= "default" then             return Nothing         else do@@ -737,8 +772,7 @@ defragFd :: Fd -> IO () defragFd fd =     throwErrnoIfMinus1_ "defragFd" $-        withBlockSIGVTALRM $ -- this is probably a bad idea-            ioctl fd (#const BTRFS_IOC_DEFRAG) nullPtr+        ioctl fd (#const BTRFS_IOC_DEFRAG) nullPtr  -- | Defrag a single file. --@@ -755,7 +789,7 @@     , draExtentThreshold :: Word32         -- ^ Any extent of size bigger or equal to this number will be         -- considered already defragged. Use 0 for the kernel default.-    , draCompress :: Maybe CompressionType+    , draCompress :: CompressionType         -- ^ Compress the file while defragmenting.     , draFlush :: Bool         -- ^ Flush data to disk immediately after defragmenting.@@ -769,7 +803,7 @@     { draStart = 0     , draLength = maxBound     , draExtentThreshold = 0-    , draCompress = Nothing+    , draCompress = compressNone     , draFlush = False     } @@ -782,17 +816,14 @@         (#poke struct btrfs_ioctl_defrag_range_args, extent_thresh) args draExtentThreshold         (#poke struct btrfs_ioctl_defrag_range_args, compress_type) args comp_type         throwErrnoIfMinus1_ "defragRangeFd" $-            withBlockSIGVTALRM $ -- this is probably a bad idea-                ioctl fd (#const BTRFS_IOC_DEFRAG_RANGE) args+            ioctl fd (#const BTRFS_IOC_DEFRAG_RANGE) args   where+    flags :: Word64     flags = comp_flags .|. if draFlush then (#const BTRFS_DEFRAG_RANGE_START_IO) else 0-    comp_flags :: Word64-    comp_type :: Word32-    (comp_flags, comp_type) =-        case draCompress of-            Nothing -> (0, 0)-            Just Zlib -> ((#const BTRFS_DEFRAG_RANGE_COMPRESS), (#const BTRFS_COMPRESS_ZLIB))-            Just LZO  -> ((#const BTRFS_DEFRAG_RANGE_COMPRESS), (#const BTRFS_COMPRESS_LZO))+    comp_flags+        | draCompress == compressNone = 0+        | otherwise = (#const BTRFS_DEFRAG_RANGE_COMPRESS)+    CompressionType comp_type = draCompress  -- | Defrag a range within a single file. --@@ -804,6 +835,93 @@  -------------------------------------------------------------------------------- +-- | Information about a btrfs file system.+data FSInfo = FSInfo+    { fsiDeviceCount :: Word64+        -- ^ The number of devices in the file system.+    , fsiUuid :: UUID+        -- ^ The UUID of the file system.+    , fsiNodeSize :: FileSize+        -- ^ The tree block size in which metadata is stored.+    , fsiSectorSize :: FileSize+        -- ^ The minimum data block allocation unit.+    , fsiCloneAlignment :: FileSize+        -- ^ The size that is used for the alignment constraints of clone+        -- range operations.+    }+  deriving (Show, Eq)++getFSInfoFd :: Fd -> IO FSInfo+getFSInfoFd fd =+    allocaBytes (#size struct btrfs_ioctl_fs_info_args) $ \fsia -> do+        throwErrnoIfMinus1_ "getFSInfoFd" $+            ioctl_fast fd (#const BTRFS_IOC_FS_INFO) fsia+        nd <- (#peek struct btrfs_ioctl_fs_info_args, num_devices) fsia :: IO Word64+        uuid <- (#peek struct btrfs_ioctl_fs_info_args, fsid) fsia :: IO UUID+        ns <- (#peek struct btrfs_ioctl_fs_info_args, nodesize) fsia :: IO Word32+        ss <- (#peek struct btrfs_ioctl_fs_info_args, sectorsize) fsia :: IO Word32+        ca <- (#peek struct btrfs_ioctl_fs_info_args, clone_alignment) fsia :: IO Word32+        return FSInfo+            { fsiDeviceCount = nd+            , fsiUuid = uuid+            , fsiNodeSize = fromIntegral ns+            , fsiSectorSize = fromIntegral ss+            , fsiCloneAlignment = fromIntegral ca+            }++-- | Retrieve information about a btrfs file system.+--+-- Note: calls the @BTRFS_IOC_FS_INFO@ @ioctl@.+getFSInfo+    :: FILEPATH -- ^ The mount point of the volume (or any file in that volume).+    -> IO FSInfo+getFSInfo path =+    withFd path ReadOnly getFSInfoFd++--------------------------------------------------------------------------------++getFSLabelFd :: Fd -> IO FILEPATH+getFSLabelFd fd =+    allocaBytesZero maxLabelSize $ \ptr -> do+        throwErrnoIfMinus1_ "getFSLabelFd" $+            ioctl_fast fd (#const BTRFS_IOC_GET_FSLABEL) ptr+        peekFilePath ptr++-- | Retrieve the label of a btrfs file system.+--+-- Note: calls the @BTRFS_IOC_GET_FSLABEL@ @ioctl@.+getFSLabel+    :: FILEPATH -- ^ The mount point of the volume (or any file in that volume).+    -> IO FILEPATH+getFSLabel path =+    withFd path ReadOnly getFSLabelFd++setFSLabelFd :: Fd -> FILEPATH -> IO ()+setFSLabelFd fd label =+    withFilePathLen label $ \(ptr, len) ->+        allocaBytesZero maxLabelSize $ \buf -> do+            copyArray buf ptr (min len (maxLabelSize - 1))+            throwErrnoIfMinus1_ "setFSLabelFd" $+                ioctl fd (#const BTRFS_IOC_SET_FSLABEL) buf++-- | Set the label of a btrfs file system. Note that a label can be up to+-- 255 /bytes/ long. If the provided label is longer, it will be silently+-- truncated.+--+-- Note: calls the @BTRFS_IOC_SET_FSLABEL@ @ioctl@.+setFSLabel+    :: FILEPATH -- ^ The mount point of the volume (or any file in that volume).+    -> FILEPATH -- ^ The new label.+    -> IO ()+setFSLabel path label =+    withFd path ReadOnly $ \fd ->+        setFSLabelFd fd label++maxLabelSize :: Int+maxLabelSize = (#const BTRFS_LABEL_SIZE)++--------------------------------------------------------------------------------+ syncFd :: Fd -> IO () syncFd fd =     throwErrnoIfMinus1_ "syncFd" $@@ -888,7 +1006,7 @@         count      <- (#peek struct btrfs_data_container, elem_cnt   ) fspath :: IO Word32         let val = (#ptr struct btrfs_data_container, val) fspath :: Ptr Word64         vals <- peekArray (fromIntegral count) val-        paths <- mapM (peekCString . plusPtr val . fromIntegral) vals+        paths <- mapM (peekFilePath . plusPtr val . fromIntegral) vals         return (paths, fromIntegral elemMissed)   where     fspathSize = 2 * 1024 + (#size struct btrfs_data_container)@@ -917,7 +1035,7 @@             ioctl_fast fd (#const BTRFS_IOC_INO_LOOKUP) ila         treeId' <- (#peek struct btrfs_ioctl_ino_lookup_args, treeid) ila :: IO Word64         let cName = (#ptr struct btrfs_ioctl_ino_lookup_args, name) ila-        name <- peekCString cName+        name <- peekFilePath cName         return (treeId', dropTrailingSlash name)  -- | Find the path of a file given its inode number and the id of the@@ -1122,7 +1240,7 @@     LE64 dirId   <- (#peek struct btrfs_root_ref, dirid   ) rrPtr     LE16 nameLen <- (#peek struct btrfs_root_ref, name_len) rrPtr     let cName = rrPtr `plusPtr` (#size struct btrfs_root_ref)-    name <- peekCStringLen (cName, fromIntegral nameLen)+    name <- peekFilePathLen (cName, fromIntegral nameLen)     return (dirId, name)  --------------------------------------------------------------------------------@@ -1134,19 +1252,13 @@  withSplitPathOpenParent :: String -> Int -> FILEPATH -> (CStringLen -> Fd -> IO r) -> IO r withSplitPathOpenParent loc maxLen path action =-    unsafeWithCStringLen name $ \cName @ (_, l) -> do+    unsafeWithFilePathLen name $ \cName @ (_, l) -> do         unless (l <= maxLen) $             ioError $ flip ioeSetErrorString "the subvolume name is too long"                     $ mkIOError illegalOperationErrorType loc Nothing (Just (asString name))         withFd dir ReadOnly $ action cName   where     (dir, name) = splitFileName (dropTrailingSlash path)--withBlockSIGVTALRM :: IO a -> IO a-withBlockSIGVTALRM =-    bracket_ (blockSignals s) (unblockSignals s)-  where-    s = addSignal sigVTALRM emptySignalSet  nothingIf :: Bool -> a -> Maybe a nothingIf f v = if f then Nothing else Just v
System/Linux/Btrfs/ByteString.hsc view
@@ -16,13 +16,18 @@ #if BTRFS_RAW_PATHS ##define FILEPATH RawFilePath module System.Linux.Btrfs.ByteString+{-# DEPRECATED "This module is deprecated and will be removed in a\+ future version of this library. Please leave a comment on\+ https://github.com/redneb/hs-btrfs/issues/5 if you think that is\+ should not be removed." #-} #else ##define FILEPATH FilePath module System.Linux.Btrfs #endif     (     -- * Basic types-      FileSize, ObjectType, ObjectId, InodeNum, SubvolId, CompressionType(..)+      FileSize, ObjectType, ObjectId, InodeNum, SubvolId+    , CompressionType, compressNone, compressZlib, compressLZO, compressZstd     -- * File cloning/deduplication     , cloneFd, clone, cloneNew     , cloneRangeFd, cloneRange@@ -48,10 +53,26 @@     , getSubvolByReceivedUuidFd, getSubvolByReceivedUuid     , getDefaultSubvolFd, getDefaultSubvol     , setDefaultSubvolFd, setDefaultSubvol-    -- * Defragging+    -- * Defrag+    -- | There is a limitation in the kernel whereby a defrag operation+    -- will be silently aborted when the calling process receives any+    -- signal. This does not play well with GHC's rts which in some+    -- cases uses signals as a way to preempt haskell threads. So in order+    -- to use 'defrag' or 'defragRange', you must compile your program with+    -- GHC >=8.2 and the use the threaded runtime which does not use+    -- signals anymore. Alternatively, for older versions of GHC, you can+    -- use something like the @withRTSSignalsBlocked@ function from+    -- <http://www.serpentine.com/blog/2010/09/04/dealing-with-fragile-c-libraries-e-g-mysql-from-haskell/ here>.     , defragFd, defrag     , DefragRangeArgs(..), defaultDefragRangeArgs     , defragRangeFd, defragRange+    -- * File system info+    , FSInfo+    , fsiDeviceCount, fsiUuid, fsiNodeSize, fsiSectorSize, fsiCloneAlignment+    , getFSInfoFd, getFSInfo+    -- * File system label+    , getFSLabelFd, getFSLabel+    , setFSLabelFd, setFSLabel     -- * Sync     , syncFd, sync     , startSyncFd, startSync@@ -77,7 +98,6 @@ import System.Posix.Types import System.Posix.IO hiding (openFd) import System.Posix.Files-import System.Posix.Signals import System.IO.Error import Control.Exception import Control.Monad@@ -117,9 +137,23 @@  type SubvolId = ObjectId -data CompressionType = Zlib | LZO-    deriving (Show, Read, Eq, Enum, Bounded)+newtype CompressionType = CompressionType Word32+    deriving Eq +instance Show CompressionType where+    show t+        | t == compressNone = "compressNone"+        | t == compressZlib = "compressZlib"+        | t == compressLZO  = "compressLZO"+        | t == compressZstd = "compressZstd"+        | otherwise = error "unknown compression type"++compressNone, compressZlib, compressLZO, compressZstd :: CompressionType+compressNone = CompressionType (#const BTRFS_COMPRESS_NONE)+compressZlib = CompressionType (#const BTRFS_COMPRESS_ZLIB)+compressLZO  = CompressionType (#const BTRFS_COMPRESS_LZO)+compressZstd = CompressionType (#const BTRFS_COMPRESS_ZSTD)+ --------------------------------------------------------------------------------  cloneFd :: Fd -> Fd -> IO ()@@ -164,7 +198,8 @@             ioctl_fast dstFd (#const BTRFS_IOC_CLONE_RANGE) cra  -- | Clones a range of bytes from a file to another file. All ranges must--- be block-aligned.+-- be block-aligned (the block size can be obtained using 'getFSInfo' and+-- 'fsiCloneAlignment'). -- -- Note: calls the @BTRFS_IOC_CLONE_RANGE@/@FICLONERANGE@ @ioctl@. cloneRange@@ -697,7 +732,7 @@     l <- treeSearchListFd fd sk $ \_ ptr -> do         LE16 nameLen <- (#peek struct btrfs_dir_item, name_len) ptr         let cName = ptr `plusPtr` (#size struct btrfs_dir_item)-        name <- peekCStringLen (cName, fromIntegral nameLen)+        name <- peekFilePathLen (cName, fromIntegral nameLen)         if name /= "default" then             return Nothing         else do@@ -737,8 +772,7 @@ defragFd :: Fd -> IO () defragFd fd =     throwErrnoIfMinus1_ "defragFd" $-        withBlockSIGVTALRM $ -- this is probably a bad idea-            ioctl fd (#const BTRFS_IOC_DEFRAG) nullPtr+        ioctl fd (#const BTRFS_IOC_DEFRAG) nullPtr  -- | Defrag a single file. --@@ -755,7 +789,7 @@     , draExtentThreshold :: Word32         -- ^ Any extent of size bigger or equal to this number will be         -- considered already defragged. Use 0 for the kernel default.-    , draCompress :: Maybe CompressionType+    , draCompress :: CompressionType         -- ^ Compress the file while defragmenting.     , draFlush :: Bool         -- ^ Flush data to disk immediately after defragmenting.@@ -769,7 +803,7 @@     { draStart = 0     , draLength = maxBound     , draExtentThreshold = 0-    , draCompress = Nothing+    , draCompress = compressNone     , draFlush = False     } @@ -782,17 +816,14 @@         (#poke struct btrfs_ioctl_defrag_range_args, extent_thresh) args draExtentThreshold         (#poke struct btrfs_ioctl_defrag_range_args, compress_type) args comp_type         throwErrnoIfMinus1_ "defragRangeFd" $-            withBlockSIGVTALRM $ -- this is probably a bad idea-                ioctl fd (#const BTRFS_IOC_DEFRAG_RANGE) args+            ioctl fd (#const BTRFS_IOC_DEFRAG_RANGE) args   where+    flags :: Word64     flags = comp_flags .|. if draFlush then (#const BTRFS_DEFRAG_RANGE_START_IO) else 0-    comp_flags :: Word64-    comp_type :: Word32-    (comp_flags, comp_type) =-        case draCompress of-            Nothing -> (0, 0)-            Just Zlib -> ((#const BTRFS_DEFRAG_RANGE_COMPRESS), (#const BTRFS_COMPRESS_ZLIB))-            Just LZO  -> ((#const BTRFS_DEFRAG_RANGE_COMPRESS), (#const BTRFS_COMPRESS_LZO))+    comp_flags+        | draCompress == compressNone = 0+        | otherwise = (#const BTRFS_DEFRAG_RANGE_COMPRESS)+    CompressionType comp_type = draCompress  -- | Defrag a range within a single file. --@@ -804,6 +835,93 @@  -------------------------------------------------------------------------------- +-- | Information about a btrfs file system.+data FSInfo = FSInfo+    { fsiDeviceCount :: Word64+        -- ^ The number of devices in the file system.+    , fsiUuid :: UUID+        -- ^ The UUID of the file system.+    , fsiNodeSize :: FileSize+        -- ^ The tree block size in which metadata is stored.+    , fsiSectorSize :: FileSize+        -- ^ The minimum data block allocation unit.+    , fsiCloneAlignment :: FileSize+        -- ^ The size that is used for the alignment constraints of clone+        -- range operations.+    }+  deriving (Show, Eq)++getFSInfoFd :: Fd -> IO FSInfo+getFSInfoFd fd =+    allocaBytes (#size struct btrfs_ioctl_fs_info_args) $ \fsia -> do+        throwErrnoIfMinus1_ "getFSInfoFd" $+            ioctl_fast fd (#const BTRFS_IOC_FS_INFO) fsia+        nd <- (#peek struct btrfs_ioctl_fs_info_args, num_devices) fsia :: IO Word64+        uuid <- (#peek struct btrfs_ioctl_fs_info_args, fsid) fsia :: IO UUID+        ns <- (#peek struct btrfs_ioctl_fs_info_args, nodesize) fsia :: IO Word32+        ss <- (#peek struct btrfs_ioctl_fs_info_args, sectorsize) fsia :: IO Word32+        ca <- (#peek struct btrfs_ioctl_fs_info_args, clone_alignment) fsia :: IO Word32+        return FSInfo+            { fsiDeviceCount = nd+            , fsiUuid = uuid+            , fsiNodeSize = fromIntegral ns+            , fsiSectorSize = fromIntegral ss+            , fsiCloneAlignment = fromIntegral ca+            }++-- | Retrieve information about a btrfs file system.+--+-- Note: calls the @BTRFS_IOC_FS_INFO@ @ioctl@.+getFSInfo+    :: FILEPATH -- ^ The mount point of the volume (or any file in that volume).+    -> IO FSInfo+getFSInfo path =+    withFd path ReadOnly getFSInfoFd++--------------------------------------------------------------------------------++getFSLabelFd :: Fd -> IO FILEPATH+getFSLabelFd fd =+    allocaBytesZero maxLabelSize $ \ptr -> do+        throwErrnoIfMinus1_ "getFSLabelFd" $+            ioctl_fast fd (#const BTRFS_IOC_GET_FSLABEL) ptr+        peekFilePath ptr++-- | Retrieve the label of a btrfs file system.+--+-- Note: calls the @BTRFS_IOC_GET_FSLABEL@ @ioctl@.+getFSLabel+    :: FILEPATH -- ^ The mount point of the volume (or any file in that volume).+    -> IO FILEPATH+getFSLabel path =+    withFd path ReadOnly getFSLabelFd++setFSLabelFd :: Fd -> FILEPATH -> IO ()+setFSLabelFd fd label =+    withFilePathLen label $ \(ptr, len) ->+        allocaBytesZero maxLabelSize $ \buf -> do+            copyArray buf ptr (min len (maxLabelSize - 1))+            throwErrnoIfMinus1_ "setFSLabelFd" $+                ioctl fd (#const BTRFS_IOC_SET_FSLABEL) buf++-- | Set the label of a btrfs file system. Note that a label can be up to+-- 255 /bytes/ long. If the provided label is longer, it will be silently+-- truncated.+--+-- Note: calls the @BTRFS_IOC_SET_FSLABEL@ @ioctl@.+setFSLabel+    :: FILEPATH -- ^ The mount point of the volume (or any file in that volume).+    -> FILEPATH -- ^ The new label.+    -> IO ()+setFSLabel path label =+    withFd path ReadOnly $ \fd ->+        setFSLabelFd fd label++maxLabelSize :: Int+maxLabelSize = (#const BTRFS_LABEL_SIZE)++--------------------------------------------------------------------------------+ syncFd :: Fd -> IO () syncFd fd =     throwErrnoIfMinus1_ "syncFd" $@@ -888,7 +1006,7 @@         count      <- (#peek struct btrfs_data_container, elem_cnt   ) fspath :: IO Word32         let val = (#ptr struct btrfs_data_container, val) fspath :: Ptr Word64         vals <- peekArray (fromIntegral count) val-        paths <- mapM (peekCString . plusPtr val . fromIntegral) vals+        paths <- mapM (peekFilePath . plusPtr val . fromIntegral) vals         return (paths, fromIntegral elemMissed)   where     fspathSize = 2 * 1024 + (#size struct btrfs_data_container)@@ -917,7 +1035,7 @@             ioctl_fast fd (#const BTRFS_IOC_INO_LOOKUP) ila         treeId' <- (#peek struct btrfs_ioctl_ino_lookup_args, treeid) ila :: IO Word64         let cName = (#ptr struct btrfs_ioctl_ino_lookup_args, name) ila-        name <- peekCString cName+        name <- peekFilePath cName         return (treeId', dropTrailingSlash name)  -- | Find the path of a file given its inode number and the id of the@@ -1122,7 +1240,7 @@     LE64 dirId   <- (#peek struct btrfs_root_ref, dirid   ) rrPtr     LE16 nameLen <- (#peek struct btrfs_root_ref, name_len) rrPtr     let cName = rrPtr `plusPtr` (#size struct btrfs_root_ref)-    name <- peekCStringLen (cName, fromIntegral nameLen)+    name <- peekFilePathLen (cName, fromIntegral nameLen)     return (dirId, name)  --------------------------------------------------------------------------------@@ -1134,19 +1252,13 @@  withSplitPathOpenParent :: String -> Int -> FILEPATH -> (CStringLen -> Fd -> IO r) -> IO r withSplitPathOpenParent loc maxLen path action =-    unsafeWithCStringLen name $ \cName @ (_, l) -> do+    unsafeWithFilePathLen name $ \cName @ (_, l) -> do         unless (l <= maxLen) $             ioError $ flip ioeSetErrorString "the subvolume name is too long"                     $ mkIOError illegalOperationErrorType loc Nothing (Just (asString name))         withFd dir ReadOnly $ action cName   where     (dir, name) = splitFileName (dropTrailingSlash path)--withBlockSIGVTALRM :: IO a -> IO a-withBlockSIGVTALRM =-    bracket_ (blockSignals s) (unblockSignals s)-  where-    s = addSignal sigVTALRM emptySignalSet  nothingIf :: Bool -> a -> Maybe a nothingIf f v = if f then Nothing else Just v
System/Linux/Btrfs/FilePathLike.hs view
@@ -7,29 +7,29 @@  import Data.String import Data.Monoid-import Data.List-import Foreign.C.String hiding-    ( peekCString, peekCStringLen-    , newCString, newCStringLen-    , withCString, withCStringLen)-import qualified Foreign.C.String as S+import Data.List (dropWhileEnd)+import Foreign.C.String (CString, CStringLen)+import qualified System.Posix.Internals as P+import GHC.IO.Encoding (getFileSystemEncoding)+import qualified GHC.Foreign as GHC import qualified Data.ByteString as B import qualified Data.ByteString.Unsafe as B import qualified Data.ByteString.Char8 as B8-import System.Posix.Types+import System.Posix.Types (Fd, FileMode) import System.Posix.IO hiding (openFd) import System.Posix.ByteString.FilePath (RawFilePath) import qualified System.Posix.IO as S (openFd) import qualified System.Posix.IO.ByteString as B (openFd) import System.IO.Unsafe (unsafePerformIO)+import Prelude  class (Monoid s, IsString s) => FilePathLike s where     asString :: s -> String-    peekCString :: CString -> IO s-    peekCStringLen :: CStringLen -> IO s-    withCString :: s -> (CString -> IO a) -> IO a -    withCStringLen :: s -> (CStringLen -> IO a) -> IO a -    unsafeWithCStringLen :: s -> (CStringLen -> IO a) -> IO a +    peekFilePath :: CString -> IO s+    peekFilePathLen :: CStringLen -> IO s+    withFilePath :: s -> (CString -> IO a) -> IO a+    withFilePathLen :: s -> (CStringLen -> IO a) -> IO a+    unsafeWithFilePathLen :: s -> (CStringLen -> IO a) -> IO a     openFd :: s -> OpenMode -> Maybe FileMode -> OpenFileFlags -> IO Fd     dropTrailingSlash :: s -> s     (</>) :: s -> s -> s@@ -37,11 +37,13 @@  instance FilePathLike [Char] where     asString = id-    peekCString = S.peekCString-    peekCStringLen = S.peekCStringLen-    withCString = S.withCString-    withCStringLen = S.withCStringLen-    unsafeWithCStringLen = withCStringLen+    peekFilePath = P.peekFilePath+    peekFilePathLen = P.peekFilePathLen+    withFilePath = P.withFilePath+    withFilePathLen path action =+        getFileSystemEncoding >>= \enc ->+            GHC.withCStringLen enc path action+    unsafeWithFilePathLen = withFilePathLen     openFd = S.openFd     dropTrailingSlash s = if null s' then "/" else s'       where@@ -58,11 +60,11 @@  instance FilePathLike B.ByteString where     asString = convert-    peekCString = B.packCString-    peekCStringLen = B.packCStringLen-    withCString = B.useAsCString-    withCStringLen = B.useAsCStringLen-    unsafeWithCStringLen = B.unsafeUseAsCStringLen+    peekFilePath = B.packCString+    peekFilePathLen = B.packCStringLen+    withFilePath = B.useAsCString+    withFilePathLen = B.useAsCStringLen+    unsafeWithFilePathLen = B.unsafeUseAsCStringLen     openFd = B.openFd     dropTrailingSlash s = if B.null s' then slashBS else s'       where@@ -81,7 +83,7 @@         curDir = B8.pack "./"  convert :: (FilePathLike s1, FilePathLike s2) => s1 -> s2-convert s = unsafePerformIO $ unsafeWithCStringLen s peekCStringLen+convert s = unsafePerformIO $ unsafeWithFilePathLen s peekFilePathLen  slashBS :: B.ByteString slashBS = B8.singleton '/'
btrfs.cabal view
@@ -1,5 +1,5 @@ name:                btrfs-version:             0.1.2.3+version:             0.2.0.0 synopsis:            Bindings to the btrfs API description:   This package provides bindings to the low-level btrfs API (i.e. the@@ -23,7 +23,7 @@ cabal-version:       >=1.10  extra-source-files:-  ChangeLog+  ChangeLog.md   include/btrfs/ctree.h   include/btrfs/extent-cache.h   include/btrfs/extent_io.h@@ -32,6 +32,7 @@   include/btrfs/list.h   include/btrfs/radix-tree.h   include/btrfs/rbtree.h+  include/btrfs/sizes.h   include/sys/capability.h   make-bytestring.hs @@ -64,8 +65,8 @@   else     build-depends:       base >=4.6 && <5, btrfs, unix, filepath,                          linux-file-extents, ansi-terminal-    default-language:    Haskell2010-    ghc-options:         -Wall+  default-language:    Haskell2010+  ghc-options:         -Wall -threaded  executable btrfs-clone-range   hs-source-dirs:      examples@@ -74,8 +75,8 @@     buildable:           False   else     build-depends:       base >=4.6 && <5, btrfs-    default-language:    Haskell2010-    ghc-options:         -Wall+  default-language:    Haskell2010+  ghc-options:         -Wall  executable btrfs-split   hs-source-dirs:      examples@@ -84,9 +85,19 @@     buildable:           False   else     build-depends:       base >=4.6 && <5, btrfs, unix-    default-language:    Haskell2010-    ghc-options:         -Wall+  default-language:    Haskell2010+  ghc-options:         -Wall +executable btrfs-join+  hs-source-dirs:      examples+  main-is:             btrfs-join.hs+  if !flag(examples)+    buildable:           False+  else+    build-depends:       base >=4.6 && <5, btrfs, unix+  default-language:    Haskell2010+  ghc-options:         -Wall+ executable btrfs-list-subvols   hs-source-dirs:      examples   main-is:             btrfs-list-subvols.hs@@ -94,8 +105,8 @@     buildable:           False   else     build-depends:       base >=4.6 && <5, btrfs-    default-language:    Haskell2010-    ghc-options:         -Wall+  default-language:    Haskell2010+  ghc-options:         -Wall  executable btrfs-print-creation-time   hs-source-dirs:      examples@@ -105,5 +116,5 @@     buildable:           False   else     build-depends:       base >=4.6 && <5, btrfs, unix >=2.6, time >=1.4-    default-language:    Haskell2010-    ghc-options:         -Wall+  default-language:    Haskell2010+  ghc-options:         -Wall
+ examples/btrfs-join.hs view
@@ -0,0 +1,38 @@+import System.Environment (getArgs, getProgName)+import System.Exit (exitFailure)+import System.IO (stderr, hPutStrLn)+import Control.Exception (bracket)+import System.Posix++import System.Linux.Btrfs (cloneRangeFd)++main :: IO ()+main = do+    args <- getArgs+    case args of+        dstPath : srcFiles0@(_ : _) ->+            withWriteFd dstPath $ \dstFd -> do+                let loop offset (srcFile : srcFiles) = do+                        len <- withReadFd srcFile $ \srcFd -> do+                            cloneRangeFd srcFd 0 0 dstFd offset+                            fileSize <$> getFdStatus srcFd+                        loop (offset + fromIntegral len) srcFiles+                    loop _ [] = return ()+                loop 0 srcFiles0+        _ -> do+            prog <- getProgName+            hPutStrLn stderr "Invalid command line arguments"+            hPutStrLn stderr $ "Usage: " ++ prog ++ " DEST SOURCE [SOURCE]..."+            exitFailure++withReadFd :: FilePath -> (Fd -> IO r) -> IO r+withReadFd path action =+    bracket+        (openFd path ReadOnly Nothing defaultFileFlags {nonBlock = True})+        closeFd action++withWriteFd :: FilePath -> (Fd -> IO r) -> IO r+withWriteFd path action =+    bracket+        (openFd path WriteOnly (Just stdFileMode) defaultFileFlags {trunc = True})+        closeFd action
include/btrfs/ctree.h view
@@ -19,6 +19,8 @@ #ifndef __BTRFS_CTREE_H__ #define __BTRFS_CTREE_H__ +#include <stdbool.h>+ #if BTRFS_FLAT_INCLUDES #include "list.h" #include "kerncompat.h"@@ -26,6 +28,7 @@ #include "extent-cache.h" #include "extent_io.h" #include "ioctl.h"+#include "sizes.h" #else #include <btrfs/list.h> #include <btrfs/kerncompat.h>@@ -33,6 +36,7 @@ #include <btrfs/extent-cache.h> #include <btrfs/extent_io.h> #include <btrfs/ioctl.h>+#include <btrfs/sizes.h> #endif /* BTRFS_FLAT_INCLUDES */  struct btrfs_root;@@ -40,6 +44,14 @@ struct btrfs_free_space_ctl; #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ +/*+ * Fake signature for an unfinalized filesystem, which only has barebone tree+ * structures (normally 6 near empty trees, on SINGLE meta/sys temporary chunks)+ *+ * ascii !BHRfS_M, no null+ */+#define BTRFS_MAGIC_TEMPORARY 0x4D5F536652484221ULL+ #define BTRFS_MAX_MIRRORS 3  #define BTRFS_MAX_LEVEL 8@@ -79,6 +91,9 @@ /* tracks free space in block groups. */ #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL +/* device stats in the device tree */+#define BTRFS_DEV_STATS_OBJECTID 0ULL+ /* for storing balance parameters in the root tree */ #define BTRFS_BALANCE_OBJECTID -4ULL @@ -127,6 +142,8 @@  */ #define BTRFS_DEV_ITEMS_OBJECTID 1ULL +#define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2ULL+ /*  * the max metadata block size.  This limit is somewhat artificial,  * but the memmove costs go through the roof for larger blocks.@@ -152,10 +169,9 @@ /* csum types */ #define BTRFS_CSUM_TYPE_CRC32	0 +/* four bytes for CRC32 */ static int btrfs_csum_sizes[] = { 4 }; -/* four bytes for CRC32 */-#define BTRFS_CRC32_SIZE 4 #define BTRFS_EMPTY_DIR_SIZE 0  #define BTRFS_FT_UNKNOWN	0@@ -341,18 +357,9 @@ 	u8 level; } __attribute__ ((__packed__)); -#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \-			        sizeof(struct btrfs_header)) / \-			        sizeof(struct btrfs_key_ptr)) #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header))-#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->nodesize))-#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \-					sizeof(struct btrfs_item) - \-					sizeof(struct btrfs_file_extent_item))-#define BTRFS_MAX_XATTR_SIZE(r)	(BTRFS_LEAF_DATA_SIZE(r) - \-				 sizeof(struct btrfs_item) -\-				 sizeof(struct btrfs_dir_item))-+#define BTRFS_LEAF_DATA_SIZE(fs_info) \+				(__BTRFS_LEAF_DATA_SIZE(fs_info->nodesize))  /*  * this is a very generous portion of the super block, giving us@@ -429,7 +436,7 @@ 	__le32 sectorsize; 	__le32 nodesize; 	/* Unused and must be equal to nodesize */-	__le32 leafsize;+	__le32 __unused_leafsize; 	__le32 stripesize; 	__le32 sys_chunk_array_size; 	__le64 chunk_root_generation;@@ -458,19 +465,20 @@  * ones specified below then we will fail to mount  */ #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE	(1ULL << 0)+/*+ * Older kernels on big-endian systems produced broken free space tree bitmaps,+ * and btrfs-progs also used to corrupt the free space tree. If this bit is+ * clear, then the free space tree cannot be trusted. btrfs-progs can also+ * intentionally clear this bit to ask the kernel to rebuild the free space+ * tree.+ */+#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID	(1ULL << 1)  #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF	(1ULL << 0) #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL	(1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS	(1ULL << 2) #define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO	(1ULL << 3)--/*- * some patches floated around with a second compression method- * lets save that incompat here for when they do get in- * Note we don't actually support it, we're just reserving the- * number- */-#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2   (1ULL << 4)+#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD	(1ULL << 4)  /*  * older kernels tried to do bigger metadata blocks, but the@@ -484,13 +492,18 @@  #define BTRFS_FEATURE_COMPAT_SUPP		0ULL -#define BTRFS_FEATURE_COMPAT_RO_SUPP			\-	(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE)+/*+ * The FREE_SPACE_TREE and FREE_SPACE_TREE_VALID compat_ro bits must not be+ * added here until read-write support for the free space tree is implemented in+ * btrfs-progs.+ */+#define BTRFS_FEATURE_COMPAT_RO_SUPP		0ULL  #define BTRFS_FEATURE_INCOMPAT_SUPP			\ 	(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |		\ 	 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL |	\ 	 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO |		\+	 BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD |		\ 	 BTRFS_FEATURE_INCOMPAT_BIG_METADATA |		\ 	 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF |		\ 	 BTRFS_FEATURE_INCOMPAT_RAID56 |		\@@ -543,22 +556,24 @@  * The slots array records the index of the item or block pointer  * used while walking the tree.  */-+enum { READA_NONE = 0, READA_BACK, READA_FORWARD }; struct btrfs_path { 	struct extent_buffer *nodes[BTRFS_MAX_LEVEL]; 	int slots[BTRFS_MAX_LEVEL];-	/* if there is real range locking, this locks field will change */+#if 0+	/* The kernel locking sheme is not done in userspace. */ 	int locks[BTRFS_MAX_LEVEL];-	int reada;+#endif+	signed char reada; 	/* keep some upper locks as we walk down */-	int lowest_level;+	u8 lowest_level;  	/* 	 * set by btrfs_split_item, tells search_slot to keep all locks 	 * and to force calls to keep space in the nodes 	 */-	unsigned int search_for_split:1;-	unsigned int skip_check_block:1;+	u8 search_for_split;+	u8 skip_check_block; };  /*@@ -576,9 +591,10 @@ 	__le32 refs; } __attribute__ ((__packed__)); -#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) ((BTRFS_LEAF_DATA_SIZE(r) >> 4) - \+#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) \+			((BTRFS_LEAF_DATA_SIZE(r->fs_info) >> 4) - \ 					sizeof(struct btrfs_item))-#define BTRFS_MAX_EXTENT_SIZE		(128 * 1024 * 1024)+#define BTRFS_MAX_EXTENT_SIZE		SZ_128M  #define BTRFS_EXTENT_FLAG_DATA		(1ULL << 0) #define BTRFS_EXTENT_FLAG_TREE_BLOCK	(1ULL << 1)@@ -650,8 +666,9 @@ 	BTRFS_COMPRESS_NONE  = 0, 	BTRFS_COMPRESS_ZLIB  = 1, 	BTRFS_COMPRESS_LZO   = 2,-	BTRFS_COMPRESS_TYPES = 2,-	BTRFS_COMPRESS_LAST  = 3,+	BTRFS_COMPRESS_ZSTD  = 3,+	BTRFS_COMPRESS_TYPES = 3,+	BTRFS_COMPRESS_LAST  = 4, } btrfs_compression_type;  /* we don't understand any encryption methods right now */@@ -780,6 +797,84 @@ 	__le16 name_len; } __attribute__ ((__packed__)); +struct btrfs_disk_balance_args {+	/*+	 * profiles to operate on, single is denoted by+	 * BTRFS_AVAIL_ALLOC_BIT_SINGLE+	 */+	__le64 profiles;++	/*+	 * usage filter+	 * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N'+	 * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max+	 */+	union {+		__le64 usage;+		struct {+			__le32 usage_min;+			__le32 usage_max;+		};+	};++	/* devid filter */+	__le64 devid;++	/* devid subset filter [pstart..pend) */+	__le64 pstart;+	__le64 pend;++	/* btrfs virtual address space subset filter [vstart..vend) */+	__le64 vstart;+	__le64 vend;++	/*+	 * profile to convert to, single is denoted by+	 * BTRFS_AVAIL_ALLOC_BIT_SINGLE+	 */+	__le64 target;++	/* BTRFS_BALANCE_ARGS_* */+	__le64 flags;++	/*+	 * BTRFS_BALANCE_ARGS_LIMIT with value 'limit'+	 * BTRFS_BALANCE_ARGS_LIMIT_RANGE - the extend version can use minimum+	 * and maximum+	 */+	union {+		__le64 limit;+		struct {+			__le32 limit_min;+			__le32 limit_max;+		};+	};++	/*+	 * Process chunks that cross stripes_min..stripes_max devices,+	 * BTRFS_BALANCE_ARGS_STRIPES_RANGE+	 */+	__le32 stripes_min;+	__le32 stripes_max;++	__le64 unused[6];+} __attribute__ ((__packed__));++/*+ * store balance parameters to disk so that balance can be properly+ * resumed after crash or unmount+ */+struct btrfs_balance_item {+	/* BTRFS_BALANCE_* */+	__le64 flags;++	struct btrfs_disk_balance_args data;+	struct btrfs_disk_balance_args meta;+	struct btrfs_disk_balance_args sys;++	__le64 unused[4];+} __attribute__ ((__packed__));+ #define BTRFS_FILE_EXTENT_INLINE 0 #define BTRFS_FILE_EXTENT_REG 1 #define BTRFS_FILE_EXTENT_PREALLOC 2@@ -833,6 +928,14 @@  } __attribute__ ((__packed__)); +struct btrfs_dev_stats_item {+        /*+         * grow this item struct at the end for future enhancements and keep+         * the existing values unchanged+         */+        __le64 values[BTRFS_DEV_STAT_VALUES_MAX];+} __attribute__ ((__packed__));+ struct btrfs_csum_item { 	u8 csum; } __attribute__ ((__packed__));@@ -843,7 +946,7 @@  *  - the first 64k blank is useful for some boot loader/manager  *  - the first 1M could be scratched by buggy partitioner or somesuch  */-#define BTRFS_BLOCK_RESERVED_1M_FOR_SUPER	((u64)1024 * 1024)+#define BTRFS_BLOCK_RESERVED_1M_FOR_SUPER	((u64)SZ_1M)  /* tag for the radix tree of block groups in ram */ #define BTRFS_BLOCK_GROUP_DATA		(1ULL << 0)@@ -856,8 +959,18 @@ #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 +enum btrfs_raid_types {+	BTRFS_RAID_RAID10,+	BTRFS_RAID_RAID1,+	BTRFS_RAID_DUP,+	BTRFS_RAID_RAID0,+	BTRFS_RAID_SINGLE,+	BTRFS_RAID_RAID5,+	BTRFS_RAID_RAID6,+	BTRFS_NR_RAID_TYPES+};+ #define BTRFS_BLOCK_GROUP_TYPE_MASK	(BTRFS_BLOCK_GROUP_DATA |    \ 					 BTRFS_BLOCK_GROUP_SYSTEM |  \ 					 BTRFS_BLOCK_GROUP_METADATA)@@ -1015,8 +1128,8 @@  	struct btrfs_fs_devices *fs_devices; 	struct list_head space_info;-	int system_allocs; +	unsigned int system_allocs:1; 	unsigned int readonly:1; 	unsigned int on_restoring:1; 	unsigned int is_chunk_recover:1;@@ -1026,15 +1139,21 @@ 	unsigned int ignore_chunk_tree_error:1; 	unsigned int avoid_meta_chunk_alloc:1; 	unsigned int avoid_sys_chunk_alloc:1;+	unsigned int finalize_on_close:1; -	int (*free_extent_hook)(struct btrfs_trans_handle *trans,-				struct btrfs_root *root,+	int transaction_aborted;++	int (*free_extent_hook)(struct btrfs_fs_info *fs_info, 				u64 bytenr, u64 num_bytes, u64 parent, 				u64 root_objectid, u64 owner, u64 offset, 				int refs_to_drop); 	struct cache_tree *fsck_extent_cache; 	struct cache_tree *corrupt_blocks; +	/* Cached block sizes */+	u32 nodesize;+	u32 sectorsize;+	u32 stripesize; };  /*@@ -1050,24 +1169,11 @@ 	u64 objectid; 	u64 last_trans; -	/* data allocations are done in sectorsize units */-	u32 sectorsize;--	/* node allocations are done in nodesize units */-	u32 nodesize;--	/* Unused, equal to nodesize */-	u32 leafsize;--	/* leaf allocations are done in nodesize units */-	u32 stripesize;- 	int ref_cows; 	int track_dirty;   	u32 type;-	u64 highest_inode; 	u64 last_inode_alloc;  	/*@@ -1085,6 +1191,35 @@ 	struct rb_node rb_node; }; +static inline u32 BTRFS_MAX_ITEM_SIZE(const struct btrfs_fs_info *info)+{+	return BTRFS_LEAF_DATA_SIZE(info) - sizeof(struct btrfs_item);+}++static inline u32 BTRFS_NODEPTRS_PER_BLOCK(const struct btrfs_fs_info *info)+{+	return BTRFS_LEAF_DATA_SIZE(info) / sizeof(struct btrfs_key_ptr);+}++static inline u32 BTRFS_NODEPTRS_PER_EXTENT_BUFFER(const struct extent_buffer *eb)+{+	BUG_ON(eb->fs_info && eb->fs_info->nodesize != eb->len);+	return __BTRFS_LEAF_DATA_SIZE(eb->len) / sizeof(struct btrfs_key_ptr);+}++#define BTRFS_FILE_EXTENT_INLINE_DATA_START		\+	(offsetof(struct btrfs_file_extent_item, disk_bytenr))+static inline u32 BTRFS_MAX_INLINE_DATA_SIZE(const struct btrfs_fs_info *info)+{+	return BTRFS_MAX_ITEM_SIZE(info) -+		BTRFS_FILE_EXTENT_INLINE_DATA_START;+}++static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_fs_info *info)+{+	return BTRFS_MAX_ITEM_SIZE(info) - sizeof(struct btrfs_dir_item);+}+ /*  * inode items have the data typically returned from stat and store other  * info about object characteristics.  There is one for every file and dir in@@ -1205,12 +1340,44 @@ #define BTRFS_QGROUP_RELATION_KEY	246  /*- * Persistently stores the io stats in the device tree.- * One key for all stats, (0, BTRFS_DEV_STATS_KEY, devid).+ * Obsolete name, see BTRFS_TEMPORARY_ITEM_KEY.  */-#define BTRFS_DEV_STATS_KEY	249+#define BTRFS_BALANCE_ITEM_KEY	248  /*+ * The key type for tree items that are stored persistently, but do not need to+ * exist for extended period of time. The items can exist in any tree.+ *+ * [subtype, BTRFS_TEMPORARY_ITEM_KEY, data]+ *+ * Existing items:+ *+ * - balance status item+ *   (BTRFS_BALANCE_OBJECTID, BTRFS_TEMPORARY_ITEM_KEY, 0)+ */+#define BTRFS_TEMPORARY_ITEM_KEY	248++/*+ * Obsolete name, see BTRFS_PERSISTENT_ITEM_KEY+ */+#define BTRFS_DEV_STATS_KEY		249++/*+ * The key type for tree items that are stored persistently and usually exist+ * for a long period, eg. filesystem lifetime. The item kinds can be status+ * information, stats or preference values. The item can exist in any tree.+ *+ * [subtype, BTRFS_PERSISTENT_ITEM_KEY, data]+ *+ * Existing items:+ *+ * - device statistics, store IO stats in the device tree, one key for all+ *   stats+ *   (BTRFS_DEV_STATS_OBJECTID, BTRFS_DEV_STATS_KEY, 0)+ */+#define BTRFS_PERSISTENT_ITEM_KEY	249++/*  * Persistently stores the device replace state in the device tree.  * The key is built like this: (0, BTRFS_DEV_REPLACE_KEY, 0).  */@@ -1240,6 +1407,15 @@ #define BTRFS_INODE_NODATASUM		(1 << 0) #define BTRFS_INODE_NODATACOW		(1 << 1) #define BTRFS_INODE_READONLY		(1 << 2)+#define BTRFS_INODE_NOCOMPRESS		(1 << 3)+#define BTRFS_INODE_PREALLOC		(1 << 4)+#define BTRFS_INODE_SYNC		(1 << 5)+#define BTRFS_INODE_IMMUTABLE		(1 << 6)+#define BTRFS_INODE_APPEND		(1 << 7)+#define BTRFS_INODE_NODUMP		(1 << 8)+#define BTRFS_INODE_NOATIME		(1 << 9)+#define BTRFS_INODE_DIRSYNC		(1 << 10)+#define BTRFS_INODE_COMPRESS		(1 << 11)  #define read_eb_member(eb, ptr, type, member, result) (			\ 	read_extent_buffer(eb, (char *)(result),			\@@ -1697,7 +1873,7 @@ 	return btrfs_item_end(eb, btrfs_item_nr(nr)); } -static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr)+static inline u32 btrfs_item_offset_nr(const struct extent_buffer *eb, int nr) { 	return btrfs_item_offset(eb, btrfs_item_nr(nr)); }@@ -1740,7 +1916,10 @@ BTRFS_SETGET_FUNCS(dir_name_len, struct btrfs_dir_item, name_len, 16); BTRFS_SETGET_FUNCS(dir_transid, struct btrfs_dir_item, transid, 64); +BTRFS_SETGET_STACK_FUNCS(stack_dir_data_len, struct btrfs_dir_item, data_len, 16);+BTRFS_SETGET_STACK_FUNCS(stack_dir_type, struct btrfs_dir_item, type, 8); BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, name_len, 16);+BTRFS_SETGET_STACK_FUNCS(stack_dir_transid, struct btrfs_dir_item, transid, 64);  static inline void btrfs_dir_item_key(struct extent_buffer *eb, 				      struct btrfs_dir_item *item,@@ -1825,17 +2004,6 @@ 	btrfs_disk_key_to_cpu(key, &disk_key); } --static inline u8 btrfs_key_type(struct btrfs_key *key)-{-	return key->type;-}--static inline void btrfs_set_key_type(struct btrfs_key *key, u8 val)-{-	key->type = val;-}- /* struct btrfs_header */ BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64); BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,@@ -1895,33 +2063,12 @@ 	return offsetof(struct btrfs_header, chunk_tree_uuid); } -static inline u8 *btrfs_super_fsid(struct extent_buffer *eb)-{-	unsigned long ptr = offsetof(struct btrfs_super_block, fsid);-	return (u8 *)ptr;-}- static inline u8 *btrfs_header_csum(struct extent_buffer *eb) { 	unsigned long ptr = offsetof(struct btrfs_header, csum); 	return (u8 *)ptr; } -static inline struct btrfs_node *btrfs_buffer_node(struct extent_buffer *eb)-{-	return NULL;-}--static inline struct btrfs_leaf *btrfs_buffer_leaf(struct extent_buffer *eb)-{-	return NULL;-}--static inline struct btrfs_header *btrfs_buffer_header(struct extent_buffer *eb)-{-	return NULL;-}- static inline int btrfs_is_leaf(struct extent_buffer *eb) { 	return (btrfs_header_level(eb) == 0);@@ -1956,6 +2103,38 @@ BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item, 			 rtransid, 64); +static inline struct btrfs_timespec* btrfs_root_ctime(+		struct btrfs_root_item *root_item)+{+	unsigned long ptr = (unsigned long)root_item;+	ptr += offsetof(struct btrfs_root_item, ctime);+	return (struct btrfs_timespec *)ptr;+}++static inline struct btrfs_timespec* btrfs_root_otime(+		struct btrfs_root_item *root_item)+{+	unsigned long ptr = (unsigned long)root_item;+	ptr += offsetof(struct btrfs_root_item, otime);+	return (struct btrfs_timespec *)ptr;+}++static inline struct btrfs_timespec* btrfs_root_stime(+		struct btrfs_root_item *root_item)+{+	unsigned long ptr = (unsigned long)root_item;+	ptr += offsetof(struct btrfs_root_item, stime);+	return (struct btrfs_timespec *)ptr;+}++static inline struct btrfs_timespec* btrfs_root_rtime(+		struct btrfs_root_item *root_item)+{+	unsigned long ptr = (unsigned long)root_item;+	ptr += offsetof(struct btrfs_root_item, rtime);+	return (struct btrfs_timespec *)ptr;+}+ /* struct btrfs_root_backup */ BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup, 		   tree_root, 64);@@ -2036,8 +2215,6 @@ 			 sectorsize, 32); BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block, 			 nodesize, 32);-BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block,-			 leafsize, 32); BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block, 			 stripesize, 32); BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block,@@ -2183,7 +2360,50 @@ BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_rsv_exclusive, 			 struct btrfs_qgroup_limit_item, rsv_exclusive, 64); +/* btrfs_balance_item */+BTRFS_SETGET_FUNCS(balance_item_flags, struct btrfs_balance_item, flags, 64);++static inline struct btrfs_disk_balance_args* btrfs_balance_item_data(+		struct extent_buffer *eb, struct btrfs_balance_item *bi)+{+	unsigned long offset = (unsigned long)bi;+	struct btrfs_balance_item *p;+	p = (struct btrfs_balance_item *)(eb->data + offset);+	return &p->data;+}++static inline struct btrfs_disk_balance_args* btrfs_balance_item_meta(+		struct extent_buffer *eb, struct btrfs_balance_item *bi)+{+	unsigned long offset = (unsigned long)bi;+	struct btrfs_balance_item *p;+	p = (struct btrfs_balance_item *)(eb->data + offset);+	return &p->meta;+}++static inline struct btrfs_disk_balance_args* btrfs_balance_item_sys(+		struct extent_buffer *eb, struct btrfs_balance_item *bi)+{+	unsigned long offset = (unsigned long)bi;+	struct btrfs_balance_item *p;+	p = (struct btrfs_balance_item *)(eb->data + offset);+	return &p->sys;+}+ /*+ * btrfs_dev_stats_item helper, returns pointer to the raw array, do the+ * endiannes conversion, @dsi is offset to eb data+ */+static inline __le64* btrfs_dev_stats_values(struct extent_buffer *eb,+		struct btrfs_dev_stats_item *dsi)+{+	unsigned long offset = (unsigned long)dsi;+	struct btrfs_dev_stats_item *p;+	p = (struct btrfs_dev_stats_item *)(eb->data + offset);+	return p->values;+}++/*  * this returns the number of bytes used by the item on disk, minus the  * size of any extent headers.  If a file is compressed on disk, this is  * the compressed size@@ -2222,47 +2442,20 @@ 	return get_unaligned_32(&sh->len); } -/* this returns the number of file bytes represented by the inline item.- * If an item is compressed, this is the uncompressed size- */-static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb,-					       int slot,-					       struct btrfs_file_extent_item *fi)-{-	/*-	 * return the space used on disk if this item isn't-	 * compressed or encoded-	 */-	if (btrfs_file_extent_compression(eb, fi) == 0 &&-	    btrfs_file_extent_encryption(eb, fi) == 0 &&-	    btrfs_file_extent_other_encoding(eb, fi) == 0) {-		return btrfs_file_extent_inline_item_len(eb,-							 btrfs_item_nr(slot));-	}--	/* otherwise use the ram bytes field */-	return btrfs_file_extent_ram_bytes(eb, fi);-}--/*- * NOTE: Backward compatibility, do not use.- * Replacement: read nodesize directly- */-__attribute__((deprecated))-static inline u32 btrfs_level_size(struct btrfs_root *root, int level) {-	if (level == 0)-		return root->leafsize;-	return root->nodesize;-}+#define btrfs_fs_incompat(fs_info, opt) \+	__btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt) -static inline int btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag)+static inline bool __btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag) { 	struct btrfs_super_block *disk_super; 	disk_super = fs_info->super_copy; 	return !!(btrfs_super_incompat_flags(disk_super) & flag); } -static inline int btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)+#define btrfs_fs_compat_ro(fs_info, opt) \+	__btrfs_fs_compat_ro((fs_info), BTRFS_FEATURE_COMPAT_RO_##opt)++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;@@ -2283,14 +2476,12 @@ 			 struct btrfs_root *root, 			 u64 num_bytes, u64 empty_size, 			 u64 hint_byte, u64 search_end,-			 struct btrfs_key *ins, int data);-int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,-				 struct btrfs_root *root);+			 struct btrfs_key *ins, bool is_data);+int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans); void btrfs_pin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes); void btrfs_unpin_extent(struct btrfs_fs_info *fs_info, 			u64 bytenr, u64 num_bytes);-int btrfs_extent_post_op(struct btrfs_trans_handle *trans,-			 struct btrfs_root *root);+int btrfs_extent_post_op(struct btrfs_trans_handle *trans); struct btrfs_block_group_cache *btrfs_lookup_block_group(struct 							 btrfs_fs_info *info, 							 u64 bytenr);@@ -2302,22 +2493,19 @@ 					u32 blocksize, u64 root_objectid, 					struct btrfs_disk_key *key, int level, 					u64 hint, u64 empty_size);-int btrfs_alloc_extent(struct btrfs_trans_handle *trans,-		       struct btrfs_root *root,-		       u64 num_bytes, u64 parent,-		       u64 root_objectid, u64 ref_generation,-		       u64 owner, u64 empty_size, u64 hint_byte,-		       u64 search_end, struct btrfs_key *ins, int data); int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,-			     struct btrfs_root *root, u64 bytenr,+			     struct btrfs_fs_info *fs_info, u64 bytenr, 			     u64 offset, int metadata, u64 *refs, u64 *flags);-int btrfs_set_block_flags(struct btrfs_trans_handle *trans,-			  struct btrfs_root *root,-			  u64 bytenr, int level, u64 flags);+int btrfs_set_block_flags(struct btrfs_trans_handle *trans, u64 bytenr,+			  int level, u64 flags); int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 		  struct extent_buffer *buf, int record_parent); int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 		  struct extent_buffer *buf, int record_parent);+int btrfs_free_tree_block(struct btrfs_trans_handle *trans,+			  struct btrfs_root *root,+			  struct extent_buffer *buf,+			  u64 parent, int last_ref); int btrfs_free_extent(struct btrfs_trans_handle *trans, 		      struct btrfs_root *root, 		      u64 bytenr, u64 num_bytes, u64 parent,@@ -2341,15 +2529,13 @@ int btrfs_read_block_groups(struct btrfs_root *root); struct btrfs_block_group_cache * btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,-		      u64 chunk_objectid, u64 chunk_offset, u64 size);+		      u64 chunk_offset, u64 size); int btrfs_make_block_group(struct btrfs_trans_handle *trans,-			   struct btrfs_root *root, u64 bytes_used,-			   u64 type, u64 chunk_objectid, u64 chunk_offset,-			   u64 size);+			   struct btrfs_fs_info *fs_info, u64 bytes_used,+			   u64 type, u64 chunk_offset, u64 size); int btrfs_make_block_groups(struct btrfs_trans_handle *trans,-			    struct btrfs_root *root);-int btrfs_update_block_group(struct btrfs_trans_handle *trans,-			     struct btrfs_root *root, u64 bytenr, u64 num,+			    struct btrfs_fs_info *fs_info);+int btrfs_update_block_group(struct btrfs_root *root, u64 bytenr, u64 num, 			     int alloc, int mark_free); int btrfs_record_file_extent(struct btrfs_trans_handle *trans, 			      struct btrfs_root *root, u64 objectid,@@ -2364,10 +2550,12 @@ 			  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);+u64 hash_extent_data_ref(u64 root_objectid, u64 owner, u64 offset);+ /* 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,-		   struct btrfs_path *path, int level, int slot);+int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path,+		int level, int slot); enum btrfs_tree_block_status btrfs_check_node(struct btrfs_root *root, struct btrfs_disk_key *parent_key, 		 struct extent_buffer *buf);@@ -2376,7 +2564,7 @@ 		 struct extent_buffer *buf); void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, 			     int level, int slot, u64 objectid);-struct extent_buffer *read_node_slot(struct btrfs_root *root,+struct extent_buffer *read_node_slot(struct btrfs_fs_info *fs_info, 				   struct extent_buffer *parent, int slot); int btrfs_previous_item(struct btrfs_root *root, 			struct btrfs_path *path, u64 min_objectid,@@ -2399,11 +2587,9 @@ 		      struct btrfs_root *root, 		      struct extent_buffer *buf, 		      struct extent_buffer **cow_ret, u64 new_root_objectid);-int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root-		      *root, struct btrfs_path *path, u32 data_size);-int btrfs_truncate_item(struct btrfs_trans_handle *trans,-			struct btrfs_root *root,-			struct btrfs_path *path,+int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,+		u32 data_size);+int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path, 			u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, 		     struct btrfs_root *root,@@ -2458,7 +2644,7 @@ }  int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);-int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);+int btrfs_leaf_free_space(struct extent_buffer *leaf); void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path, 			  struct btrfs_disk_key *key, int level); int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path,@@ -2476,6 +2662,8 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root 		      *root, struct btrfs_key *key, struct btrfs_root_item 		      *item);+int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,+		   struct btrfs_key *key); int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root 		      *root, struct btrfs_key *key, struct btrfs_root_item 		      *item);@@ -2535,14 +2723,13 @@ 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 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,-		    struct btrfs_root *root, u64 bytenr, u64 len);+int btrfs_del_csums(struct btrfs_trans_handle *trans, u64 bytenr, u64 len); int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, 			     struct btrfs_root *root, 			     u64 objectid, u64 pos, u64 offset,@@ -2550,7 +2737,7 @@ 			     u64 num_bytes); int btrfs_insert_inline_extent(struct btrfs_trans_handle *trans, 				struct btrfs_root *root, u64 objectid,-				u64 offset, char *buffer, size_t size);+				u64 offset, const char *buffer, size_t size); int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 			  struct btrfs_root *root, u64 alloc_end, 			  u64 bytenr, char *data, size_t len);@@ -2576,9 +2763,11 @@ 		u64 dir, u64 index); int btrfs_new_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, 		u64 ino, u32 mode);+int btrfs_change_inode_flags(struct btrfs_trans_handle *trans,+			     struct btrfs_root *root, u64 ino, u64 flags); 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);+		   u8 type, u64 *index, int add_backref, int ignore_existed); 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);@@ -2587,6 +2776,8 @@ 			  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);+struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root, const char *base,+				  u64 root_objectid, bool convert);  /* file.c */ int btrfs_get_extent(struct btrfs_trans_handle *trans,@@ -2596,4 +2787,7 @@ int btrfs_punch_hole(struct btrfs_trans_handle *trans, 		     struct btrfs_root *root, 		     u64 ino, u64 offset, u64 len);+int btrfs_read_file(struct btrfs_root *root, u64 ino, u64 start, int len,+		    char *dest);+ #endif
include/btrfs/extent-cache.h view
@@ -106,8 +106,6 @@  */ 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);  /*
include/btrfs/extent_io.h view
@@ -75,6 +75,7 @@ 	struct cache_tree cache; 	struct list_head lru; 	u64 cache_size;+	u64 max_cache_size; };  struct extent_state {@@ -90,14 +91,15 @@ 	struct cache_extent cache_node; 	u64 start; 	u64 dev_bytenr;-	u32 len; 	struct extent_io_tree *tree; 	struct list_head lru; 	struct list_head recow;+	u32 len; 	int refs; 	u32 flags; 	int fd;-	char data[];+	struct btrfs_fs_info *fs_info;+	char data[] __attribute__((aligned(8))); };  static inline void extent_buffer_get(struct extent_buffer *eb)@@ -106,27 +108,24 @@ }  void extent_io_tree_init(struct extent_io_tree *tree);+void extent_io_tree_init_cache_max(struct extent_io_tree *tree,+				   u64 max_cache_size); void extent_io_tree_cleanup(struct extent_io_tree *tree);-int set_extent_bits(struct extent_io_tree *tree, u64 start,-		    u64 end, int bits, gfp_t mask);-int clear_extent_bits(struct extent_io_tree *tree, u64 start,-		      u64 end, int bits, gfp_t mask);+int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits);+int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits); int find_first_extent_bit(struct extent_io_tree *tree, u64 start, 			  u64 *start_ret, u64 *end_ret, int bits); int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, 		   int bits, int filled);-int set_extent_dirty(struct extent_io_tree *tree, u64 start,-		     u64 end, gfp_t mask);-int clear_extent_dirty(struct extent_io_tree *tree, u64 start,-		       u64 end, gfp_t mask);+int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end);+int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end); 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)+static inline int clear_extent_buffer_uptodate(struct extent_buffer *eb) { 	eb->flags &= ~EXTENT_UPTODATE; 	return 0;@@ -147,10 +146,11 @@ 					 u64 bytenr, u32 blocksize); struct extent_buffer *find_first_extent_buffer(struct extent_io_tree *tree, 					       u64 start);-struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,+struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, 					  u64 bytenr, u32 blocksize); struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); void free_extent_buffer(struct extent_buffer *eb);+void free_extent_buffer_nocache(struct extent_buffer *eb); int read_extent_from_disk(struct extent_buffer *eb, 			  unsigned long offset, unsigned long len); int write_extent_to_disk(struct extent_buffer *eb);
include/btrfs/ioctl.h view
@@ -25,11 +25,17 @@  #include <asm/types.h> #include <linux/ioctl.h>+#include <stddef.h>  #ifndef __user #define __user #endif +/* We don't want to include entire kerncompat.h */+#ifndef BUILD_ASSERT+#define BUILD_ASSERT(x)+#endif+ #define BTRFS_IOCTL_MAGIC 0x94 #define BTRFS_VOL_NAME_MAX 255 @@ -39,6 +45,7 @@ 	__s64 fd; 	char name[BTRFS_PATH_NAME_MAX + 1]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_vol_args) == 4096);  #define BTRFS_DEVICE_PATH_NAME_MAX 1024 @@ -65,6 +72,7 @@ 	__u64	rsv_referenced; 	__u64	rsv_exclusive; };+BUILD_ASSERT(sizeof(struct btrfs_qgroup_limit) == 40);  struct btrfs_qgroup_inherit { 	__u64	flags;@@ -74,11 +82,13 @@ 	struct btrfs_qgroup_limit lim; 	__u64	qgroups[0]; };+BUILD_ASSERT(sizeof(struct btrfs_qgroup_inherit) == 72);  struct btrfs_ioctl_qgroup_limit_args { 	__u64	qgroupid; 	struct btrfs_qgroup_limit lim; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_qgroup_limit_args) == 48);  #define BTRFS_SUBVOL_NAME_MAX 4039 struct btrfs_ioctl_vol_args_v2 {@@ -97,6 +107,7 @@ 		__u64 devid; 	}; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_vol_args_v2) == 4096);  /*  * structure to report errors and progress to userspace, either as a@@ -145,6 +156,7 @@ 	/* pad to 1k */ 	__u64 unused[(1024-32-sizeof(struct btrfs_scrub_progress))/8]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_scrub_args) == 1024);  #define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS	0 #define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID	1@@ -155,6 +167,7 @@ 	__u8 srcdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1];	/* in */ 	__u8 tgtdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1];	/* in */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_replace_start_params) == 2072);  #define BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED	0 #define BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED		1@@ -169,6 +182,7 @@ 	__u64 num_write_errors;	/* out */ 	__u64 num_uncorrectable_read_errors;	/* out */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_replace_status_params) == 48);  #define BTRFS_IOCTL_DEV_REPLACE_CMD_START			0 #define BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS			1@@ -189,6 +203,7 @@  	__u64 spare[64]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_replace_args) == 2600);  struct btrfs_ioctl_dev_info_args { 	__u64 devid;				/* in/out */@@ -198,6 +213,7 @@ 	__u64 unused[379];			/* pad to 4k */ 	__u8 path[BTRFS_DEVICE_PATH_NAME_MAX];	/* out */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_dev_info_args) == 4096);  struct btrfs_ioctl_fs_info_args { 	__u64 max_id;				/* out */@@ -209,12 +225,14 @@ 	__u32 reserved32; 	__u64 reserved[122];			/* pad to 1k */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_fs_info_args) == 1024);  struct btrfs_ioctl_feature_flags { 	__u64 compat_flags; 	__u64 compat_ro_flags; 	__u64 incompat_flags; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_feature_flags) == 24);  /* balance control ioctl modes */ #define BTRFS_BALANCE_CTL_PAUSE		1@@ -292,6 +310,7 @@  	__u64 unused[72];			/* pad to 1k */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_balance_args) == 1024);  #define BTRFS_INO_LOOKUP_PATH_MAX 4080 struct btrfs_ioctl_ino_lookup_args {@@ -299,6 +318,7 @@ 	__u64 objectid; 	char name[BTRFS_INO_LOOKUP_PATH_MAX]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_ino_lookup_args) == 4096);  struct btrfs_ioctl_search_key { 	/* which root are we searching.  0 is the tree of tree roots */@@ -366,6 +386,7 @@                                             *       to store item */         __u64 buf[0];                      /* out - found items */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_search_args_v2) == 112);  /* With a @src_length of zero, the range from @src_offset->EOF is cloned! */ struct btrfs_ioctl_clone_range_args {@@ -373,6 +394,7 @@ 	__u64 src_offset, src_length; 	__u64 dest_offset; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_clone_range_args) == 32);  /* flags for the defrag range ioctl */ #define BTRFS_DEFRAG_RANGE_COMPRESS 1@@ -402,6 +424,7 @@ 	__u32 reserved2; 	struct btrfs_ioctl_same_extent_info info[0]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_same_args) == 24);  struct btrfs_ioctl_defrag_range_args { 	/* start of the defrag operation */@@ -433,6 +456,7 @@ 	/* spare for later */ 	__u32 unused[4]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_defrag_range_args) == 48);  struct btrfs_ioctl_space_info { 	__u64 flags;@@ -445,6 +469,7 @@ 	__u64 total_spaces; 	struct btrfs_ioctl_space_info spaces[0]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_space_args) == 16);  struct btrfs_data_container { 	__u32	bytes_left;	/* out -- bytes not needed to deliver output */@@ -461,6 +486,7 @@ 	/* struct btrfs_data_container	*fspath;	   out */ 	__u64				fspath;		/* out */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_ino_path_args) == 56);  struct btrfs_ioctl_logical_ino_args { 	__u64				logical;	/* in */@@ -500,8 +526,9 @@ 	/* out values: */ 	__u64 values[BTRFS_DEV_STAT_VALUES_MAX]; -	__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k */+	__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k + 8B */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_get_dev_stats) == 1032);  /* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */ #define BTRFS_QUOTA_CTL_ENABLE	1@@ -511,12 +538,14 @@ 	__u64 cmd; 	__u64 status; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_quota_ctl_args) == 16);  struct btrfs_ioctl_quota_rescan_args { 	__u64	flags; 	__u64   progress; 	__u64   reserved[6]; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_quota_rescan_args) == 64);  struct btrfs_ioctl_qgroup_assign_args { 	__u64 assign;@@ -528,6 +557,8 @@ 	__u64 create; 	__u64 qgroupid; };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_qgroup_create_args) == 16);+ struct btrfs_ioctl_timespec { 	__u64 sec; 	__u32 nsec;@@ -542,8 +573,41 @@ 	__u64	flags;			/* in */ 	__u64	reserved[16];		/* in */ };+BUILD_ASSERT(sizeof(struct btrfs_ioctl_received_subvol_args) == 200);  /*+ * If we have a 32-bit userspace and 64-bit kernel, then the UAPI+ * structures are incorrect, as the timespec structure from userspace+ * is 4 bytes too small. We define these alternatives here for backward+ * compatibility, the kernel understands both values.+ */++/*+ * Structure size is different on 32bit and 64bit, has some padding if the+ * structure is embedded. Packing makes sure the size is same on both, but will+ * be misaligned on 64bit.+ *+ * NOTE: do not use in your code, this is for testing only+ */+struct btrfs_ioctl_timespec_32 {+	__u64 sec;+	__u32 nsec;+} __attribute__ ((__packed__));++struct btrfs_ioctl_received_subvol_args_32 {+	char	uuid[BTRFS_UUID_SIZE];	/* in */+	__u64	stransid;		/* in */+	__u64	rtransid;		/* out */+	struct btrfs_ioctl_timespec_32 stime; /* in */+	struct btrfs_ioctl_timespec_32 rtime; /* out */+	__u64	flags;			/* in */+	__u64	reserved[16];		/* in */+} __attribute__ ((__packed__));+BUILD_ASSERT(sizeof(struct btrfs_ioctl_received_subvol_args_32) == 192);++#define BTRFS_IOC_SET_RECEIVED_SUBVOL_32_COMPAT_DEFINED 1++/*  * 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.@@ -576,7 +640,38 @@ 	__u64 flags;			/* in */ 	__u64 reserved[4];		/* in */ };+/*+ * Size of structure depends on pointer width, was not caught in the early+ * days.  Kernel handles pointer width differences transparently.+ */+BUILD_ASSERT(sizeof(__u64 *) == 8+	     ? sizeof(struct btrfs_ioctl_send_args) == 72+	     : (sizeof(void *) == 4+		? sizeof(struct btrfs_ioctl_send_args) == 68+		: 0)); +/*+ * Different pointer width leads to structure size change. Kernel should accept+ * both ioctl values (derived from the structures) for backward compatibility.+ * Size of this structure is same on 32bit and 64bit though.+ *+ * NOTE: do not use in your code, this is for testing only+ */+struct btrfs_ioctl_send_args_64 {+	__s64 send_fd;			/* in */+	__u64 clone_sources_count;	/* in */+	union {+		__u64 __user *clone_sources;	/* in */+		__u64 __clone_sources_alignment;+	};+	__u64 parent_root;		/* in */+	__u64 flags;			/* in */+	__u64 reserved[4];		/* in */+} __attribute__((packed));+BUILD_ASSERT(sizeof(struct btrfs_ioctl_send_args_64) == 72);++#define BTRFS_IOC_SEND_64_COMPAT_DEFINED 1+ /* Error codes as returned by the kernel */ enum btrfs_err_code { 	notused,@@ -688,6 +783,17 @@ 					struct btrfs_ioctl_logical_ino_args) #define BTRFS_IOC_SET_RECEIVED_SUBVOL _IOWR(BTRFS_IOCTL_MAGIC, 37, \ 				struct btrfs_ioctl_received_subvol_args)++#ifdef BTRFS_IOC_SET_RECEIVED_SUBVOL_32_COMPAT_DEFINED+#define BTRFS_IOC_SET_RECEIVED_SUBVOL_32 _IOWR(BTRFS_IOCTL_MAGIC, 37, \+				struct btrfs_ioctl_received_subvol_args_32)+#endif++#ifdef BTRFS_IOC_SEND_64_COMPAT_DEFINED+#define BTRFS_IOC_SEND_64 _IOW(BTRFS_IOCTL_MAGIC, 38, \+		struct btrfs_ioctl_send_args_64)+#endif+ #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)
include/btrfs/kerncompat.h view
@@ -68,6 +68,14 @@ #define ULONG_MAX       (~0UL) #endif +#define __token_glue(a,b,c)	___token_glue(a,b,c)+#define ___token_glue(a,b,c)	a ## b ## c+#ifdef DEBUG_BUILD_CHECKS+#define BUILD_ASSERT(x)		extern int __token_glue(compile_time_assert_,__LINE__,__COUNTER__)[1-2*!(x)] __attribute__((unused))+#else+#define BUILD_ASSERT(x)+#endif+ #ifndef BTRFS_DISABLE_BACKTRACE #define MAX_BACKTRACE	16 static inline void print_trace(void)@@ -78,26 +86,35 @@ 	size = backtrace(array, MAX_BACKTRACE); 	backtrace_symbols_fd(array, size, 2); }+#endif -static inline void assert_trace(const char *assertion, const char *filename,-			      const char *func, unsigned line, int val)+static inline void warning_trace(const char *assertion, const char *filename,+			      const char *func, unsigned line, long val) {-	if (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);+	fprintf(stderr,+		"%s:%d: %s: Warning: assertion `%s` failed, value %ld\n",+		filename, line, func, assertion, val);+#ifndef BTRFS_DISABLE_BACKTRACE 	print_trace();-	exit(1);+#endif } -#define BUG() assert_trace(NULL, __FILE__, __func__, __LINE__, 0)-#else-#define BUG() assert(0)+static inline void bugon_trace(const char *assertion, const char *filename,+			      const char *func, unsigned line, long val)+{+	if (!val)+		return;+	fprintf(stderr,+		"%s:%d: %s: BUG_ON `%s` triggered, value %ld\n",+		filename, line, func, assertion, val);+#ifndef BTRFS_DISABLE_BACKTRACE+	print_trace(); #endif+	abort();+	exit(1);+}  #ifdef __CHECKER__ #define __force    __attribute__((force))@@ -236,11 +253,16 @@ 	return (long) ptr; } -static inline long IS_ERR(const void *ptr)+static inline int IS_ERR(const void *ptr) { 	return IS_ERR_VALUE((unsigned long)ptr); } +static inline int IS_ERR_OR_NULL(const void *ptr)+{+	return !ptr || IS_ERR(ptr);+}+ /*  * This looks more complex than it should be. But we need to  * get the type for the ~ right in round_down (it needs to be@@ -269,27 +291,39 @@ #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))-#endif--#define WARN_ON(c) BUG_ON(c)-+static inline void assert_trace(const char *assertion, const char *filename,+			      const char *func, unsigned line, long val)+{+	if (val)+		return;+	fprintf(stderr,+		"%s:%d: %s: Assertion `%s` failed, value %ld\n",+		filename, line, func, assertion, val); #ifndef BTRFS_DISABLE_BACKTRACE-#define	ASSERT(c) assert_trace(#c, __FILE__, __func__, __LINE__, (c))+	print_trace();+#endif+	abort();+	exit(1);+}+#define	ASSERT(c) assert_trace(#c, __FILE__, __func__, __LINE__, (long)(c)) #else #define ASSERT(c) assert(c) #endif +#define BUG_ON(c) bugon_trace(#c, __FILE__, __func__, __LINE__, (long)(c))+#define BUG() BUG_ON(1)+#define WARN_ON(c) warning_trace(#c, __FILE__, __func__, __LINE__, (long)(c))+ #define container_of(ptr, type, member) ({                      \         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \ 	        (type *)( (char *)__mptr - offsetof(type,member) );})+#ifndef __bitwise #ifdef __CHECKER__ #define __bitwise __bitwise__ #else #define __bitwise-#endif+#endif /* __CHECKER__ */+#endif	/* __bitwise */  /* Alignment check */ #define IS_ALIGNED(x, a)                (((x) & ((typeof(x))(a) - 1)) == 0)
+ include/btrfs/sizes.h view
@@ -0,0 +1,47 @@+/*+ * include/linux/sizes.h+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ */+#ifndef __LINUX_SIZES_H__+#define __LINUX_SIZES_H__++#define SZ_1				0x00000001+#define SZ_2				0x00000002+#define SZ_4				0x00000004+#define SZ_8				0x00000008+#define SZ_16				0x00000010+#define SZ_32				0x00000020+#define SZ_64				0x00000040+#define SZ_128				0x00000080+#define SZ_256				0x00000100+#define SZ_512				0x00000200++#define SZ_1K				0x00000400+#define SZ_2K				0x00000800+#define SZ_4K				0x00001000+#define SZ_8K				0x00002000+#define SZ_16K				0x00004000+#define SZ_32K				0x00008000+#define SZ_64K				0x00010000+#define SZ_128K				0x00020000+#define SZ_256K				0x00040000+#define SZ_512K				0x00080000++#define SZ_1M				0x00100000+#define SZ_2M				0x00200000+#define SZ_4M				0x00400000+#define SZ_8M				0x00800000+#define SZ_16M				0x01000000+#define SZ_32M				0x02000000+#define SZ_64M				0x04000000+#define SZ_128M				0x08000000+#define SZ_256M				0x10000000+#define SZ_512M				0x20000000++#define SZ_1G				0x40000000+#define SZ_2G				0x80000000++#endif /* __LINUX_SIZES_H__ */
include/sys/capability.h view
@@ -27,7 +27,6 @@ #define __user #endif #include <linux/capability.h>-#include <linux/xattr.h>  /*  * POSIX capability types