| 
					
				 | 
			
			
				@@ -230,12 +230,14 @@ class FuseBackend(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.contents = defaultdict(dict) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.default_uid = os.getuid() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.default_gid = os.getgid() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.default_dir = Item(mode=0o40755, mtime=int(time.time() * 1e9), uid=self.default_uid, gid=self.default_gid) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.default_dir = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Archives to be loaded when first accessed, mapped by their placeholder inode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.pending_archives = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.cache = ItemCache(decrypted_repository) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.allow_damaged_files = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.versions = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.uid_forced = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.gid_forced = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def _create_filesystem(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._create_dir(parent=1)  # first call, create root dir (inode == 1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -443,19 +445,40 @@ class FuseOperations(llfuse.Operations, FuseBackend): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def mount(self, mountpoint, mount_options, foreground=False): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Mount filesystem on *mountpoint* with *mount_options*.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        def pop_option(options, key, present, not_present, wanted_type): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assert isinstance(options, list)  # we mutate this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for idx, option in enumerate(options): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if option == key: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    options.pop(idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return present 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if option.startswith(key + '='): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    options.pop(idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    value = option.split('=', 1)[1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if wanted_type is bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        v = value.lower() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if v in ('y', 'yes', 'true', '1'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if v in ('n', 'no', 'false', '0'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise ValueError('unsupported value in option: %s' % option) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return wanted_type(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    except ValueError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise ValueError('unsupported value in option: %s' % option) from None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return not_present 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         options = ['fsname=borgfs', 'ro'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if mount_options: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             options.extend(mount_options.split(',')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            options.remove('allow_damaged_files') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.allow_damaged_files = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        except ValueError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            options.remove('versions') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.versions = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        except ValueError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.allow_damaged_files = pop_option(options, 'allow_damaged_files', True, False, bool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.versions = pop_option(options, 'versions', True, False, bool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.uid_forced = pop_option(options, 'uid', None, None, int) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.gid_forced = pop_option(options, 'gid', None, None, int) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dir_uid = self.uid_forced if self.uid_forced is not None else self.default_uid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dir_gid = self.gid_forced if self.gid_forced is not None else self.default_gid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.default_dir = Item(mode=0o40755, mtime=int(time.time() * 1e9), uid=dir_uid, gid=dir_gid) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._create_filesystem() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         llfuse.init(self, mountpoint, options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if not foreground: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -500,8 +523,8 @@ class FuseOperations(llfuse.Operations, FuseBackend): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         entry.attr_timeout = 300 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         entry.st_mode = item.mode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         entry.st_nlink = item.get('nlink', 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        entry.st_uid = item.uid if item.uid >= 0 else self.default_uid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        entry.st_gid = item.gid if item.gid >= 0 else self.default_gid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        entry.st_uid = self.uid_forced if self.uid_forced is not None else item.uid if item.uid >= 0 else self.default_uid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        entry.st_gid = self.gid_forced if self.gid_forced is not None else item.gid if item.gid >= 0 else self.default_gid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         entry.st_rdev = item.get('rdev', 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         entry.st_size = item.get_size() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         entry.st_blksize = 512 
			 |