diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,42 @@
+Version 0.1.1.0 (2014-06-05)
+----------------------------
+
+- New functions for working in the `user` namespace.
+    * Set extended `user` attributes:
+        - setUserXAttr
+        - lSetUserXAttr
+        - fdSetUserXAttr
+    * Create extended `user` attributes:
+        - createUserXAttr
+        - lCreateUserXAttr
+        - fdCreateUserXAttr
+    * Replace extended `user` attributes:
+        - replaceUserXAttr
+        - lReplaceUserXAttr
+        - fdReplaceUserXAttr
+    * Retrieve extended `user` attributes:
+        - getUserXAttr
+        - lGetUserXAttr
+        - fdGetUserXAttr
+    * List extended `user` attributes:
+        - listUserXAttr
+        - lListUserXAttr
+        - fdListUserXAttr
+    * Remove extended `user` attributes:
+        - removeUserXAttr
+        - lRemoveUserXAttr
+        - fdRemoveUserXAttr
+- Use Safe Haskell extension.
+- Use type synonyms `Name` and `Value` for name and value of extended
+  attributes.
+- Improve documentation.
+- Minor code fixes.
+
 Version 0.1.0.1 (2014-04-08)
 ----------------------------
 
 - Relicense under BSD3.
-- Edit description and .cabal file
+- Edit description and .cabal file.
 - Clean up code.
 
 Version 0.1.0.0 (2013-03-15)
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,8 +1,17 @@
 `linux-xattr` provides [Haskell][Haskell] bindings to the Linux syscalls for
-reading and manipulating [extended attributes][ea] (`setxattr`, `getxattr`,
-`listxattr`, ...).
+reading and manipulating [extended attributes][ea] ([`setxattr`][setxattr],
+[`getxattr`][getxattr], [`listxattr`][listxattr] and
+[`removexattr`][removexattr]).
 
-  [Haskell]:  http://www.haskell.org/
-              "Haskell Programming Language"
-  [ea]:       http://en.wikipedia.org/wiki/Extended_file_attributes
-              "Extended file attributes"
+  [Haskell]:      http://www.haskell.org/
+                  "Haskell Programming Language"
+  [ea]:           http://en.wikipedia.org/wiki/Extended_file_attributes
+                  "Extended file attributes"
+  [setxattr]:     http://man7.org/linux/man-pages/man2/setxattr.2.html
+                  "setxattr(2) - Linux manual page"
+  [getxattr]:     http://man7.org/linux/man-pages/man2/getxattr.2.html
+                  "getxattr(2) - Linux manual page"
+  [listxattr]:    http://man7.org/linux/man-pages/man2/listxattr.2.html
+                  "listxattr(2) - Linux manual page"
+  [removexattr]:  http://man7.org/linux/man-pages/man2/removexattr.2.html
+                  "removexattr(2) - Linux manual page"
diff --git a/System/Linux/XAttr.hsc b/System/Linux/XAttr.hsc
--- a/System/Linux/XAttr.hsc
+++ b/System/Linux/XAttr.hsc
@@ -1,5 +1,3 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
-
 --------------------------------------------------------------------------------
 -- |
 -- Module      :  $Header$
@@ -11,56 +9,157 @@
 -- Portability :  portable
 --
 -- @linux-xattr@ provides bindings to the Linux syscalls for reading and
--- manipulating extended attributes (@setxattr@, @getxattr@, @listxattr@, ...).
+-- manipulating
+-- <http://en.wikipedia.org/wiki/Extended_file_attributes extended attributes>
+-- (@<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@,
+-- @<http://man7.org/linux/man-pages/man2/getxattr.2.html getxattr>@,
+-- @<http://man7.org/linux/man-pages/man2/listxattr.2.html listxattr>@ and
+-- @<http://man7.org/linux/man-pages/man2/removexattr.2.html removexattr>@).
+--
 -- Each function in this module has two variants: one with the name prefixed by
--- \"l\" and one prefixed by \"fd\".  Both of these are identical to the
--- original version except that the \"l\"-variant does not follow symbolic link
--- but acts on the link itself, and the \"fd\"-variant take a file descriptor as
--- argument rather than a @'FilePath'@.
+-- @__l__@ and one prefixed by @__fd__@.  Both of these are identical to the
+-- original version except that the @__l__@-variant does not follow symbolic
+-- link but acts on the link itself, and the @__fd__@-variant take a file
+-- descriptor as argument rather than a @'FilePath'@.
 --
+-- Moreover, every function has an @/xxx/__UserXAttr__@ variant for working
+-- transparently in the @__user__@ namespace of extended attributes, without
+-- worrying about the @"user."@ prefix: these functions automatically prepends
+-- the string @"user."@ to the @'Name'@ of the attribute when @'Name'@ is an
+-- input value, or strip the prefix @"user."@ from it when @'Name'@ is a
+-- returned value. See the documentation of each individual function for
+-- details.
+--
 --------------------------------------------------------------------------------
 
 module System.Linux.XAttr
     ( -- * Set extended attributes
+
+      -- | Functions in this section call the
+      -- @<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@
+      -- syscall.
+
       setXAttr
     , lSetXAttr
     , fdSetXAttr
+
+      -- ** Set extended @user@ attributes
+
+    , setUserXAttr
+    , lSetUserXAttr
+    , fdSetUserXAttr
+
       -- * Create extended attributes
+
+      -- | Functions in this section call the
+      -- @<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@
+      -- syscall with the flag @XATTR_CREATE@.
+
     , createXAttr
     , lCreateXAttr
     , fdCreateXAttr
+
+      -- ** Create extended @user@ attributes
+
+    , createUserXAttr
+    , lCreateUserXAttr
+    , fdCreateUserXAttr
+
       -- * Replace extended attributes
+
+      -- | Functions in this section call the
+      -- @<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@
+      -- syscall with the flag @XATTR_REPLACE@.
+
     , replaceXAttr
     , lReplaceXAttr
     , fdReplaceXAttr
-      -- * Retrive extended attributes
+
+      -- ** Replace extended @user@ attributes
+
+    , replaceUserXAttr
+    , lReplaceUserXAttr
+    , fdReplaceUserXAttr
+
+      -- * Retrieve extended attributes
+
+      -- | Functions in this section call the
+      -- @<http://man7.org/linux/man-pages/man2/getxattr.2.html getxattr>@
+      -- syscall.
+
     , getXAttr
     , lGetXAttr
     , fdGetXAttr
+
+      -- ** Retrieve extended @user@ attributes
+
+    , getUserXAttr
+    , lGetUserXAttr
+    , fdGetUserXAttr
+
       -- * List extended attributes
+
+      -- | Functions in this section call the
+      -- @<http://man7.org/linux/man-pages/man2/listxattr.2.html listxattr>@
+      -- syscall.
+
     , listXAttr
     , lListXAttr
     , fdListXAttr
+
+      -- ** List extended @user@ attributes
+
+      -- | These functions only list those extended attributes with @'Name'@
+      -- beginning with @"user."@. The @"user."@ prefix is removed from each
+      -- @'Name'@ in the output list.
+
+    , listUserXAttr
+    , lListUserXAttr
+    , fdListUserXAttr
+
       -- * Remove extended attributes
+
+      -- | Functions in this section call the
+      -- @<http://man7.org/linux/man-pages/man2/removexattr.2.html removexattr>@
+      -- syscall.
+
     , removeXAttr
     , lRemoveXAttr
     , fdRemoveXAttr
+
+      -- ** Remove extended @user@ attributes
+
+    , removeUserXAttr
+    , lRemoveUserXAttr
+    , fdRemoveUserXAttr
+
+      -- * Types for extended attributes
+
+    , Name
+    , Value
     ) where
 
 #include <sys/xattr.h>
 
-import           Data.ByteString    (ByteString, packCStringLen,
-                                     useAsCStringLen)
-import           Foreign.C          (CInt (..), CSize (..), CString,
-                                     peekCStringLen, throwErrnoIfMinus1,
-                                     throwErrnoIfMinus1_, withCString)
-import           Foreign.Marshal    (allocaBytes)
-import           Foreign.Ptr        (Ptr, castPtr, nullPtr)
-import           System.Posix.Types (CSsize (..), Fd (..))
+import           Control.Monad         (liftM)
+import           Data.ByteString       (ByteString, packCStringLen,
+                                        useAsCStringLen)
+import           Foreign.C             (CInt (..), CSize (..), CString,
+                                        peekCStringLen, throwErrnoIfMinus1,
+                                        throwErrnoIfMinus1_, withCString)
+import           Foreign.Marshal.Alloc (allocaBytes)
+import           Foreign.Ptr           (Ptr, nullPtr)
+import           System.Posix.Types    (CSsize (..), Fd (..))
 
-xAttrSet :: String
-         -> ByteString
-         -> (a -> CString -> Ptr () -> CSize -> CInt -> IO CInt)
+-- | Name of extended attribute.
+type Name = String
+
+-- | Value of extended attribute.
+type Value = ByteString
+
+xAttrSet :: Name
+         -> Value
+         -> (a -> CString -> CString -> CSize -> CInt -> IO CInt)
          -> String
          -> CInt
          -> a
@@ -68,101 +167,155 @@
 xAttrSet attr value func name mode f =
     throwErrnoIfMinus1_ name $ withCString attr $ \b ->
         useAsCStringLen value $ \(c,d) ->
-            func f b (castPtr c) (fromIntegral d) mode
+            func f b c (fromIntegral d) mode
 
--- | Set the value of an extended attribute.
-setXAttr :: FilePath    -- ^ target file
-         -> String      -- ^ name of attribute to set
-         -> ByteString  -- ^ value of attribute
-         -> IO ()
+-- | Set the @'Value'@ of the extended attribute identified by @'Name'@ and
+-- associated with the given @'FilePath'@ in the filesystem.
+setXAttr :: FilePath -> Name -> Value -> IO ()
 setXAttr path attr value =
-    withCString path $ xAttrSet attr value c_setxattr "setxattr" 0
+    withCString path $ xAttrSet attr value setxattr "setxattr" 0
 
--- | Set the value of an extended attribute (do not follow symbolic links).
-lSetXAttr :: FilePath -> String -> ByteString -> IO ()
+-- | @'setUserXAttr' "\/some\/path" "foo" "bar" = 'setXAttr' "\/some\/path" "user.foo" "bar"@
+setUserXAttr :: FilePath -> Name -> Value -> IO ()
+setUserXAttr = userXAttr setXAttr
+
+-- | Set the @'Value'@ of the extended attribute identified by @'Name'@ and
+-- associated with the given @'FilePath'@ in the filesystem (do not follow
+-- symbolic links).
+lSetXAttr :: FilePath -> Name -> Value -> IO ()
 lSetXAttr path attr value =
-    withCString path $ xAttrSet attr value c_lsetxattr "lsetxattr" 0
+    withCString path $ xAttrSet attr value lsetxattr "lsetxattr" 0
 
--- | Set the value of an extended attribute.
-fdSetXAttr :: Fd -> String -> ByteString -> IO ()
+-- | @'lSetUserXAttr' "\/some\/link" "foo" "bar" = 'lSetXAttr' "\/some\/link" "user.foo" "bar"@
+lSetUserXAttr :: FilePath -> Name -> Value -> IO ()
+lSetUserXAttr = userXAttr lSetXAttr
+
+-- | Set the @'Value'@ of the extended attribute identified by @'Name'@ and
+-- associated with the given file descriptor in the filesystem.
+fdSetXAttr :: Fd -> Name -> Value -> IO ()
 fdSetXAttr (Fd n) attr value =
-    xAttrSet attr value c_fsetxattr "fsetxattr" 0 n
+    xAttrSet attr value fsetxattr "fsetxattr" 0 n
 
--- | Identical to @'setXAttr'@, but if the attribute already exists fail and set
--- errno to EEXIST.
-createXAttr :: FilePath -> String -> ByteString -> IO ()
+-- | @'fdSetUserXAttr' ('Fd' n) "foo" "bar" = 'fdSetXAttr' ('Fd' n) "user.foo" "bar"@
+fdSetUserXAttr :: Fd -> Name -> Value -> IO ()
+fdSetUserXAttr = userXAttr fdSetXAttr
+
+-- | Identical to @'setXAttr'@, but if the attribute already exists fail with
+-- @`System.IO.Error.isAlreadyExistsError`@.
+createXAttr :: FilePath -> Name -> Value -> IO ()
 createXAttr path attr value =
     withCString path $
-    xAttrSet attr value c_setxattr "setxattr" #{const XATTR_CREATE}
+    xAttrSet attr value setxattr "setxattr" #{const XATTR_CREATE}
 
--- | Identical to @'lSetXAttr'@, but if the attribute already exists fail and
--- set errno to EEXIST.
-lCreateXAttr :: FilePath -> String -> ByteString -> IO ()
+-- | @'createUserXAttr' "\/some\/path" "foo" "bar" = 'createXAttr' "\/some\/path" "user.foo" "bar"@
+createUserXAttr :: FilePath -> Name -> Value -> IO ()
+createUserXAttr = userXAttr createXAttr
+
+-- | Identical to @'lSetXAttr'@, but if the attribute already exists fail with
+-- @`System.IO.Error.isAlreadyExistsError`@.
+lCreateXAttr :: FilePath -> Name -> Value -> IO ()
 lCreateXAttr path attr value =
     withCString path $
-    xAttrSet attr value c_lsetxattr "lsetxattr" #{const XATTR_CREATE}
+    xAttrSet attr value lsetxattr "lsetxattr" #{const XATTR_CREATE}
 
--- | Identical to @'fdSetXAttr'@, but if the attribute already exists fail and
--- set errno to EEXIST.
-fdCreateXAttr :: Fd -> String -> ByteString -> IO ()
+-- | @'lCreateUserXAttr' "\/some\/link" "foo" "bar" = 'lCreateXAttr' "\/some\/link" "user.foo" "bar"@
+lCreateUserXAttr :: FilePath -> Name -> Value -> IO ()
+lCreateUserXAttr = userXAttr lCreateXAttr
+
+-- | Identical to @'fdSetXAttr'@, but if the attribute already exists fail with
+-- @`System.IO.Error.isAlreadyExistsError`@.
+fdCreateXAttr :: Fd -> Name -> Value -> IO ()
 fdCreateXAttr (Fd n) attr value =
-    xAttrSet attr value c_fsetxattr "fsetxattr" #{const XATTR_CREATE} n
+    xAttrSet attr value fsetxattr "fsetxattr" #{const XATTR_CREATE} n
 
--- | Identical to @'setXAttr'@, but if the attribute does not exist fail and set
--- errno to ENOATTR.
-replaceXAttr :: FilePath -> String -> ByteString -> IO ()
+-- | @'fdCreateUserXAttr' ('Fd' n) "foo" "bar" = 'fdCreateXAttr' ('Fd' n) "user.foo" "bar"@
+fdCreateUserXAttr :: Fd -> Name -> Value -> IO ()
+fdCreateUserXAttr = userXAttr fdCreateXAttr
+
+-- | Identical to @'setXAttr'@, but if the attribute does not exist fail with
+-- @`System.IO.Error.isDoesNotExistError`@.
+replaceXAttr :: FilePath -> Name -> Value -> IO ()
 replaceXAttr path attr value =
     withCString path $
-    xAttrSet attr value c_setxattr "setxattr" #{const XATTR_REPLACE}
+    xAttrSet attr value setxattr "setxattr" #{const XATTR_REPLACE}
 
--- | Identical to @'lSetXAttr'@, but if the attribute does not exist fail and
--- set errno to ENOATTR.
-lReplaceXAttr :: FilePath -> String -> ByteString -> IO ()
+-- | @'replaceUserXAttr' "\/some\/path" "foo" "bar" = 'replaceXAttr' "\/some\/path" "user.foo" "bar"@
+replaceUserXAttr :: FilePath -> Name -> Value -> IO ()
+replaceUserXAttr = userXAttr replaceXAttr
+
+-- | Identical to @'lSetXAttr'@, but if the attribute does not exist fail with
+-- @`System.IO.Error.isDoesNotExistError`@.
+lReplaceXAttr :: FilePath -> Name -> Value -> IO ()
 lReplaceXAttr path attr value =
     withCString path $
-    xAttrSet attr value c_lsetxattr "lsetxattr" #{const XATTR_REPLACE}
+    xAttrSet attr value lsetxattr "lsetxattr" #{const XATTR_REPLACE}
 
--- | Identical to @'fdSetXAttr'@, but if the attribute does not exist fail and
--- set errno to ENOATTR.
-fdReplaceXAttr :: Fd -> String -> ByteString -> IO ()
+-- | @'lReplaceUserXAttr' "\/some\/link" "foo" "bar" = 'lReplaceXAttr' "\/some\/link" "user.foo" "bar"@
+lReplaceUserXAttr :: FilePath -> Name -> Value -> IO ()
+lReplaceUserXAttr = userXAttr lReplaceXAttr
+
+-- | Identical to @'fdSetXAttr'@, but if the attribute does not exist fail with
+-- @`System.IO.Error.isDoesNotExistError`@.
+fdReplaceXAttr :: Fd -> Name -> Value -> IO ()
 fdReplaceXAttr (Fd n) attr value =
-    xAttrSet attr value c_fsetxattr "fsetxattr" #{const XATTR_REPLACE} n
+    xAttrSet attr value fsetxattr "fsetxattr" #{const XATTR_REPLACE} n
 
+-- | @'fdReplaceUserXAttr' ('Fd' n) "foo" "bar" = 'fdReplaceXAttr' ('Fd' n) "user.foo" "bar"@
+fdReplaceUserXAttr :: Fd -> Name -> Value -> IO ()
+fdReplaceUserXAttr = userXAttr fdReplaceXAttr
 
-xAttrGet :: String
-         -> (a -> CString -> Ptr () -> CSize -> IO CSsize)
+
+xAttrGet :: Name
+         -> (a -> CString -> CString -> CSize -> IO CSsize)
          -> String
          -> a
-         -> IO ByteString
+         -> IO Value
 xAttrGet attr func name f =
     withCString attr $ \cstr ->
         do size <- throwErrnoIfMinus1 name (func f cstr nullPtr 0)
            allocaBytes (fromIntegral size) $ \p ->
                do throwErrnoIfMinus1_ name $ func f cstr p (fromIntegral size)
-                  packCStringLen (castPtr p, fromIntegral size)
+                  packCStringLen (p, fromIntegral size)
 
--- | Get the value of an extended attribute.
-getXAttr :: FilePath       -- ^ target file
-         -> String         -- ^ name of the attribute
-         -> IO ByteString  -- ^ value of the attribute
+-- | Retrieve the @'Value'@ of the extended attribute identified by @'Name'@ and
+-- associated with the given @'FilePath'@ in the filesystem, or fail with
+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.
+getXAttr :: FilePath -> Name -> IO Value
 getXAttr path attr =
-    withCString path $ xAttrGet attr c_getxattr "getxattr"
+    withCString path $ xAttrGet attr getxattr "getxattr"
 
--- | Get the value of an extended attribute (do not follow symbolic links).
-lGetXAttr :: FilePath -> String -> IO ByteString
+-- | @'getUserXAttr' "\/some\/path" "foo" = 'getXAttr' "\/some\/path" "user.foo"@
+getUserXAttr :: FilePath -> Name -> IO Value
+getUserXAttr = userXAttr getXAttr
+
+-- | Retrieve the @'Value'@ of the extended attribute identified by @'Name'@ and
+-- associated with the given @'FilePath'@ in the filesystem, or fail with
+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist (do
+-- not follow symbolic links).
+lGetXAttr :: FilePath -> Name -> IO Value
 lGetXAttr path attr =
-    withCString path $ xAttrGet attr c_lgetxattr "lgetxattr"
+    withCString path $ xAttrGet attr lgetxattr "lgetxattr"
 
--- | Get the value of an extended attribute.
-fdGetXAttr :: Fd -> String -> IO ByteString
+-- | @'lGetUserXAttr' "\/some\/link" "foo" = 'lGetXAttr' "\/some\/link" "user.foo"@
+lGetUserXAttr :: FilePath -> Name -> IO Value
+lGetUserXAttr = userXAttr lGetXAttr
+
+-- | Retrieve the @'Value'@ of the extended attribute identified by @'Name'@ and
+-- associated with the given file descriptor in the filesystem, or fail with
+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.
+fdGetXAttr :: Fd -> Name -> IO Value
 fdGetXAttr (Fd n) attr =
-    xAttrGet attr c_fgetxattr "fgetxattr" n
+    xAttrGet attr fgetxattr "fgetxattr" n
 
+-- | @'fdGetUserXAttr' ('Fd' n) "foo" = 'fdGetXAttr' ('Fd' n) "user.foo"@
+fdGetUserXAttr :: Fd -> Name -> IO Value
+fdGetUserXAttr = userXAttr fdGetXAttr
 
+
 xAttrList :: (a -> CString -> CSize -> IO CSsize)
           -> String
           -> a
-          -> IO [String]
+          -> IO [Name]
 xAttrList func name f =
     do size <- throwErrnoIfMinus1 name (func f nullPtr 0)
        allocaBytes (fromIntegral size) $ \p ->
@@ -173,111 +326,169 @@
           split xs = fst c : split (tail $ snd c)
               where c = break (== '\NUL') xs
 
--- | Get the list of attribute names associated with the given @'FilePath'@.
-listXAttr :: FilePath      -- ^ target file
-          -> IO [String] -- ^ list of attribute names
-listXAttr path = withCString path $ xAttrList c_listxattr "listxattr"
+-- | Get the list of extended attribute @'Name'@s associated with the given
+-- @'FilePath'@ in the filesystem.
+listXAttr :: FilePath -> IO [Name]
+listXAttr path = withCString path $ xAttrList listxattr "listxattr"
 
--- | Get the list of attribute names associated with the given @'FilePath'@ (do
--- not follow symbolic links).
-lListXAttr :: FilePath -> IO [String]
+-- |
+-- @
+-- >>> 'listXAttr' "\/some\/path"
+-- ["user.foo","user.bar"]
+-- >>> 'listUserXAttr' "\/some\/path"
+-- ["foo","bar"]
+-- @
+listUserXAttr :: FilePath -> IO [Name]
+listUserXAttr = userXAttrList listXAttr
+
+-- | Get the list of extended attribute @'Name'@s associated with the given
+-- @'FilePath'@ in the filesystem (do not follow symbolic links).
+lListXAttr :: FilePath -> IO [Name]
 lListXAttr path =
-    withCString path $ xAttrList c_llistxattr "llistxattr"
+    withCString path $ xAttrList llistxattr "llistxattr"
 
--- | Get the list of attribute names associated with the given file descriptor.
-fdListXAttr :: Fd -> IO [String]
+-- |
+-- @
+-- >>> 'lListXAttr' "\/some\/link"
+-- ["user.foo","user.bar"]
+-- >>> 'lListUserXAttr' "\/some\/link"
+-- ["foo","bar"]
+-- @
+lListUserXAttr :: FilePath -> IO [Name]
+lListUserXAttr = userXAttrList lListXAttr
+
+-- | Get the list of extended attribute @'Name'@s associated with the given file
+-- descriptor in the filesystem.
+fdListXAttr :: Fd -> IO [Name]
 fdListXAttr (Fd n) =
-    xAttrList c_flistxattr "flistxattr" n
+    xAttrList flistxattr "flistxattr" n
 
+-- |
+-- @
+-- >>> 'fdListXAttr' ('Fd' n)
+-- ["user.foo","user.bar"]
+-- >>> 'fdListUserXAttr' ('Fd' n)
+-- ["foo","bar"]
+-- @
+fdListUserXAttr :: Fd -> IO [Name]
+fdListUserXAttr = userXAttrList fdListXAttr
 
-xAttrRemove :: String -> (a -> CString -> IO CInt) -> String -> a -> IO ()
+
+xAttrRemove :: Name -> (a -> CString -> IO CInt) -> String -> a -> IO ()
 xAttrRemove attr func name f =
     throwErrnoIfMinus1_ name $ withCString attr (func f)
 
--- | Remove an extended attribute from the given @'FilePath'@.
-removeXAttr :: FilePath  -- ^ target file
-            -> String    -- ^ name of the attribute
-            -> IO ()
+-- | Remove the extended attribute identified by @'Name'@ and associated with
+-- the given @'FilePath'@ in the filesystem, or fail with
+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.
+removeXAttr :: FilePath -> Name -> IO ()
 removeXAttr path attr =
-    withCString path $ xAttrRemove attr c_removexattr "removexattr"
+    withCString path $ xAttrRemove attr removexattr "removexattr"
 
--- | Remove an extended attribute from the given @'FilePath'@ (do not follow
--- symbolic links).
-lRemoveXAttr :: FilePath -> String -> IO ()
+-- | @'removeUserXAttr' "\/some\/path" "foo" = 'removeXAttr' "\/some\/path" "user.foo"@
+removeUserXAttr :: FilePath -> Name -> IO ()
+removeUserXAttr = userXAttr removeXAttr
+
+-- | Remove the extended attribute identified by @'Name'@ and associated with
+-- the given @'FilePath'@ in the filesystem, or fail with
+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist (do
+-- not follow symbolic links).
+lRemoveXAttr :: FilePath -> Name -> IO ()
 lRemoveXAttr path attr =
-    withCString path $ xAttrRemove attr c_lremovexattr "lremovexattr"
+    withCString path $ xAttrRemove attr lremovexattr "lremovexattr"
 
--- | Remove an extended attribute from the given file descriptor.
-fdRemoveXAttr :: Fd -> String -> IO ()
+-- | @'lRemoveUserXAttr' "\/some\/link" "foo" = 'lRemoveXAttr' "\/some\/link" "user.foo"@
+lRemoveUserXAttr :: FilePath -> Name -> IO ()
+lRemoveUserXAttr = userXAttr lRemoveXAttr
+
+-- | Remove the extended attribute identified by @'Name'@ and associated with
+-- the given file descriptor in the filesystem, or fail with
+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.
+fdRemoveXAttr :: Fd -> Name -> IO ()
 fdRemoveXAttr (Fd n) attr =
-    xAttrRemove attr c_fremovexattr "fremovexattr" n
+    xAttrRemove attr fremovexattr "fremovexattr" n
 
+-- | @'fdRemoveUserXAttr' ('Fd' n) "foo" = 'fdRemoveXAttr' ('Fd' n) "user.foo"@
+fdRemoveUserXAttr :: Fd -> Name -> IO ()
+fdRemoveUserXAttr = userXAttr fdRemoveXAttr
 
-foreign import ccall unsafe "setxattr" c_setxattr :: CString
-                                                  -> CString
-                                                  -> Ptr ()
-                                                  -> CSize
-                                                  -> CInt
-                                                  -> IO CInt
 
-foreign import ccall unsafe "lsetxattr" c_lsetxattr :: CString
-                                                    -> CString
-                                                    -> Ptr ()
-                                                    -> CSize
-                                                    -> CInt
-                                                    -> IO CInt
+userXAttr :: (a -> Name -> b) -> a -> Name -> b
+userXAttr func f name = func f ("user." ++ name)
 
-foreign import ccall unsafe "fsetxattr" c_fsetxattr :: CInt
-                                                    -> CString
-                                                    -> Ptr ()
-                                                    -> CSize
-                                                    -> CInt
-                                                    -> IO CInt
+userXAttrList :: (a -> IO [Name]) -> a -> IO [Name]
+userXAttrList func f = liftM unUser $ func f
+    where unUser []     = []
+          unUser (x:xs) = case splitAt 5 x of
+                            ("user.",attr) -> attr : unUser xs
+                            _              -> unUser xs
 
 
-foreign import ccall unsafe "getxattr" c_getxattr :: CString
-                                                  -> CString
-                                                  -> Ptr ()
-                                                  -> CSize
-                                                  -> IO CSsize
+foreign import ccall unsafe setxattr :: CString
+                                     -> CString
+                                     -> Ptr a
+                                     -> CSize
+                                     -> CInt
+                                     -> IO CInt
 
-foreign import ccall unsafe "lgetxattr" c_lgetxattr :: CString
-                                                    -> CString
-                                                    -> Ptr ()
-                                                    -> CSize
-                                                    -> IO CSsize
+foreign import ccall unsafe lsetxattr :: CString
+                                      -> CString
+                                      -> Ptr a
+                                      -> CSize
+                                      -> CInt
+                                      -> IO CInt
 
-foreign import ccall unsafe "fgetxattr" c_fgetxattr :: CInt
-                                                    -> CString
-                                                    -> Ptr ()
-                                                    -> CSize
-                                                    -> IO CSsize
+foreign import ccall unsafe fsetxattr :: CInt
+                                      -> CString
+                                      -> Ptr a
+                                      -> CSize
+                                      -> CInt
+                                      -> IO CInt
 
 
-foreign import ccall unsafe "listxattr" c_listxattr :: CString
-                                                    -> CString
-                                                    -> CSize
-                                                    -> IO CSsize
+foreign import ccall unsafe getxattr :: CString
+                                     -> CString
+                                     -> Ptr a
+                                     -> CSize
+                                     -> IO CSsize
 
-foreign import ccall unsafe "llistxattr" c_llistxattr :: CString
-                                                      -> CString
-                                                      -> CSize
-                                                      -> IO CSsize
+foreign import ccall unsafe lgetxattr :: CString
+                                      -> CString
+                                      -> Ptr a
+                                      -> CSize
+                                      -> IO CSsize
 
-foreign import ccall unsafe "flistxattr" c_flistxattr :: CInt
-                                                      -> CString
-                                                      -> CSize
-                                                      -> IO CSsize
+foreign import ccall unsafe fgetxattr :: CInt
+                                      -> CString
+                                      -> Ptr a
+                                      -> CSize
+                                      -> IO CSsize
 
 
-foreign import ccall unsafe "removexattr" c_removexattr :: CString
-                                                        -> CString
-                                                        -> IO CInt
+foreign import ccall unsafe listxattr :: CString
+                                      -> CString
+                                      -> CSize
+                                      -> IO CSsize
 
-foreign import ccall unsafe "lremovexattr" c_lremovexattr :: CString
-                                                          -> CString
-                                                          -> IO CInt
+foreign import ccall unsafe llistxattr :: CString
+                                       -> CString
+                                       -> CSize
+                                       -> IO CSsize
 
-foreign import ccall unsafe "fremovexattr" c_fremovexattr :: CInt
-                                                          -> CString
-                                                          -> IO CInt
+foreign import ccall unsafe flistxattr :: CInt
+                                       -> CString
+                                       -> CSize
+                                       -> IO CSsize
+
+
+foreign import ccall unsafe removexattr :: CString
+                                        -> CString
+                                        -> IO CInt
+
+foreign import ccall unsafe lremovexattr :: CString
+                                         -> CString
+                                         -> IO CInt
+
+foreign import ccall unsafe fremovexattr :: CInt
+                                         -> CString
+                                         -> IO CInt
diff --git a/linux-xattr.cabal b/linux-xattr.cabal
--- a/linux-xattr.cabal
+++ b/linux-xattr.cabal
@@ -1,6 +1,6 @@
 Name:           linux-xattr
-Version:        0.1.0.1
-Cabal-Version:  >= 1.8
+Version:        0.1.1.0
+Cabal-Version:  >= 1.10
 Build-Type:     Simple
 License:        BSD3
 License-File:   LICENSE
@@ -14,7 +14,10 @@
 Description:
 
   Bindings to the Linux syscalls for reading and manipulating extended
-  attributes (@setxattr@, @getxattr@, @listxattr@, ...).
+  attributes (@<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@,
+  @<http://man7.org/linux/man-pages/man2/getxattr.2.html getxattr>@,
+  @<http://man7.org/linux/man-pages/man2/listxattr.2.html listxattr>@ and
+  @<http://man7.org/linux/man-pages/man2/removexattr.2.html removexattr>@).
 
 Extra-Source-Files:
   CHANGELOG.md
@@ -27,10 +30,12 @@
 Source-Repository this
   Type:      git
   Location:  git://github.com/tensor5/linux-xattr.git
-  Tag:       v0.1.0.1
+  Tag:       v0.1.1.0
 
 Library
-  Build-Depends:        base == 4.*,
-                        bytestring == 0.10.*
-  Ghc-Options:          -Wall
-  Exposed-Modules:      System.Linux.XAttr
+  Default-Language:    Haskell2010
+  Default-Extensions:  Safe
+  Build-Depends:       base == 4.*,
+                       bytestring == 0.10.*
+  Ghc-Options:         -Wall
+  Exposed-Modules:     System.Linux.XAttr
