packages feed

btrfs 0.1.0.1 → 0.1.1.0

raw patch · 10 files changed

+215/−18 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ System.Linux.Btrfs: DefragRangeArgs :: FileSize -> FileSize -> Word32 -> Maybe CompressionType -> Bool -> DefragRangeArgs
+ System.Linux.Btrfs: LZO :: CompressionType
+ System.Linux.Btrfs: Zlib :: CompressionType
+ System.Linux.Btrfs: data CompressionType
+ System.Linux.Btrfs: data DefragRangeArgs
+ System.Linux.Btrfs: defaultDefragRangeArgs :: DefragRangeArgs
+ System.Linux.Btrfs: defragRange :: FilePath -> DefragRangeArgs -> IO ()
+ System.Linux.Btrfs: defragRangeFd :: Fd -> DefragRangeArgs -> IO ()
+ 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 CompressionType
+ System.Linux.Btrfs: instance Read CompressionType
+ System.Linux.Btrfs: instance Show CompressionType
+ System.Linux.Btrfs.ByteString: DefragRangeArgs :: FileSize -> FileSize -> Word32 -> Maybe CompressionType -> Bool -> DefragRangeArgs
+ System.Linux.Btrfs.ByteString: LZO :: CompressionType
+ System.Linux.Btrfs.ByteString: Zlib :: CompressionType
+ System.Linux.Btrfs.ByteString: data CompressionType
+ System.Linux.Btrfs.ByteString: data DefragRangeArgs
+ System.Linux.Btrfs.ByteString: defaultDefragRangeArgs :: DefragRangeArgs
+ System.Linux.Btrfs.ByteString: defragRange :: RawFilePath -> DefragRangeArgs -> IO ()
+ System.Linux.Btrfs.ByteString: defragRangeFd :: Fd -> DefragRangeArgs -> IO ()
+ 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 CompressionType
+ System.Linux.Btrfs.ByteString: instance Read CompressionType
+ System.Linux.Btrfs.ByteString: instance Show CompressionType

Files

+ ChangeLog view
@@ -0,0 +1,3 @@+v0.1.1.0++	* Support defraging file ranges.
System/Linux/Btrfs.hsc view
@@ -11,6 +11,7 @@ -}  {-# LANGUAGE CPP #-}+{-# LANGUAGE RecordWildCards #-}  #if BTRFS_RAW_PATHS ##define FILEPATH RawFilePath@@ -21,7 +22,7 @@ #endif     (     -- * Basic types-      FileSize, ObjectType, ObjectId, InodeNum, SubvolId+      FileSize, ObjectType, ObjectId, InodeNum, SubvolId, CompressionType(..)     -- * File cloning     , cloneFd, clone, cloneNew     , cloneRangeFd, cloneRange@@ -47,6 +48,8 @@     , getSubvolByReceivedUuidFd, getSubvolByReceivedUuid     -- * Defragging     , defragFd, defrag+    , DefragRangeArgs(..), defaultDefragRangeArgs+    , defragRangeFd, defragRange     -- * Sync     , syncFd, sync     , startSyncFd, startSync@@ -90,9 +93,9 @@ import System.Linux.Btrfs.Time import System.Linux.Btrfs.UUID -#include <linux/btrfs.h>-#define __IOCTL_+#include <btrfs/ioctl.h> #include <btrfs/ctree.h>+#include <missing.h>  #include <linux/fs.h> @@ -111,6 +114,9 @@  type SubvolId = ObjectId +data CompressionType = Zlib | LZO+    deriving (Show, Read, Eq, Enum, Bounded)+ --------------------------------------------------------------------------------  cloneFd :: Fd -> Fd -> IO ()@@ -325,7 +331,7 @@ snapshot     :: FILEPATH -- ^ The source subvolume.     -> FILEPATH -- ^ The destination subvolume (must not exist).-    -> Bool     -- ^ Make the subvolume read-only?+    -> Bool     -- ^ Create a read-only snapshot?     -> IO () snapshot srcPath dstPath readOnly =     withFd srcPath ReadOnly $ \srcFd ->@@ -680,6 +686,62 @@ defrag :: FILEPATH -> IO () defrag path = withFd path ReadWrite defragFd +-- | Argument to the 'defragRange' operation.+data DefragRangeArgs = DefragRangeArgs+    { draStart :: FileSize+        -- ^ Beginning of the defrag range.+    , draLength :: FileSize+        -- ^ Number of bytes to defrag, use 'maxBound' to say all.+    , draExtentThreshold :: Word32+        -- ^ Any extent bigger than this size will be considered already+        -- defragged. Use 0 to take the kernel default, use 1 to say every+        -- single extent must be rewritten.+    , draCompress :: Maybe CompressionType+        -- ^ Compress the file while defragmenting.+    , draFlush :: Bool+        -- ^ Flush data to disk immediately after defragmenting.+    }++-- | Defaults for 'defragRange'. Selects the entire file, no compression,+-- and no flushing.+defaultDefragRangeArgs :: DefragRangeArgs+defaultDefragRangeArgs = DefragRangeArgs+    { draStart = 0+    , draLength = maxBound+    , draExtentThreshold = 0+    , draCompress = Nothing+    , draFlush = False+    }++defragRangeFd :: Fd -> DefragRangeArgs -> IO ()+defragRangeFd fd DefragRangeArgs{..} =+    allocaBytesZero (#size struct btrfs_ioctl_defrag_range_args) $ \args -> do+        (#poke struct btrfs_ioctl_defrag_range_args, start        ) args draStart+        (#poke struct btrfs_ioctl_defrag_range_args, len          ) args draLength+        (#poke struct btrfs_ioctl_defrag_range_args, flags        ) args flags+        (#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+  where+    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))++-- | Defrag a range within a single file.+--+-- Note: calls the @BTRFS_IOC_DEFRAG_RANGE@ @ioctl@.+defragRange :: FILEPATH -> DefragRangeArgs -> IO ()+defragRange path args =+    withFd path ReadWrite $ \fd ->+        defragRangeFd fd args+ --------------------------------------------------------------------------------  syncFd :: Fd -> IO ()@@ -772,7 +834,7 @@     fspathSize = 2 * 1024 + (#size struct btrfs_data_container)  -- | Find the file path(s) given an inode number. Returns a list of file paths--- and an integer indicating the number of path found but not included in+-- and an integer indicating the number of paths found but not included in -- the resulting list. This is because of a limitation in the kernel (it -- will not return an arbitrarily large list). The paths returned are -- relative to the root of the subvolume.@@ -925,7 +987,7 @@         else do             let shPtr' = itemPtr `plusPtr` fromIntegral (shLen sh)             loopItems shPtr' (itemsFound - 1)-    -- items are index by keys which are (objectId, iType, offset)+    -- items are indexed by keys which are (objectId, iType, offset)     -- they are returned in lexicographical order wrt the keys     nextKey (objectId, iType, offset)         | offset   < maxBound         = Just (objectId, iType, offset + 1)
System/Linux/Btrfs/ByteString.hsc view
@@ -11,6 +11,7 @@ -}  {-# LANGUAGE CPP #-}+{-# LANGUAGE RecordWildCards #-}  #if BTRFS_RAW_PATHS ##define FILEPATH RawFilePath@@ -21,7 +22,7 @@ #endif     (     -- * Basic types-      FileSize, ObjectType, ObjectId, InodeNum, SubvolId+      FileSize, ObjectType, ObjectId, InodeNum, SubvolId, CompressionType(..)     -- * File cloning     , cloneFd, clone, cloneNew     , cloneRangeFd, cloneRange@@ -47,6 +48,8 @@     , getSubvolByReceivedUuidFd, getSubvolByReceivedUuid     -- * Defragging     , defragFd, defrag+    , DefragRangeArgs(..), defaultDefragRangeArgs+    , defragRangeFd, defragRange     -- * Sync     , syncFd, sync     , startSyncFd, startSync@@ -90,9 +93,9 @@ import System.Linux.Btrfs.Time import System.Linux.Btrfs.UUID -#include <linux/btrfs.h>-#define __IOCTL_+#include <btrfs/ioctl.h> #include <btrfs/ctree.h>+#include <missing.h>  #include <linux/fs.h> @@ -111,6 +114,9 @@  type SubvolId = ObjectId +data CompressionType = Zlib | LZO+    deriving (Show, Read, Eq, Enum, Bounded)+ --------------------------------------------------------------------------------  cloneFd :: Fd -> Fd -> IO ()@@ -325,7 +331,7 @@ snapshot     :: FILEPATH -- ^ The source subvolume.     -> FILEPATH -- ^ The destination subvolume (must not exist).-    -> Bool     -- ^ Make the subvolume read-only?+    -> Bool     -- ^ Create a read-only snapshot?     -> IO () snapshot srcPath dstPath readOnly =     withFd srcPath ReadOnly $ \srcFd ->@@ -680,6 +686,62 @@ defrag :: FILEPATH -> IO () defrag path = withFd path ReadWrite defragFd +-- | Argument to the 'defragRange' operation.+data DefragRangeArgs = DefragRangeArgs+    { draStart :: FileSize+        -- ^ Beginning of the defrag range.+    , draLength :: FileSize+        -- ^ Number of bytes to defrag, use 'maxBound' to say all.+    , draExtentThreshold :: Word32+        -- ^ Any extent bigger than this size will be considered already+        -- defragged. Use 0 to take the kernel default, use 1 to say every+        -- single extent must be rewritten.+    , draCompress :: Maybe CompressionType+        -- ^ Compress the file while defragmenting.+    , draFlush :: Bool+        -- ^ Flush data to disk immediately after defragmenting.+    }++-- | Defaults for 'defragRange'. Selects the entire file, no compression,+-- and no flushing.+defaultDefragRangeArgs :: DefragRangeArgs+defaultDefragRangeArgs = DefragRangeArgs+    { draStart = 0+    , draLength = maxBound+    , draExtentThreshold = 0+    , draCompress = Nothing+    , draFlush = False+    }++defragRangeFd :: Fd -> DefragRangeArgs -> IO ()+defragRangeFd fd DefragRangeArgs{..} =+    allocaBytesZero (#size struct btrfs_ioctl_defrag_range_args) $ \args -> do+        (#poke struct btrfs_ioctl_defrag_range_args, start        ) args draStart+        (#poke struct btrfs_ioctl_defrag_range_args, len          ) args draLength+        (#poke struct btrfs_ioctl_defrag_range_args, flags        ) args flags+        (#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+  where+    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))++-- | Defrag a range within a single file.+--+-- Note: calls the @BTRFS_IOC_DEFRAG_RANGE@ @ioctl@.+defragRange :: FILEPATH -> DefragRangeArgs -> IO ()+defragRange path args =+    withFd path ReadWrite $ \fd ->+        defragRangeFd fd args+ --------------------------------------------------------------------------------  syncFd :: Fd -> IO ()@@ -772,7 +834,7 @@     fspathSize = 2 * 1024 + (#size struct btrfs_data_container)  -- | Find the file path(s) given an inode number. Returns a list of file paths--- and an integer indicating the number of path found but not included in+-- and an integer indicating the number of paths found but not included in -- the resulting list. This is because of a limitation in the kernel (it -- will not return an arbitrarily large list). The paths returned are -- relative to the root of the subvolume.@@ -925,7 +987,7 @@         else do             let shPtr' = itemPtr `plusPtr` fromIntegral (shLen sh)             loopItems shPtr' (itemsFound - 1)-    -- items are index by keys which are (objectId, iType, offset)+    -- items are indexed by keys which are (objectId, iType, offset)     -- they are returned in lexicographical order wrt the keys     nextKey (objectId, iType, offset)         | offset   < maxBound         = Just (objectId, iType, offset + 1)
System/Linux/Btrfs/UUID.hs view
@@ -13,7 +13,6 @@ import Foreign.Ptr (castPtr) import Foreign.C.Types (CInt) --- | A @UUID@ is stored as two big-endian 'Word64's. data UUID = UUID Word64 Word64   deriving (Eq, Ord) @@ -22,6 +21,7 @@         showParen (p > 9) $             showString "fromString " . shows (toString u) +-- | A @UUID@ is stored as two big-endian 'Word64's. instance Storable UUID where     sizeOf _ = 16     alignment _ = alignment (undefined :: CInt)
btrfs.cabal view
@@ -1,5 +1,5 @@ name:                btrfs-version:             0.1.0.1+version:             0.1.1.0 synopsis:            Bindings to the btrfs API description:   This package provides low-level bindings to the btrfs API (i.e. the@@ -7,7 +7,7 @@   supported, including functions needed to work with subvolumes/snapshots   as well as file cloning.   .-  In order to build this package, you need to @linux-headers 3.9@ or newer.+  In order to build this package, @linux-headers@ need 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.@@ -23,6 +23,8 @@ cabal-version:       >=1.10  extra-source-files:+  ChangeLog+  include/missing.h   include/btrfs/ctree.h   include/btrfs/extent-cache.h   include/btrfs/extent_io.h
include/btrfs/ctree.h view
@@ -40,6 +40,8 @@ struct btrfs_free_space_ctl; #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ +#define BTRFS_MAX_MIRRORS 3+ #define BTRFS_MAX_LEVEL 8  #define BTRFS_COMPAT_EXTENT_TREE_V0@@ -943,6 +945,7 @@ 	struct btrfs_root *chunk_root; 	struct btrfs_root *dev_root; 	struct btrfs_root *csum_root;+	struct btrfs_root *quota_root;  	struct rb_root fs_root_tree; @@ -988,6 +991,7 @@ 	unsigned int readonly:1; 	unsigned int on_restoring:1; 	unsigned int is_chunk_recover:1;+	unsigned int quota_enabled:1;  	int (*free_extent_hook)(struct btrfs_trans_handle *trans, 				struct btrfs_root *root,@@ -2382,4 +2386,12 @@ int btrfs_lookup_uuid_subvol_item(int fd, const u8 *uuid, u64 *subvol_id); int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid, 					   u64 *subvol_id);++static inline int is_fstree(u64 rootid)+{+	if (rootid == BTRFS_FS_TREE_OBJECTID ||+	    (signed long long)rootid >= (signed long long)BTRFS_FIRST_FREE_OBJECTID)+		return 1;+	return 0;+} #endif
include/btrfs/ioctl.h view
@@ -194,7 +194,9 @@  	__u64 flags; -	__u64 unused[8];+	__u64 limit;++	__u64 unused[7]; } __attribute__ ((__packed__));  struct btrfs_balance_progress {
include/btrfs/kerncompat.h view
@@ -28,7 +28,11 @@ #include <assert.h> #include <stddef.h> #include <linux/types.h>+#include <stdint.h> +#define ptr_to_u64(x)	((u64)(uintptr_t)x)+#define u64_to_ptr(x)	((void *)(uintptr_t)x)+ #ifndef READ #define READ 0 #define WRITE 1@@ -235,7 +239,7 @@  #define BUG_ON(c) assert(!(c)) #define WARN_ON(c) assert(!(c))-+#define	ASSERT(c) assert(c)  #define container_of(ptr, type, member) ({                      \         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+ include/missing.h view
@@ -0,0 +1,48 @@+/*+ * 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
make-bytestring.hs view
@@ -13,6 +13,8 @@     withFile "System/Linux/Btrfs/ByteString.hsc" WriteMode $ \oHdl -> do         hPutStrLn oHdl "#define BTRFS_RAW_PATHS 1"         withFile "System/Linux/Btrfs.hsc" ReadMode $ \iHdl -> do-            _ <- hGetLine iHdl -- skip the first line+            s <- hGetLine iHdl -- skip the first line+            unless (s == "#define BTRFS_RAW_PATHS 0") $+                fail "the first line does not have the expected contents"             contents <- hGetContents iHdl             hPutStr oHdl contents