(self, *, path, parent_fd, name, st, cache, flags=flags_normal, last_try=False, strip_prefix)
| 1413 | return status |
| 1414 | |
| 1415 | def process_file(self, *, path, parent_fd, name, st, cache, flags=flags_normal, last_try=False, strip_prefix): |
| 1416 | with self.create_helper(path, st, None, strip_prefix=strip_prefix) as ( |
| 1417 | item, |
| 1418 | status, |
| 1419 | hardlinked, |
| 1420 | hl_chunks, |
| 1421 | ): # no status yet |
| 1422 | if item is None: |
| 1423 | return status |
| 1424 | with OsOpen(path=path, parent_fd=parent_fd, name=name, flags=flags, noatime=True) as fd: |
| 1425 | with backup_io("fstat"): |
| 1426 | st = stat_update_check(st, os.fstat(fd)) |
| 1427 | item.update(self.metadata_collector.stat_simple_attrs(st, path, fd=fd)) |
| 1428 | item.update(self.metadata_collector.stat_ext_attrs(st, path, fd=fd)) |
| 1429 | maybe_exclude_by_attr(item) # check early, before processing all the file content |
| 1430 | is_special_file = is_special(st.st_mode) |
| 1431 | if is_special_file: |
| 1432 | # we process a special file like a regular file. reflect that in mode, |
| 1433 | # so it can be extracted / accessed in FUSE mount like a regular file. |
| 1434 | # this needs to be done early, so that part files also get the patched mode. |
| 1435 | item.mode = stat.S_IFREG | stat.S_IMODE(item.mode) |
| 1436 | # we begin processing chunks now. |
| 1437 | if hl_chunks is not None: # create_helper gave us chunks from a previous hard link |
| 1438 | item.chunks = [] |
| 1439 | for chunk_id, chunk_size in hl_chunks: |
| 1440 | # process one-by-one, so we will know in item.chunks how far we got |
| 1441 | chunk_entry = cache.reuse_chunk(chunk_id, chunk_size, self.stats) |
| 1442 | item.chunks.append(chunk_entry) |
| 1443 | else: # normal case, no "2nd+" hard link |
| 1444 | if not is_special_file: |
| 1445 | hashed_path = safe_encode(item.path) # path as in archive item! |
| 1446 | started_hashing = time.monotonic() |
| 1447 | path_hash = self.key.id_hash(hashed_path) |
| 1448 | self.stats.hashing_time += time.monotonic() - started_hashing |
| 1449 | known, chunks = cache.file_known_and_unchanged(hashed_path, path_hash, st) |
| 1450 | else: |
| 1451 | # in --read-special mode, we may be called for special files. |
| 1452 | # there should be no information in the cache about special files processed in |
| 1453 | # read-special mode, but we better play safe as this was wrong in the past: |
| 1454 | hashed_path = path_hash = None |
| 1455 | known, chunks = False, None |
| 1456 | if chunks is not None: |
| 1457 | # Make sure all ids are available |
| 1458 | for chunk in chunks: |
| 1459 | if not cache.seen_chunk(chunk.id): |
| 1460 | # cache said it is unmodified, but we lost a chunk: process file like modified |
| 1461 | status = "M" |
| 1462 | break |
| 1463 | else: |
| 1464 | item.chunks = [] |
| 1465 | for chunk in chunks: |
| 1466 | # process one-by-one, so we will know in item.chunks how far we got |
| 1467 | cache.reuse_chunk(chunk.id, chunk.size, self.stats) |
| 1468 | item.chunks.append(chunk) |
| 1469 | status = "U" # regular file, unchanged |
| 1470 | else: |
| 1471 | status = "M" if known else "A" # regular file, modified or added |
| 1472 | self.print_file_status(status, path) |
nothing calls this directly
no test coverage detected