]> dgit.raspbian.org Git - git-annex.git/commitdiff
shared repository content file permissions for v9
authorJoey Hess <joeyh@joeyh.name>
Tue, 11 Jan 2022 20:36:07 +0000 (16:36 -0400)
committerJoey Hess <joeyh@joeyh.name>
Tue, 11 Jan 2022 20:50:50 +0000 (16:50 -0400)
v9 will not need to write to annex content files in order to lock them,
so freezeContent removes the write bit in a shared repository, the same
as in any other repository.

checkContentWritePerm makes sure that the write perm is not set, which
will let git-annex fsck fix up the permissions. Upgrading to v9
will need to fix the permissions as well, but it seems likely there will
be situations where the user git-annex is running an upgrade as cannot,
so it will have to leave the write bit set. In such a case, git-annex
fsck can fix it later.

Sponsored-by: Dartmouth College's Datalad project
Annex/Init.hs
Annex/Perms.hs
Annex/Version.hs

index 96e61eb2d56e178ee5db9473e35843434aaa306e..9e78dcc0219c7bcc20977a2e21ab5c3e20951469 100644 (file)
@@ -282,7 +282,7 @@ probeCrippledFileSystem' tmp freezecontent thawcontent = do
                -- running as root). But some crippled
                -- filesystems ignore write bit removals or ignore
                -- permissions entirely.
-               ifM ((== Just False) <$> liftIO (checkContentWritePerm' UnShared (toRawFilePath f)))
+               ifM ((== Just False) <$> liftIO (checkContentWritePerm' UnShared (toRawFilePath f) Nothing))
                        ( return (True, ["Filesystem does not allow removing write bit from files."])
                        , liftIO $ ifM ((== 0) <$> getRealUserID)
                                ( return (False, [])
index aa3fd694d817f948d7d88bbeceec24bffa18b8e7..66f59743e6fbea4ce75c415d66816ebd337d4c9b 100644 (file)
@@ -32,6 +32,8 @@ import Utility.FileMode
 import Git
 import Git.ConfigTypes
 import qualified Annex
+import Annex.Version
+import Types.RepoVersion
 import Config
 import Utility.Directory.Create
 import qualified Utility.RawFilePath as R
@@ -127,11 +129,14 @@ createWorkTreeDirectory dir = do
 {- Normally, blocks writing to an annexed file, and modifies file
  - permissions to allow reading it.
  -
- - When core.sharedRepository is set, the write bits are not removed from
- - the file, but instead the appropriate group write bits are set. This is
- - necessary to let other users in the group lock the file. But, in a
- - shared repository, the current user may not be able to change a file
- - owned by another user, so failure to set this mode is ignored.
+ - Before v9, when core.sharedRepository is set, the write bits are not
+ - removed from the file, but instead the appropriate group write bits
+ - are set. This is necessary to let other users in the group lock the file.
+ - v9 improved this by using separate lock files, so the content file does
+ - not need to be writable when using it.
+ -
+ - In a shared repository, the current user may not be able to change
+ - a file owned by another user, so failure to change modes is ignored.
  -
  - Note that, on Linux, xattrs can sometimes prevent removing
  - certain permissions from a file with chmod. (Maybe some ACLs too?) 
@@ -148,13 +153,27 @@ freezeContent' sr file = do
        go sr
        freezeHook file
   where
-       go GroupShared = liftIO $ void $ tryIO $ modifyFileMode file $
-               addModes [ownerReadMode, groupReadMode, ownerWriteMode, groupWriteMode]
-       go AllShared = liftIO $ void $ tryIO $ modifyFileMode file $
-               addModes (readModes ++ writeModes)
-       go _ = liftIO $ modifyFileMode file $
+       go GroupShared = ifM (versionNeedsWritableContentFiles <$> getVersion)
+               ( liftIO $ ignoresharederr $ modmode $ addModes
+                       [ownerReadMode, groupReadMode, ownerWriteMode, groupWriteMode]
+               , liftIO $ ignoresharederr $
+                       nowriteadd [ownerReadMode, groupReadMode]
+               )
+       go AllShared = ifM (versionNeedsWritableContentFiles <$> getVersion)
+               ( liftIO $ ignoresharederr $ modmode $ addModes
+                       (readModes ++ writeModes)
+               , liftIO $ ignoresharederr $ 
+                       nowriteadd readModes
+               )
+       go _ = liftIO $ nowriteadd [ownerReadMode]
+
+       ignoresharederr = void . tryIO
+
+       modmode = modifyFileMode file
+
+       nowriteadd readmodes = modmode $ 
                removeModes writeModes .
-               addModes [ownerReadMode]
+               addModes readmodes
 
 {- Checks if the write permissions are as freezeContent should set them.
  -
@@ -166,14 +185,21 @@ freezeContent' sr file = do
 checkContentWritePerm :: RawFilePath -> Annex (Maybe Bool)
 checkContentWritePerm file = ifM crippledFileSystem
        ( return (Just True)
-       , withShared (\sr -> liftIO (checkContentWritePerm' sr file))
+       , do
+               rv <- getVersion
+               withShared (\sr -> liftIO (checkContentWritePerm' sr file rv))
        )
 
-checkContentWritePerm' :: SharedRepository -> RawFilePath -> IO (Maybe Bool)
-checkContentWritePerm' sr file = case sr of
-       GroupShared -> want sharedret
-               (includemodes [ownerWriteMode, groupWriteMode])
-       AllShared -> want sharedret (includemodes writeModes)
+checkContentWritePerm' :: SharedRepository -> RawFilePath -> Maybe RepoVersion -> IO (Maybe Bool)
+checkContentWritePerm' sr file rv = case sr of
+       GroupShared
+               | versionNeedsWritableContentFiles rv -> want sharedret
+                       (includemodes [ownerWriteMode, groupWriteMode])
+               | otherwise -> want sharedret (excludemodes writeModes)
+       AllShared
+               | versionNeedsWritableContentFiles rv -> 
+                       want sharedret (includemodes writeModes)
+               | otherwise -> want sharedret (excludemodes writeModes)
        _ -> want Just (excludemodes writeModes)
   where
        want mk f = catchMaybeIO (fileMode <$> R.getFileStatus file)
index 56b3bc72cf3a4fc53a59d133c16b5dda2a929f8f..5e7ba85c7c8452299470ca062ffdf095a6404a4e 100644 (file)
@@ -1,6 +1,6 @@
 {- git-annex repository versioning
  -
- - Copyright 2010-2021 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2022 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
@@ -54,3 +54,8 @@ setVersion (RepoVersion v) = setConfig versionField (show v)
 
 removeVersion :: Annex ()
 removeVersion = unsetConfig versionField
+
+versionNeedsWritableContentFiles :: Maybe RepoVersion -> Bool
+versionNeedsWritableContentFiles (Just v) 
+       | v >= RepoVersion 9 = False
+versionNeedsWritableContentFiles _ = True