##// END OF EJS Templates
mmap: add a `is_mmap_safe` method to vfs...
marmoute -
r52545:ba205f94 stable
parent child Browse files
Show More
@@ -441,6 +441,13 b' class bufferedinputpipe:'
441
441
442
442
443 def mmapread(fp, size=None):
443 def mmapread(fp, size=None):
444 """Read a file content using mmap
445
446 The responsability of checking the file system is mmap safe is the
447 responsability of the caller.
448
449 In some case, a normal string might be returned.
450 """
444 if size == 0:
451 if size == 0:
445 # size of 0 to mmap.mmap() means "all data"
452 # size of 0 to mmap.mmap() means "all data"
446 # rather than "zero bytes", so special case that.
453 # rather than "zero bytes", so special case that.
@@ -189,6 +189,35 b' class abstractvfs:'
189 def lstat(self, path: Optional[bytes] = None):
189 def lstat(self, path: Optional[bytes] = None):
190 return os.lstat(self.join(path))
190 return os.lstat(self.join(path))
191
191
192 def is_mmap_safe(self, path: Optional[bytes] = None) -> bool:
193 """return True if it is safe to read a file content as mmap
194
195 This focus on the file system aspect of such safety, the application
196 logic around that file is not taken into account, so caller need to
197 make sure the file won't be truncated in a way that will create SIGBUS
198 on access.
199
200
201 The initial motivation for this logic is that if mmap is used on NFS
202 and somebody deletes the mapped file (e.g. by renaming on top of it),
203 then you get SIGBUS, which can be pretty disruptive: we get core dump
204 reports, and the process terminates without writing to the blackbox.
205
206 Instead in this situation we prefer to read the file normally.
207 The risk of ESTALE in the middle of the read remains, but it's
208 smaller because we read sooner and the error should be reported
209 just as any other error.
210
211 Note that python standard library does not offer the necessary function
212 to detect the file stem bits. So this detection rely on compiled bits
213 and is not available in pure python.
214 """
215 # XXX Since we already assume a vfs to address a consistent file system
216 # in other location, we could determine the fstype once for the root
217 # and cache that value.
218 fstype = util.getfstype(self.join(path))
219 return fstype is not None and fstype != b'nfs'
220
192 def listdir(self, path: Optional[bytes] = None):
221 def listdir(self, path: Optional[bytes] = None):
193 return os.listdir(self.join(path))
222 return os.listdir(self.join(path))
194
223
General Comments 0
You need to be logged in to leave comments. Login now