btrfs 0.1.2.0 → 0.1.2.1
raw patch · 12 files changed
+222/−109 lines, 12 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
Files
- ChangeLog +5/−0
- System/Linux/Btrfs.hsc +17/−11
- System/Linux/Btrfs/ByteString.hsc +17/−11
- System/Linux/Capabilities.hsc +35/−0
- btrfs.cabal +3/−2
- examples/btrfs-defrag.hs +27/−19
- include/btrfs/ctree.h +51/−20
- include/btrfs/extent-cache.h +1/−1
- include/btrfs/extent_io.h +36/−17
- include/btrfs/ioctl.h +18/−5
- include/btrfs/kerncompat.h +11/−22
- include/btrfs/rbtree.h +1/−1
ChangeLog view
@@ -1,3 +1,8 @@+v0.1.2.1++ * Support cloneRangeIfSame on read-only subvolumes (requires+ CAP_SYS_ADMIN).+ v0.1.2.0 * Expose System.Linux.Btrfs.Time.
System/Linux/Btrfs.hsc view
@@ -23,7 +23,7 @@ ( -- * Basic types FileSize, ObjectType, ObjectId, InodeNum, SubvolId, CompressionType(..)- -- * File cloning+ -- * File cloning/deduplication , cloneFd, clone, cloneNew , cloneRangeFd, cloneRange , CloneResult(..)@@ -95,6 +95,7 @@ import Data.Word.Endian import System.Linux.Btrfs.Time import System.Linux.Btrfs.UUID+import System.Linux.Capabilities #include <btrfs/ioctl.h> #include <btrfs/ctree.h>@@ -130,7 +131,7 @@ -- | Clone an entire file to an existing file. ----- Note: calls the @BTRFS_IOC_CLONE@ @ioctl@.+-- Note: calls the @BTRFS_IOC_CLONE@/@FICLONE@ @ioctl@. clone :: FILEPATH -- ^ The source file. -> FILEPATH -- ^ The destination file.@@ -143,7 +144,7 @@ -- | Like 'clone' except that it will create or truncate the destination -- file if necessary. This is similar to @cp --reflink=always@. ----- Note: calls the @BTRFS_IOC_CLONE@ @ioctl@.+-- Note: calls the @BTRFS_IOC_CLONE@/@FICLONE@ @ioctl@. cloneNew :: FILEPATH -> FILEPATH -> IO () cloneNew srcPath dstPath = withFd srcPath ReadOnly $ \srcFd -> do@@ -165,7 +166,7 @@ -- | Clones a range of bytes from a file to another file. All ranges must -- be block-aligned. ----- Note: calls the @BTRFS_IOC_CLONE_RANGE@ @ioctl@.+-- Note: calls the @BTRFS_IOC_CLONE_RANGE@/@FICLONERANGE@ @ioctl@. cloneRange :: FILEPATH -- ^ The source file. -> FileSize -- ^ The offset within the source file.@@ -270,7 +271,7 @@ -- function returns a list of outcomes, one for each destination file, and -- no exceptions will be raised for the failed files. ----- Note: calls the @BTRFS_IOC_FILE_EXTENT_SAME@ @ioctl@.+-- Note: calls the @BTRFS_IOC_FILE_EXTENT_SAME@/@FIDEDUPERANGE@ @ioctl@. -- -- /Requires Linux 3.12 or later./ cloneRangeIfSame@@ -279,14 +280,19 @@ -> FileSize -- ^ The length of the range. -> [(FILEPATH, FileSize)] -- ^ The destination files and corresponding offsets. -> IO [CloneResult]-cloneRangeIfSame srcPath srcOff srcLen dstsP0 =+cloneRangeIfSame srcPath srcOff srcLen dstsP0 = do+ -- we check if the process has the CAP_SYS_ADMIN capability+ -- if it does we use ReadOnly to open the destination files+ -- this allows privileged users to operate on readonly snapshots+ isAdmin <- hasSysAdminCap+ let openMode = if isAdmin then ReadOnly else WriteOnly withFd srcPath ReadOnly $ \srcFd ->- loop srcFd (reverse dstsP0) []+ loop srcFd openMode (reverse dstsP0) [] where- loop srcFd ((dstPath, dstOff) : dstsP) dsts =- withFd dstPath WriteOnly $ \fd ->- loop srcFd dstsP ((fd, dstOff) : dsts)- loop srcFd [] dsts =+ loop srcFd openMode ((dstPath, dstOff) : dstsP) dsts =+ withFd dstPath openMode $ \fd ->+ loop srcFd openMode dstsP ((fd, dstOff) : dsts)+ loop srcFd _ [] dsts = cloneRangeIfSameFd srcFd srcOff srcLen dsts --------------------------------------------------------------------------------
System/Linux/Btrfs/ByteString.hsc view
@@ -23,7 +23,7 @@ ( -- * Basic types FileSize, ObjectType, ObjectId, InodeNum, SubvolId, CompressionType(..)- -- * File cloning+ -- * File cloning/deduplication , cloneFd, clone, cloneNew , cloneRangeFd, cloneRange , CloneResult(..)@@ -95,6 +95,7 @@ import Data.Word.Endian import System.Linux.Btrfs.Time import System.Linux.Btrfs.UUID+import System.Linux.Capabilities #include <btrfs/ioctl.h> #include <btrfs/ctree.h>@@ -130,7 +131,7 @@ -- | Clone an entire file to an existing file. ----- Note: calls the @BTRFS_IOC_CLONE@ @ioctl@.+-- Note: calls the @BTRFS_IOC_CLONE@/@FICLONE@ @ioctl@. clone :: FILEPATH -- ^ The source file. -> FILEPATH -- ^ The destination file.@@ -143,7 +144,7 @@ -- | Like 'clone' except that it will create or truncate the destination -- file if necessary. This is similar to @cp --reflink=always@. ----- Note: calls the @BTRFS_IOC_CLONE@ @ioctl@.+-- Note: calls the @BTRFS_IOC_CLONE@/@FICLONE@ @ioctl@. cloneNew :: FILEPATH -> FILEPATH -> IO () cloneNew srcPath dstPath = withFd srcPath ReadOnly $ \srcFd -> do@@ -165,7 +166,7 @@ -- | Clones a range of bytes from a file to another file. All ranges must -- be block-aligned. ----- Note: calls the @BTRFS_IOC_CLONE_RANGE@ @ioctl@.+-- Note: calls the @BTRFS_IOC_CLONE_RANGE@/@FICLONERANGE@ @ioctl@. cloneRange :: FILEPATH -- ^ The source file. -> FileSize -- ^ The offset within the source file.@@ -270,7 +271,7 @@ -- function returns a list of outcomes, one for each destination file, and -- no exceptions will be raised for the failed files. ----- Note: calls the @BTRFS_IOC_FILE_EXTENT_SAME@ @ioctl@.+-- Note: calls the @BTRFS_IOC_FILE_EXTENT_SAME@/@FIDEDUPERANGE@ @ioctl@. -- -- /Requires Linux 3.12 or later./ cloneRangeIfSame@@ -279,14 +280,19 @@ -> FileSize -- ^ The length of the range. -> [(FILEPATH, FileSize)] -- ^ The destination files and corresponding offsets. -> IO [CloneResult]-cloneRangeIfSame srcPath srcOff srcLen dstsP0 =+cloneRangeIfSame srcPath srcOff srcLen dstsP0 = do+ -- we check if the process has the CAP_SYS_ADMIN capability+ -- if it does we use ReadOnly to open the destination files+ -- this allows privileged users to operate on readonly snapshots+ isAdmin <- hasSysAdminCap+ let openMode = if isAdmin then ReadOnly else WriteOnly withFd srcPath ReadOnly $ \srcFd ->- loop srcFd (reverse dstsP0) []+ loop srcFd openMode (reverse dstsP0) [] where- loop srcFd ((dstPath, dstOff) : dstsP) dsts =- withFd dstPath WriteOnly $ \fd ->- loop srcFd dstsP ((fd, dstOff) : dsts)- loop srcFd [] dsts =+ loop srcFd openMode ((dstPath, dstOff) : dstsP) dsts =+ withFd dstPath openMode $ \fd ->+ loop srcFd openMode dstsP ((fd, dstOff) : dsts)+ loop srcFd _ [] dsts = cloneRangeIfSameFd srcFd srcOff srcLen dsts --------------------------------------------------------------------------------
+ System/Linux/Capabilities.hsc view
@@ -0,0 +1,35 @@+module System.Linux.Capabilities+ ( hasSysAdminCap+ ) where++import Foreign+import Foreign.C+import System.Posix (getProcessID)++#include <sys/capability.h>++-- It's probably a bad idea to use the capget syscall instead of the+-- functions from libcap, but this way we avoid the dependecy on libcap.++hasSysAdminCap :: IO Bool+hasSysAdminCap =+ flip testBit (#const CAP_SYS_ADMIN) <$> getCapabilities++getCapabilities :: IO Word64+getCapabilities =+ allocaBytes (#size struct __user_cap_header_struct) $ \hdrp ->+ allocaBytes (2 * (#size struct __user_cap_data_struct)) $ \datap -> do+ pid <- getProcessID+ (#poke struct __user_cap_header_struct, version) hdrp ((#const _LINUX_CAPABILITY_VERSION_2) :: Word32)+ (#poke struct __user_cap_header_struct, pid) hdrp (fromIntegral pid :: Word32)+ throwErrnoIfMinus1_ "capget" $ c_capget hdrp datap+ effective0 <- (#peek struct __user_cap_data_struct, effective) datap :: IO Word32+ let datap1 = datap `plusPtr` (#size struct __user_cap_data_struct)+ effective1 <- (#peek struct __user_cap_data_struct, effective) datap1 :: IO Word32+ return (fromIntegral effective1 `unsafeShiftL` 32 .|. fromIntegral effective0)++data CapUserHeader+data CapUserData++foreign import ccall unsafe "sys/capability.h capget"+ c_capget :: Ptr CapUserHeader -> Ptr CapUserData -> IO CInt
btrfs.cabal view
@@ -1,5 +1,5 @@ name: btrfs-version: 0.1.2.0+version: 0.1.2.1 synopsis: Bindings to the btrfs API description: This package provides bindings to the low-level btrfs API (i.e. the@@ -46,7 +46,8 @@ exposed-modules: System.Linux.Btrfs, System.Linux.Btrfs.ByteString, System.Linux.Btrfs.UUID, System.Linux.Btrfs.Time other-modules: Data.Word.Endian,- System.Linux.Btrfs.FilePathLike+ System.Linux.Btrfs.FilePathLike,+ System.Linux.Capabilities build-depends: base >=4.6 && <5, unix >=2.6, time >=1.4, bytestring >=0.9 include-dirs: include
examples/btrfs-defrag.hs view
@@ -4,7 +4,6 @@ import Control.Monad.Fix import Control.Exception import Control.Arrow ((***))-import Data.Monoid import Data.IORef import Text.Printf import System.Posix@@ -21,8 +20,8 @@ hSetBuffering stdout LineBuffering hSetBuffering stderr LineBuffering paths <- getArgs- statsRef <- newIORef mempty- printStats mempty+ statsRef <- newIORef zeroStats+ printStats zeroStats mapM_ (flip traverseTree (defragFile statsRef)) paths putChar '\n' @@ -30,18 +29,25 @@ defragFile statsRef path stat | isRegularFile stat = do extBefore <- getExtentCount defReqFlags path Nothing- when (extBefore > 1) $ do -- skip files with 1 extent- handleIOExn $ defragRange path dra- extAfter <- getExtentCount defReqFlags path Nothing- stats <- readIORef statsRef- let stats' = stats <> Stats- { stFiles = 1- , stBytes = fromIntegral (fileSize stat)- , stExtentsBefore = fromIntegral extBefore- , stExtentsAfter = fromIntegral extAfter+ stats <- readIORef statsRef+ stats' <-+ if extBefore <= 1 then+ return $ stats+ { stSkippedFiles = stSkippedFiles stats + 1+ , stSkippedBytes =+ stSkippedBytes stats + fromIntegral (fileSize stat) }- writeIORef statsRef stats'- printStats stats'+ else do+ handleIOExn $ defragRange path dra+ extAfter <- getExtentCount defReqFlags path Nothing+ return $ stats+ { stFiles = stFiles stats + 1+ , stBytes = stBytes stats + fromIntegral (fileSize stat)+ , stExtentsBefore = stExtentsBefore stats + fromIntegral extBefore+ , stExtentsAfter = stExtentsAfter stats + fromIntegral extAfter+ }+ writeIORef statsRef stats'+ printStats stats' | otherwise = return () where dra = defaultDefragRangeArgs@@ -78,20 +84,22 @@ data Stats = Stats { stFiles :: !Int , stBytes :: !Integer+ , stSkippedFiles :: !Int+ , stSkippedBytes :: !Integer , stExtentsBefore :: !Int , stExtentsAfter :: !Int } -instance Monoid Stats where- mempty = Stats 0 0 0 0- mappend (Stats a1 b1 c1 d1) (Stats a2 b2 c2 d2) =- Stats (a1 + a2) (b1 + b2) (c1 + c2) (d1 + d2)+zeroStats :: Stats+zeroStats = Stats 0 0 0 0 0 0 printStats :: Stats -> IO () printStats Stats{..} = do- printf "\rprocessed: %d file(s)/%s, extents (before/after): %d/%d"+ printf "\rprocessed: %d file(s)/%s, skipped: %d file(s)/%s, extents (before/after): %d/%d" stFiles (prettyFileSize stBytes)+ stSkippedFiles+ (prettyFileSize stSkippedBytes) stExtentsBefore stExtentsAfter clearFromCursorToLineEnd
include/btrfs/ctree.h view
@@ -173,7 +173,7 @@ /* * the key defines the order in the tree, and so it also defines (optimal)- * block layout. objectid corresonds to the inode number. The flags+ * block layout. objectid corresponds to the inode number. The flags * tells us things about the object, and is a kind of stream selector. * so for a given inode, keys with flags of 1 might refer to the inode * data, flags of 2 may point to file data in the btree and flags == 3@@ -229,7 +229,7 @@ /* * starting byte of this partition on the device,- * to allowr for stripe alignment in the future+ * to allow for stripe alignment in the future */ __le64 start_offset; @@ -345,7 +345,7 @@ 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->leafsize))+#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))@@ -428,6 +428,7 @@ __le64 num_devices; __le32 sectorsize; __le32 nodesize;+ /* Unused and must be equal to nodesize */ __le32 leafsize; __le32 stripesize; __le32 sys_chunk_array_size;@@ -483,7 +484,8 @@ #define BTRFS_FEATURE_COMPAT_SUPP 0ULL -#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL+#define BTRFS_FEATURE_COMPAT_RO_SUPP \+ (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) #define BTRFS_FEATURE_INCOMPAT_SUPP \ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \@@ -576,6 +578,7 @@ #define BTRFS_MAX_EXTENT_ITEM_SIZE(r) ((BTRFS_LEAF_DATA_SIZE(r) >> 4) - \ sizeof(struct btrfs_item))+#define BTRFS_MAX_EXTENT_SIZE (128 * 1024 * 1024) #define BTRFS_EXTENT_FLAG_DATA (1ULL << 0) #define BTRFS_EXTENT_FLAG_TREE_BLOCK (1ULL << 1)@@ -744,7 +747,7 @@ /* * This generation number is used to test if the new fields are valid- * and up to date while reading the root item. Everytime the root item+ * and up to date while reading the root item. Every time the root item * is written out, the "generation" field is copied into this field. If * anyone ever mounted the fs with an older kernel, we will have * mismatching generation values here and thus must invalidate the@@ -895,7 +898,7 @@ __le64 version; __le64 generation; __le64 flags;- __le64 scan; /* progress during scanning */+ __le64 rescan; /* progress during scanning */ } __attribute__ ((__packed__)); struct btrfs_block_group_item {@@ -957,13 +960,6 @@ int ro; }; -struct btrfs_extent_ops {- int (*alloc_extent)(struct btrfs_root *root, u64 num_bytes,- u64 hint_byte, struct btrfs_key *ins, int metadata);- int (*free_extent)(struct btrfs_root *root, u64 bytenr,- u64 num_bytes);-};- struct btrfs_device; struct btrfs_fs_devices; struct btrfs_fs_info {@@ -1014,7 +1010,6 @@ u64 super_bytenr; u64 total_pinned; - struct btrfs_extent_ops *extent_ops; struct list_head dirty_cowonly_roots; struct list_head recow_ebs; @@ -1028,6 +1023,9 @@ unsigned int quota_enabled:1; unsigned int suppress_check_block_errors:1; unsigned int ignore_fsid_mismatch:1;+ unsigned int ignore_chunk_tree_error:1;+ unsigned int avoid_meta_chunk_alloc:1;+ unsigned int avoid_sys_chunk_alloc:1; int (*free_extent_hook)(struct btrfs_trans_handle *trans, struct btrfs_root *root,@@ -1058,10 +1056,10 @@ /* node allocations are done in nodesize units */ u32 nodesize; - /* leaf allocations are done in leafsize units */+ /* Unused, equal to nodesize */ u32 leafsize; - /* leaf allocations are done in leafsize units */+ /* leaf allocations are done in nodesize units */ u32 stripesize; int ref_cows;@@ -2127,8 +2125,8 @@ generation, 64); BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64);-BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item,- scan, 64);+BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item,+ rescan, 64); BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_version, struct btrfs_qgroup_status_item, version, 64);@@ -2136,8 +2134,8 @@ struct btrfs_qgroup_status_item, generation, 64); BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64);-BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_scan,- struct btrfs_qgroup_status_item, scan, 64);+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_rescan,+ struct btrfs_qgroup_status_item, rescan, 64); /* btrfs_qgroup_info_item */ BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item,@@ -2198,6 +2196,32 @@ return btrfs_item_size(eb, e) - offset; } +/* struct btrfs_ioctl_search_header */+static inline u64 btrfs_search_header_transid(struct btrfs_ioctl_search_header *sh)+{+ return get_unaligned_64(&sh->transid);+}++static inline u64 btrfs_search_header_objectid(struct btrfs_ioctl_search_header *sh)+{+ return get_unaligned_64(&sh->objectid);+}++static inline u64 btrfs_search_header_offset(struct btrfs_ioctl_search_header *sh)+{+ return get_unaligned_64(&sh->offset);+}++static inline u32 btrfs_search_header_type(struct btrfs_ioctl_search_header *sh)+{+ return get_unaligned_32(&sh->type);+}++static inline u32 btrfs_search_header_len(struct btrfs_ioctl_search_header *sh)+{+ 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 */@@ -2220,6 +2244,11 @@ 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;@@ -2354,6 +2383,8 @@ int type); int btrfs_previous_extent_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid);+int btrfs_next_extent_item(struct btrfs_root *root,+ struct btrfs_path *path, u64 max_objectid); int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot,
include/btrfs/extent-cache.h view
@@ -53,7 +53,7 @@ struct cache_extent *search_cache_extent(struct cache_tree *tree, u64 start); /*- * Find a cahce_extent which restrictly covers start.+ * Find a cache_extent which restrictly covers start. * * If not found, return NULL. */
include/btrfs/extent_io.h view
@@ -29,26 +29,45 @@ #include <btrfs/list.h> #endif /* BTRFS_FLAT_INCLUDES */ -#define EXTENT_DIRTY 1-#define EXTENT_WRITEBACK (1 << 1)-#define EXTENT_UPTODATE (1 << 2)-#define EXTENT_LOCKED (1 << 3)-#define EXTENT_NEW (1 << 4)-#define EXTENT_DELALLOC (1 << 5)-#define EXTENT_DEFRAG (1 << 6)-#define EXTENT_DEFRAG_DONE (1 << 7)-#define EXTENT_BUFFER_FILLED (1 << 8)-#define EXTENT_CSUM (1 << 9)-#define EXTENT_BAD_TRANSID (1 << 10)-#define EXTENT_BUFFER_DUMMY (1 << 11)+#define EXTENT_DIRTY (1U << 0)+#define EXTENT_WRITEBACK (1U << 1)+#define EXTENT_UPTODATE (1U << 2)+#define EXTENT_LOCKED (1U << 3)+#define EXTENT_NEW (1U << 4)+#define EXTENT_DELALLOC (1U << 5)+#define EXTENT_DEFRAG (1U << 6)+#define EXTENT_DEFRAG_DONE (1U << 7)+#define EXTENT_BUFFER_FILLED (1U << 8)+#define EXTENT_CSUM (1U << 9)+#define EXTENT_BAD_TRANSID (1U << 10)+#define EXTENT_BUFFER_DUMMY (1U << 11) #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) -#define BLOCK_GROUP_DATA EXTENT_WRITEBACK-#define BLOCK_GROUP_METADATA EXTENT_UPTODATE-#define BLOCK_GROUP_SYSTEM EXTENT_NEW+#define BLOCK_GROUP_DATA (1U << 1)+#define BLOCK_GROUP_METADATA (1U << 2)+#define BLOCK_GROUP_SYSTEM (1U << 4) -#define BLOCK_GROUP_DIRTY EXTENT_DIRTY+#define BLOCK_GROUP_DIRTY (1U) +/*+ * The extent buffer bitmap operations are done with byte granularity instead of+ * word granularity for two reasons:+ * 1. The bitmaps must be little-endian on disk.+ * 2. Bitmap items are not guaranteed to be aligned to a word and therefore a+ * single word in a bitmap may straddle two pages in the extent buffer.+ */+#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)+#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)+#define BITMAP_FIRST_BYTE_MASK(start) \+ ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)+#define BITMAP_LAST_BYTE_MASK(nbits) \+ (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))++static inline int le_test_bit(int nr, const u8 *addr)+{+ return 1U & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE-1)));+}+ struct btrfs_fs_info; struct extent_io_tree {@@ -76,7 +95,7 @@ struct list_head lru; struct list_head recow; int refs;- int flags;+ u32 flags; int fd; char data[]; };
include/btrfs/ioctl.h view
@@ -45,6 +45,14 @@ #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) #define BTRFS_SUBVOL_RDONLY (1ULL << 1) #define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2)+#define BTRFS_DEVICE_SPEC_BY_ID (1ULL << 3)++#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED \+ (BTRFS_SUBVOL_CREATE_ASYNC | \+ BTRFS_SUBVOL_RDONLY | \+ BTRFS_SUBVOL_QGROUP_INHERIT | \+ BTRFS_DEVICE_SPEC_BY_ID)+ #define BTRFS_FSID_SIZE 16 #define BTRFS_UUID_SIZE 16 @@ -84,7 +92,10 @@ }; __u64 unused[4]; };- char name[BTRFS_SUBVOL_NAME_MAX + 1];+ union {+ char name[BTRFS_SUBVOL_NAME_MAX + 1];+ __u64 devid;+ }; }; /*@@ -98,7 +109,7 @@ __u64 tree_bytes_scrubbed; /* # of tree bytes scrubbed */ __u64 read_errors; /* # of read errors encountered (EIO) */ __u64 csum_errors; /* # of failed csum checks */- __u64 verify_errors; /* # of occurences, where the metadata+ __u64 verify_errors; /* # of occurrences, where the metadata * of a tree block did not match the * expected values, like generation or * logical */@@ -118,7 +129,7 @@ __u64 last_physical; /* last physical address scrubbed. In * case a scrub was aborted, this can * be used to restart the scrub */- __u64 unverified_errors; /* # of occurences where a read for a+ __u64 unverified_errors; /* # of occurrences where a read for a * full (64k) bio failed, but the re- * check succeeded for each 4k piece. * Intermittent error. */@@ -260,7 +271,7 @@ /* report balance progress to userspace */ struct btrfs_balance_progress { __u64 expected; /* estimated # of chunks that will be- * relocated to fulfill the request */+ * relocated to fulfil the request */ __u64 considered; /* # of chunks we have considered so far */ __u64 completed; /* # of chunks relocated so far */ };@@ -674,7 +685,7 @@ #define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \ struct btrfs_ioctl_ino_path_args) #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \- struct btrfs_ioctl_ino_path_args)+ struct btrfs_ioctl_logical_ino_args) #define BTRFS_IOC_SET_RECEIVED_SUBVOL _IOWR(BTRFS_IOCTL_MAGIC, 37, \ struct btrfs_ioctl_received_subvol_args) #define BTRFS_IOC_SEND _IOW(BTRFS_IOCTL_MAGIC, 38, struct btrfs_ioctl_send_args)@@ -709,6 +720,8 @@ struct btrfs_ioctl_feature_flags[2]) #define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \ struct btrfs_ioctl_feature_flags[3])+#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \+ struct btrfs_ioctl_vol_args_v2) #ifdef __cplusplus } #endif
include/btrfs/kerncompat.h view
@@ -55,7 +55,8 @@ #define gfp_t int #define get_cpu_var(p) (p) #define __get_cpu_var(p) (p)-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)+#define BITS_PER_BYTE 8+#define BITS_PER_LONG (__SIZEOF_LONG__ * BITS_PER_BYTE) #define __GFP_BITS_SHIFT 20 #define __GFP_BITS_MASK ((int)((1 << __GFP_BITS_SHIFT) - 1)) #define GFP_KERNEL 0@@ -72,7 +73,7 @@ static inline void print_trace(void) { void *array[MAX_BACKTRACE];- size_t size;+ int size; size = backtrace(array, MAX_BACKTRACE); backtrace_symbols_fd(array, size, 2);@@ -241,26 +242,6 @@ } /*- * max/min macro- */-#define min(x,y) ({ \- typeof(x) _x = (x); \- typeof(y) _y = (y); \- (void) (&_x == &_y); \- _x < _y ? _x : _y; })--#define max(x,y) ({ \- typeof(x) _x = (x); \- typeof(y) _y = (y); \- (void) (&_x == &_y); \- _x > _y ? _x : _y; })--#define min_t(type,x,y) \- ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })-#define max_t(type,x,y) \- ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })--/* * 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 * as wide as the result!), and we want to evaluate the macro@@ -354,13 +335,21 @@ struct __una_u64 { __le64 x; } __attribute__((__packed__)); #define get_unaligned_le8(p) (*((u8 *)(p)))+#define get_unaligned_8(p) (*((u8 *)(p))) #define put_unaligned_le8(val,p) ((*((u8 *)(p))) = (val))+#define put_unaligned_8(val,p) ((*((u8 *)(p))) = (val)) #define get_unaligned_le16(p) le16_to_cpu(((const struct __una_u16 *)(p))->x)+#define get_unaligned_16(p) (((const struct __una_u16 *)(p))->x) #define put_unaligned_le16(val,p) (((struct __una_u16 *)(p))->x = cpu_to_le16(val))+#define put_unaligned_16(val,p) (((struct __una_u16 *)(p))->x = (val)) #define get_unaligned_le32(p) le32_to_cpu(((const struct __una_u32 *)(p))->x)+#define get_unaligned_32(p) (((const struct __una_u32 *)(p))->x) #define put_unaligned_le32(val,p) (((struct __una_u32 *)(p))->x = cpu_to_le32(val))+#define put_unaligned_32(val,p) (((struct __una_u32 *)(p))->x = (val)) #define get_unaligned_le64(p) le64_to_cpu(((const struct __una_u64 *)(p))->x)+#define get_unaligned_64(p) (((const struct __una_u64 *)(p))->x) #define put_unaligned_le64(val,p) (((struct __una_u64 *)(p))->x = cpu_to_le64(val))+#define put_unaligned_64(val,p) (((struct __una_u64 *)(p))->x = (val)) #ifndef true #define true 1
include/btrfs/rbtree.h view
@@ -57,7 +57,7 @@ #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) -/* 'empty' nodes are nodes that are known not to be inserted in an rbree */+/* 'empty' nodes are nodes that are known not to be inserted in an rtbree */ #define RB_EMPTY_NODE(node) \ ((node)->__rb_parent_color == (unsigned long)(node)) #define RB_CLEAR_NODE(node) \