Hello community, here is the log from the commit of package ghc-btrfs for openSUSE:Factory checked in at 2017-03-14 10:04:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-btrfs (Old) and /work/SRC/openSUSE:Factory/.ghc-btrfs.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-btrfs" Tue Mar 14 10:04:21 2017 rev:2 rq:461607 version:0.1.2.3 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-btrfs/ghc-btrfs.changes 2016-09-25 14:35:38.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-btrfs.new/ghc-btrfs.changes 2017-03-14 10:04:21.618955416 +0100 @@ -1,0 +2,5 @@ +Sun Feb 12 14:14:05 UTC 2017 - [email protected] + +- Update to version 0.1.2.3 with cabal2obs. + +------------------------------------------------------------------- Old: ---- btrfs-0.1.2.0.tar.gz New: ---- btrfs-0.1.2.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-btrfs.spec ++++++ --- /var/tmp/diff_new_pack.IdveZg/_old 2017-03-14 10:04:22.066891988 +0100 +++ /var/tmp/diff_new_pack.IdveZg/_new 2017-03-14 10:04:22.066891988 +0100 @@ -1,7 +1,7 @@ # # spec file for package ghc-btrfs # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,21 +18,19 @@ %global pkg_name btrfs Name: ghc-%{pkg_name} -Version: 0.1.2.0 +Version: 0.1.2.3 Release: 0 Summary: Bindings to the btrfs API License: BSD-3-Clause -Group: System/Libraries +Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel -# Begin cabal-rpm deps: BuildRequires: ghc-bytestring-devel BuildRequires: ghc-rpm-macros BuildRequires: ghc-time-devel BuildRequires: ghc-unix-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build -# End cabal-rpm deps %description This package provides bindings to the low-level btrfs API (i.e. the @@ -60,15 +58,12 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %post devel %ghc_pkg_recache ++++++ btrfs-0.1.2.0.tar.gz -> btrfs-0.1.2.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/ChangeLog new/btrfs-0.1.2.3/ChangeLog --- old/btrfs-0.1.2.0/ChangeLog 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/ChangeLog 2017-01-30 01:49:23.000000000 +0100 @@ -1,3 +1,17 @@ +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. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/System/Linux/Btrfs/ByteString.hsc new/btrfs-0.1.2.3/System/Linux/Btrfs/ByteString.hsc --- old/btrfs-0.1.2.0/System/Linux/Btrfs/ByteString.hsc 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/System/Linux/Btrfs/ByteString.hsc 2017-01-30 01:49:23.000000000 +0100 @@ -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 -------------------------------------------------------------------------------- @@ -307,7 +313,10 @@ createSubvol path = simpleSubvolOp "createSubvol" path (#const BTRFS_IOC_SUBVOL_CREATE) --- | Destroy (delete) a subvolume. +-- | Destroy (delete) a subvolume. The directory that corresponds to the +-- subvolume is removed asynchronously. As a result, the subvolume may +-- appear again after a crash. If this is not acceptable, call 'startSync' +-- followed by a 'waitSync', after the @destroySubvol@ call. -- -- Note: calls the @BTRFS_IOC_SNAP_DESTROY@ @ioctl@. destroySubvol :: FILEPATH -> IO () diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/System/Linux/Btrfs/UUID.hs new/btrfs-0.1.2.3/System/Linux/Btrfs/UUID.hs --- old/btrfs-0.1.2.0/System/Linux/Btrfs/UUID.hs 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/System/Linux/Btrfs/UUID.hs 2017-01-30 01:49:23.000000000 +0100 @@ -52,11 +52,11 @@ s' = filter (/= '-') s isValidUUID :: String -> Bool -isValidUUID = and . zipWith checkChar [0..] +isValidUUID s = length s == 36 && and (zipWith checkChar [0..] s) where checkChar i c = if i `elem` hyphenPosns then c == '-' else - c `elem` "0123456789abcdefABCDEF" + ('0' <= c && c <= '9') || ('a' <= c && c <= 'f')|| ('A' <= c && c <= 'F') hyphenPosns = [8, 13, 18, 23] :: [Int] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/System/Linux/Btrfs.hsc new/btrfs-0.1.2.3/System/Linux/Btrfs.hsc --- old/btrfs-0.1.2.0/System/Linux/Btrfs.hsc 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/System/Linux/Btrfs.hsc 2017-01-30 01:49:23.000000000 +0100 @@ -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 -------------------------------------------------------------------------------- @@ -307,7 +313,10 @@ createSubvol path = simpleSubvolOp "createSubvol" path (#const BTRFS_IOC_SUBVOL_CREATE) --- | Destroy (delete) a subvolume. +-- | Destroy (delete) a subvolume. The directory that corresponds to the +-- subvolume is removed asynchronously. As a result, the subvolume may +-- appear again after a crash. If this is not acceptable, call 'startSync' +-- followed by a 'waitSync', after the @destroySubvol@ call. -- -- Note: calls the @BTRFS_IOC_SNAP_DESTROY@ @ioctl@. destroySubvol :: FILEPATH -> IO () diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/System/Linux/Capabilities.hsc new/btrfs-0.1.2.3/System/Linux/Capabilities.hsc --- old/btrfs-0.1.2.0/System/Linux/Capabilities.hsc 1970-01-01 01:00:00.000000000 +0100 +++ new/btrfs-0.1.2.3/System/Linux/Capabilities.hsc 2017-01-30 01:49:23.000000000 +0100 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/btrfs.cabal new/btrfs-0.1.2.3/btrfs.cabal --- old/btrfs-0.1.2.0/btrfs.cabal 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/btrfs.cabal 2017-01-30 01:49:23.000000000 +0100 @@ -1,5 +1,5 @@ name: btrfs -version: 0.1.2.0 +version: 0.1.2.3 synopsis: Bindings to the btrfs API description: This package provides bindings to the low-level btrfs API (i.e. the @@ -32,6 +32,7 @@ include/btrfs/list.h include/btrfs/radix-tree.h include/btrfs/rbtree.h + include/sys/capability.h make-bytestring.hs source-repository head @@ -46,7 +47,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 @@ -75,6 +77,16 @@ default-language: Haskell2010 ghc-options: -Wall +executable btrfs-split + hs-source-dirs: examples + main-is: btrfs-split.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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/examples/btrfs-clone-range.hs new/btrfs-0.1.2.3/examples/btrfs-clone-range.hs --- old/btrfs-0.1.2.0/examples/btrfs-clone-range.hs 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/examples/btrfs-clone-range.hs 2017-01-30 01:49:23.000000000 +0100 @@ -1,9 +1,23 @@ -import System.Environment +import System.Environment (getArgs, getProgName) +import System.Exit (exitFailure) +import System.IO (stderr, hPutStrLn) +import Text.Read (readMaybe) import System.Linux.Btrfs main :: IO () main = do - [srcPath, srcOff, srcLen, dstPath, dstOff] <- getArgs - cloneRange srcPath (read srcOff) (read srcLen) - dstPath (read dstOff) + args <- getArgs + case args of + [srcPath, srcOffS, srcLenS, dstPath, dstOffS] + | Just srcOff <- readMaybe srcOffS + , Just srcLen <- readMaybe srcLenS + , Just dstOff <- readMaybe dstOffS -> + cloneRange srcPath srcOff srcLen dstPath dstOff + _ -> do + prog <- getProgName + hPutStrLn stderr "Invalid command line arguments" + hPutStrLn stderr $ + "Usage: " ++ prog ++ + " SOURCE SOURCE_OFF SOURCE_LEN DEST DEST_OFF" + exitFailure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/examples/btrfs-defrag.hs new/btrfs-0.1.2.3/examples/btrfs-defrag.hs --- old/btrfs-0.1.2.0/examples/btrfs-defrag.hs 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/examples/btrfs-defrag.hs 2017-01-30 01:49:23.000000000 +0100 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/examples/btrfs-split.hs new/btrfs-0.1.2.3/examples/btrfs-split.hs --- old/btrfs-0.1.2.0/examples/btrfs-split.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/btrfs-0.1.2.3/examples/btrfs-split.hs 2017-01-30 01:49:23.000000000 +0100 @@ -0,0 +1,47 @@ +import System.Environment (getArgs, getProgName) +import System.Exit (exitFailure) +import System.IO (stderr, hPutStrLn) +import Text.Read (readMaybe) +import Text.Printf (printf) +import Control.Exception (bracket) +import Data.Function (fix) +import Control.Monad (when) +import System.Posix + +import System.Linux.Btrfs (cloneRangeFd) + +main :: IO () +main = do + args <- getArgs + case args of + [srcPath, sizeS, prefix] | Just size <- readMaybe sizeS, size > 0 -> + withReadFd srcPath $ \srcFd -> do + stat <- getFdStatus srcFd + let totSize = fromIntegral $ fileSize stat + mode = fileMode stat + lastN = (totSize - 1) `div` size + formatStr = "%0" ++ show (length (show lastN)) ++ "d" + flip fix (0 :: Int, 0) $ \loop (n, offset) -> do + let filename = prefix ++ printf formatStr n + size' = min size (totSize - offset) + withWriteFd filename mode $ \dstFd -> + cloneRangeFd srcFd offset size' dstFd 0 + let offset' = offset + size' + when (offset' < totSize) $ loop (n + 1, offset') + _ -> do + prog <- getProgName + hPutStrLn stderr "Invalid command line arguments" + hPutStrLn stderr $ "Usage: " ++ prog ++ " FILE SIZE PREFIX" + exitFailure + +withReadFd :: FilePath -> (Fd -> IO r) -> IO r +withReadFd path action = + bracket + (openFd path ReadOnly Nothing defaultFileFlags {nonBlock = True}) + closeFd action + +withWriteFd :: FilePath -> FileMode -> (Fd -> IO r) -> IO r +withWriteFd path mode action = + bracket + (openFd path WriteOnly (Just mode) defaultFileFlags {trunc = True}) + closeFd action diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/btrfs/ctree.h new/btrfs-0.1.2.3/include/btrfs/ctree.h --- old/btrfs-0.1.2.0/include/btrfs/ctree.h 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/include/btrfs/ctree.h 2017-01-30 01:49:23.000000000 +0100 @@ -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, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/btrfs/extent-cache.h new/btrfs-0.1.2.3/include/btrfs/extent-cache.h --- old/btrfs-0.1.2.0/include/btrfs/extent-cache.h 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/include/btrfs/extent-cache.h 2017-01-30 01:49:23.000000000 +0100 @@ -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. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/btrfs/extent_io.h new/btrfs-0.1.2.3/include/btrfs/extent_io.h --- old/btrfs-0.1.2.0/include/btrfs/extent_io.h 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/include/btrfs/extent_io.h 2017-01-30 01:49:23.000000000 +0100 @@ -29,25 +29,44 @@ #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_DIRTY EXTENT_DIRTY +#define BLOCK_GROUP_DATA (1U << 1) +#define BLOCK_GROUP_METADATA (1U << 2) +#define BLOCK_GROUP_SYSTEM (1U << 4) + +#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; @@ -76,7 +95,7 @@ struct list_head lru; struct list_head recow; int refs; - int flags; + u32 flags; int fd; char data[]; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/btrfs/ioctl.h new/btrfs-0.1.2.3/include/btrfs/ioctl.h --- old/btrfs-0.1.2.0/include/btrfs/ioctl.h 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/include/btrfs/ioctl.h 2017-01-30 01:49:23.000000000 +0100 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/btrfs/kerncompat.h new/btrfs-0.1.2.3/include/btrfs/kerncompat.h --- old/btrfs-0.1.2.0/include/btrfs/kerncompat.h 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/include/btrfs/kerncompat.h 2017-01-30 01:49:23.000000000 +0100 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/btrfs/rbtree.h new/btrfs-0.1.2.3/include/btrfs/rbtree.h --- old/btrfs-0.1.2.0/include/btrfs/rbtree.h 2016-02-23 18:44:47.000000000 +0100 +++ new/btrfs-0.1.2.3/include/btrfs/rbtree.h 2017-01-30 01:49:23.000000000 +0100 @@ -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) \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-0.1.2.0/include/sys/capability.h new/btrfs-0.1.2.3/include/sys/capability.h --- old/btrfs-0.1.2.0/include/sys/capability.h 1970-01-01 01:00:00.000000000 +0100 +++ new/btrfs-0.1.2.3/include/sys/capability.h 2017-01-30 01:49:23.000000000 +0100 @@ -0,0 +1,127 @@ +/* + * <sys/capability.h> + * + * Copyright (C) 1997 Aleph One + * Copyright (C) 1997-8,2008 Andrew G. Morgan <[email protected]> + * + * defunct POSIX.1e Standard: 25.2 Capabilities <sys/capability.h> + */ + +#ifndef _SYS_CAPABILITY_H +#define _SYS_CAPABILITY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This file complements the kernel file by providing prototype + * information for the user library. + */ + +#include <sys/types.h> +#include <stdint.h> +#include <linux/types.h> + +#ifndef __user +#define __user +#endif +#include <linux/capability.h> +#include <linux/xattr.h> + +/* + * POSIX capability types + */ + +/* + * Opaque capability handle (defined internally by libcap) + * internal capability representation + */ +typedef struct _cap_struct *cap_t; + +/* "external" capability representation is a (void *) */ + +/* + * This is the type used to identify capabilities + */ + +typedef int cap_value_t; + +/* + * Set identifiers + */ +typedef enum { + CAP_EFFECTIVE=0, /* Specifies the effective flag */ + CAP_PERMITTED=1, /* Specifies the permitted flag */ + CAP_INHERITABLE=2 /* Specifies the inheritable flag */ +} cap_flag_t; + +/* + * These are the states available to each capability + */ +typedef enum { + CAP_CLEAR=0, /* The flag is cleared/disabled */ + CAP_SET=1 /* The flag is set/enabled */ +} cap_flag_value_t; + +/* + * User-space capability manipulation routines + */ + +/* libcap/cap_alloc.c */ +extern cap_t cap_dup(cap_t); +extern int cap_free(void *); +extern cap_t cap_init(void); + +/* libcap/cap_flag.c */ +extern int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *); +extern int cap_set_flag(cap_t, cap_flag_t, int, const cap_value_t *, + cap_flag_value_t); +extern int cap_clear(cap_t); +extern int cap_clear_flag(cap_t, cap_flag_t); + +/* libcap/cap_file.c */ +extern cap_t cap_get_fd(int); +extern cap_t cap_get_file(const char *); +extern int cap_set_fd(int, cap_t); +extern int cap_set_file(const char *, cap_t); + +/* libcap/cap_proc.c */ +extern cap_t cap_get_proc(void); +extern cap_t cap_get_pid(pid_t); +extern int cap_set_proc(cap_t); + +extern int cap_get_bound(cap_value_t); +extern int cap_drop_bound(cap_value_t); + +#define CAP_IS_SUPPORTED(cap) (cap_get_bound(cap) >= 0) + +/* libcap/cap_extint.c */ +extern ssize_t cap_size(cap_t); +extern ssize_t cap_copy_ext(void *, cap_t, ssize_t); +extern cap_t cap_copy_int(const void *); + +/* libcap/cap_text.c */ +extern cap_t cap_from_text(const char *); +extern char * cap_to_text(cap_t, ssize_t *); +extern int cap_from_name(const char *, cap_value_t *); +extern char * cap_to_name(cap_value_t); + +#define CAP_DIFFERS(result, flag) (((result) & (1 << (flag))) != 0) +extern int cap_compare(cap_t, cap_t); + +/* system calls - look to libc for function to system call mapping */ +extern int capset(cap_user_header_t header, cap_user_data_t data); +extern int capget(cap_user_header_t header, const cap_user_data_t data); + +/* deprecated - use cap_get_pid() */ +extern int capgetp(pid_t pid, cap_t cap_d); + +/* not valid with filesystem capability support - use cap_set_proc() */ +extern int capsetp(pid_t pid, cap_t cap_d); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_CAPABILITY_H */
