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