)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Object-server: Only raises 500 if put races with another encryption IV"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Previously, link_fd_to_path would automatically unlink and overwrite"},{"line_number":10,"context_line":"existing files when encountering EEXIST errors."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This commit introduces metadata-aware collision detection:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"631d786c_cd5458c3","line":9,"updated":"2025-12-09 18:59:36.000000000","message":"nit: that was true before the parent patch removed the unlink, but it\u0027s not strictly true for *this* patch. However, I\u0027m thining maybe this should be squashed anyway so it\u0027s moot. I feel like this commit message was written to cover both this and the parent change??","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ec495c9320b30918a5e704aab796f809d560dff7","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Object-server: Only raises 500 if put races with another encryption IV"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Previously, link_fd_to_path would automatically unlink and overwrite"},{"line_number":10,"context_line":"existing files when encountering EEXIST errors."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This commit introduces metadata-aware collision detection:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"22ca2097_e54d1f2d","line":9,"in_reply_to":"631d786c_cd5458c3","updated":"2025-12-09 23:00:04.000000000","message":"Done","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"72839fe717bf850a8acc2ee9cd5552849d1a7bd0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"e91bdd10_9d505cbf","updated":"2025-12-04 06:11:05.000000000","message":"working in progress to add more test assertions.","commit_id":"d64e4efb9f08b8337769433755f2d5a69ea89a11"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"307a3641_16140228","updated":"2025-12-09 18:59:36.000000000","message":"LGTM: this doesn\u0027t change the linkat() behaviour, it just changes the way we handle EEXIST errors. We need this to get a better/more accurate insight into how many EEXISTs are due to genuine timestamp collisions vs replication races.\n\nI think we might want to squash this into the parent and keep some/all of THIS patches commit message?\n\nSome fixups for my comments here: \n\nsq: _safe_metadata_linkat fixups  https://review.opendev.org/c/openstack/swift/+/970295","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"}],"swift/obj/diskfile.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"72839fe717bf850a8acc2ee9cd5552849d1a7bd0","unresolved":true,"context_lines":[{"line_number":1962,"context_line":"            # If the file exists, we need to check if the metadata matches"},{"line_number":1963,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"},{"line_number":1964,"context_line":"                existing_metadata \u003d read_metadata(f)"},{"line_number":1965,"context_line":"            if existing_metadata !\u003d metadata:"},{"line_number":1966,"context_line":"                raise FileExistsError("},{"line_number":1967,"context_line":"                    \u0027Conflicting pre-existing metadata: %r !\u003d %r (on disk)\u0027 % ("},{"line_number":1968,"context_line":"                        metadata, existing_metadata))"}],"source_content_type":"text/x-python","patch_set":2,"id":"42c4ae8d_f8084256","line":1965,"updated":"2025-12-04 06:11:05.000000000","message":"for the case which we want to avoid which ssync replicates replica to a node before the same PUT request reach the that node, ``existing_metadata`` will be exact same as `` metadata``.\n\ncan we add some comments to explain why we need this check?","commit_id":"2d5349527817e2966996e6cc9f8cc41cf275e39d"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3d24fcc09b57b8c72d23e65a7df9adec47921782","unresolved":false,"context_lines":[{"line_number":1962,"context_line":"            # If the file exists, we need to check if the metadata matches"},{"line_number":1963,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"},{"line_number":1964,"context_line":"                existing_metadata \u003d read_metadata(f)"},{"line_number":1965,"context_line":"            if existing_metadata !\u003d metadata:"},{"line_number":1966,"context_line":"                raise FileExistsError("},{"line_number":1967,"context_line":"                    \u0027Conflicting pre-existing metadata: %r !\u003d %r (on disk)\u0027 % ("},{"line_number":1968,"context_line":"                        metadata, existing_metadata))"}],"source_content_type":"text/x-python","patch_set":2,"id":"3cb0d6d9_4a6826dd","line":1965,"in_reply_to":"42c4ae8d_f8084256","updated":"2025-12-08 05:56:17.000000000","message":"Done","commit_id":"2d5349527817e2966996e6cc9f8cc41cf275e39d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":1967,"context_line":"            #    should silently succeed to maintain idempotency."},{"line_number":1968,"context_line":"            #"},{"line_number":1969,"context_line":"            # 2. Timestamp collision with conflicting data: Two concurrent PUT"},{"line_number":1970,"context_line":"            #    requests with the same timestamp but different content (due to"},{"line_number":1971,"context_line":"            #    different encryption IVs used) raced to create the same"},{"line_number":1972,"context_line":"            #    object. In this case, metadata will differ and we must raise"},{"line_number":1973,"context_line":"            #    an error to prevent silent data corruption."},{"line_number":1974,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":5,"id":"78562fdd_2e4acdfd","line":1971,"range":{"start_line":1970,"start_character":72,"end_line":1971,"end_character":47},"updated":"2025-12-09 18:59:36.000000000","message":"this is only one example: in general (remember, this is BaseDiskFileWriter so applies to EC and replicated policies) different content can be due to encryption or different client provided plain text.","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ec495c9320b30918a5e704aab796f809d560dff7","unresolved":false,"context_lines":[{"line_number":1967,"context_line":"            #    should silently succeed to maintain idempotency."},{"line_number":1968,"context_line":"            #"},{"line_number":1969,"context_line":"            # 2. Timestamp collision with conflicting data: Two concurrent PUT"},{"line_number":1970,"context_line":"            #    requests with the same timestamp but different content (due to"},{"line_number":1971,"context_line":"            #    different encryption IVs used) raced to create the same"},{"line_number":1972,"context_line":"            #    object. In this case, metadata will differ and we must raise"},{"line_number":1973,"context_line":"            #    an error to prevent silent data corruption."},{"line_number":1974,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":5,"id":"d5793739_41f95859","line":1971,"range":{"start_line":1970,"start_character":72,"end_line":1971,"end_character":47},"in_reply_to":"78562fdd_2e4acdfd","updated":"2025-12-09 23:00:04.000000000","message":"Done","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":1972,"context_line":"            #    object. In this case, metadata will differ and we must raise"},{"line_number":1973,"context_line":"            #    an error to prevent silent data corruption."},{"line_number":1974,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"},{"line_number":1975,"context_line":"                existing_metadata \u003d read_metadata(f)"},{"line_number":1976,"context_line":"            if existing_metadata !\u003d metadata:"},{"line_number":1977,"context_line":"                raise FileExistsError("},{"line_number":1978,"context_line":"                    \u0027Conflicting pre-existing metadata: %r !\u003d %r (on disk)\u0027 % ("}],"source_content_type":"text/x-python","patch_set":5,"id":"08752f12_142b3f6e","line":1975,"updated":"2025-12-09 18:59:36.000000000","message":"nit: I think we can just pass target_path to read_metadata - xattr will accept fd\u0027s or paths","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"4955ae61bf44d96fdbcf8031786773b618e156d8","unresolved":true,"context_lines":[{"line_number":1973,"context_line":"            #    an error to prevent silent data corruption."},{"line_number":1974,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"},{"line_number":1975,"context_line":"                existing_metadata \u003d read_metadata(f)"},{"line_number":1976,"context_line":"            if existing_metadata !\u003d metadata:"},{"line_number":1977,"context_line":"                raise FileExistsError("},{"line_number":1978,"context_line":"                    \u0027Conflicting pre-existing metadata: %r !\u003d %r (on disk)\u0027 % ("},{"line_number":1979,"context_line":"                        metadata, existing_metadata))"}],"source_content_type":"text/x-python","patch_set":5,"id":"1afd8739_00ea3ffe","line":1976,"updated":"2025-12-08 23:16:23.000000000","message":"@matt@oliver.net.au Matt asked some good questions on the order of local file system operations during new object PUT, like will object PUT be streaming into a temporary file, will metadata be written in the end, so there are chances the logic here won\u0027t be able to detect that.\n\nNo, that won\u0027t happen, because we are using linkat + O_TMPFILE which will create the final object file atomically, see\nhttps://github.com/NVIDIA/swift/blob/master/swift/obj/diskfile.py#L1979\nand\nhttps://yakking.branchable.com/posts/atomic-file-creation-tmpfile/\n\nIn short, a invisible temporary file will be created to receive the new object, after all bytes are received, metadata will be written, and then fsync() and drop_buffer_cache() will be called, and finally a linkat call will create the final file on disk atomically.","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d9195cd6883dd88c41a4c3967c52ccc4add37f2c","unresolved":true,"context_lines":[{"line_number":1973,"context_line":"            #    an error to prevent silent data corruption."},{"line_number":1974,"context_line":"            with open(target_path, \u0027rb\u0027) as f:"},{"line_number":1975,"context_line":"                existing_metadata \u003d read_metadata(f)"},{"line_number":1976,"context_line":"            if existing_metadata !\u003d metadata:"},{"line_number":1977,"context_line":"                raise FileExistsError("},{"line_number":1978,"context_line":"                    \u0027Conflicting pre-existing metadata: %r !\u003d %r (on disk)\u0027 % ("},{"line_number":1979,"context_line":"                        metadata, existing_metadata))"}],"source_content_type":"text/x-python","patch_set":5,"id":"412477dc_f8e44ba8","line":1976,"in_reply_to":"1afd8739_00ea3ffe","updated":"2025-12-08 23:32:58.000000000","message":"the temporary file was invisible before linkat creates the final file with the formal object path, and it\u0027s crash-proof: if OS crashes in the middle of those operations and before linkat completes, the invisible temporary file will be removed automatically by kernel.","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"}],"test/probe/test_timestamp_collision.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"72839fe717bf850a8acc2ee9cd5552849d1a7bd0","unresolved":true,"context_lines":[{"line_number":391,"context_line":"            headers\u003d{\u0027x-storage-policy\u0027: self.policy.name})"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def test_replicator_race(self):"},{"line_number":394,"context_line":"        num_sent \u003d 0"},{"line_number":395,"context_line":"        num_sent \u003d 0"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"        orig_make_putter \u003d ReplicatedObjectController._make_putter"}],"source_content_type":"text/x-python","patch_set":3,"id":"eb80702e_faf0a8db","line":394,"updated":"2025-12-04 06:11:05.000000000","message":"to be deleted.","commit_id":"d64e4efb9f08b8337769433755f2d5a69ea89a11"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3d24fcc09b57b8c72d23e65a7df9adec47921782","unresolved":false,"context_lines":[{"line_number":391,"context_line":"            headers\u003d{\u0027x-storage-policy\u0027: self.policy.name})"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def test_replicator_race(self):"},{"line_number":394,"context_line":"        num_sent \u003d 0"},{"line_number":395,"context_line":"        num_sent \u003d 0"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"        orig_make_putter \u003d ReplicatedObjectController._make_putter"}],"source_content_type":"text/x-python","patch_set":3,"id":"1341644f_3a5e86f0","line":394,"in_reply_to":"eb80702e_faf0a8db","updated":"2025-12-08 05:56:17.000000000","message":"Done","commit_id":"d64e4efb9f08b8337769433755f2d5a69ea89a11"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"72839fe717bf850a8acc2ee9cd5552849d1a7bd0","unresolved":true,"context_lines":[{"line_number":421,"context_line":"            self.swift.upload_object(BytesIO(contents), self.account,"},{"line_number":422,"context_line":"                                     self.container_name, self.object_name,"},{"line_number":423,"context_line":"                                     headers\u003dheaders)"},{"line_number":424,"context_line":"        self.assertEqual(num_sent, self.policy.object_ring.replica_count)"},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"    def test_request_race(self):"},{"line_number":427,"context_line":"        contents \u003d b\u0027a\u0027 * 97"}],"source_content_type":"text/x-python","patch_set":3,"id":"cc108410_9cd069af","line":424,"updated":"2025-12-04 06:11:05.000000000","message":"need to verify that:\n- Upload completes successfully despite concurrent replication\n- All replicas have consistent timestamps\n- All replicas contain identical, correct content (no data corruption)\n- Replication during active writes doesn\u0027t cause data inconsistencies","commit_id":"d64e4efb9f08b8337769433755f2d5a69ea89a11"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3d24fcc09b57b8c72d23e65a7df9adec47921782","unresolved":false,"context_lines":[{"line_number":421,"context_line":"            self.swift.upload_object(BytesIO(contents), self.account,"},{"line_number":422,"context_line":"                                     self.container_name, self.object_name,"},{"line_number":423,"context_line":"                                     headers\u003dheaders)"},{"line_number":424,"context_line":"        self.assertEqual(num_sent, self.policy.object_ring.replica_count)"},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"    def test_request_race(self):"},{"line_number":427,"context_line":"        contents \u003d b\u0027a\u0027 * 97"}],"source_content_type":"text/x-python","patch_set":3,"id":"05cd1f89_409a15c1","line":424,"in_reply_to":"cc108410_9cd069af","updated":"2025-12-08 05:56:17.000000000","message":"Done","commit_id":"d64e4efb9f08b8337769433755f2d5a69ea89a11"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"eed77f2aa25e3396fb466f0751883408d148cc9c","unresolved":true,"context_lines":[{"line_number":456,"context_line":"        timestamps \u003d [resp[\u0027X-Timestamp\u0027] for resp in head_responses]"},{"line_number":457,"context_line":"        self.assertEqual(timestamps[0], str(now.normal))"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"        # Verify all replicas have the correct content"},{"line_number":460,"context_line":"        for resp_headers, body in content_responses:"},{"line_number":461,"context_line":"            self.assertEqual(body, contents, \"Content mismatch on replica\")"},{"line_number":462,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"0b516453_b09969b7","line":459,"updated":"2025-12-09 23:53:36.000000000","message":"this will fail when encryption is turned on during testing, let me fix this.","commit_id":"dcce311ddc489d4a833340320ba6d20062afb635"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"f0cddfd1f815184290e50d3e2559fcc3c6a3d157","unresolved":false,"context_lines":[{"line_number":456,"context_line":"        timestamps \u003d [resp[\u0027X-Timestamp\u0027] for resp in head_responses]"},{"line_number":457,"context_line":"        self.assertEqual(timestamps[0], str(now.normal))"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"        # Verify all replicas have the correct content"},{"line_number":460,"context_line":"        for resp_headers, body in content_responses:"},{"line_number":461,"context_line":"            self.assertEqual(body, contents, \"Content mismatch on replica\")"},{"line_number":462,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"c6600be5_81604baa","line":459,"in_reply_to":"0b516453_b09969b7","updated":"2025-12-09 23:54:40.000000000","message":"Done","commit_id":"dcce311ddc489d4a833340320ba6d20062afb635"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"eed77f2aa25e3396fb466f0751883408d148cc9c","unresolved":true,"context_lines":[{"line_number":517,"context_line":"            head_responses.append(metadata)"},{"line_number":518,"context_line":"        self.assertEqual(len(head_responses),"},{"line_number":519,"context_line":"                         self.policy.object_ring.replica_count)"},{"line_number":520,"context_line":"        # N.B. the first upload_object received responses [201, 500, 500] and"},{"line_number":521,"context_line":"        # the second upload_object got responses [201, 500, 201]."},{"line_number":522,"context_line":"        color_counts \u003d Counter(["},{"line_number":523,"context_line":"            resp[\u0027X-Object-Meta-Color\u0027]"}],"source_content_type":"text/x-python","patch_set":6,"id":"0e97cf42_82f66aa5","line":520,"updated":"2025-12-09 23:53:36.000000000","message":"this is what I found when added debug tracepoint, that\u0027ll be great if we can make assertions on those return status codes.","commit_id":"dcce311ddc489d4a833340320ba6d20062afb635"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"f0cddfd1f815184290e50d3e2559fcc3c6a3d157","unresolved":false,"context_lines":[{"line_number":517,"context_line":"            head_responses.append(metadata)"},{"line_number":518,"context_line":"        self.assertEqual(len(head_responses),"},{"line_number":519,"context_line":"                         self.policy.object_ring.replica_count)"},{"line_number":520,"context_line":"        # N.B. the first upload_object received responses [201, 500, 500] and"},{"line_number":521,"context_line":"        # the second upload_object got responses [201, 500, 201]."},{"line_number":522,"context_line":"        color_counts \u003d Counter(["},{"line_number":523,"context_line":"            resp[\u0027X-Object-Meta-Color\u0027]"}],"source_content_type":"text/x-python","patch_set":6,"id":"514e2897_10b76894","line":520,"in_reply_to":"0e97cf42_82f66aa5","updated":"2025-12-09 23:54:40.000000000","message":"Done","commit_id":"dcce311ddc489d4a833340320ba6d20062afb635"}],"test/unit/obj/test_server.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":1893,"context_line":"        t0 \u003d next(self.ts)"},{"line_number":1894,"context_line":"        req \u003d Request.blank("},{"line_number":1895,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":1896,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: t0.normal,"},{"line_number":1897,"context_line":"                     \u0027Content-Length\u0027: \u00276\u0027,"},{"line_number":1898,"context_line":"                     \u0027Content-Type\u0027: \u0027application/octet-stream\u0027,"},{"line_number":1899,"context_line":"                     \u0027If-None-Match\u0027: \u0027notthere\u0027})"}],"source_content_type":"text/x-python","patch_set":5,"id":"c2db0bb6_3fc1eee3","line":1896,"range":{"start_line":1896,"start_character":36,"end_line":1896,"end_character":45},"updated":"2025-12-09 18:59:36.000000000","message":"nit: strictly, these timestamps should be ``t0.internal`` to match real proxy behaviour","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ec495c9320b30918a5e704aab796f809d560dff7","unresolved":false,"context_lines":[{"line_number":1893,"context_line":"        t0 \u003d next(self.ts)"},{"line_number":1894,"context_line":"        req \u003d Request.blank("},{"line_number":1895,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":1896,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: t0.normal,"},{"line_number":1897,"context_line":"                     \u0027Content-Length\u0027: \u00276\u0027,"},{"line_number":1898,"context_line":"                     \u0027Content-Type\u0027: \u0027application/octet-stream\u0027,"},{"line_number":1899,"context_line":"                     \u0027If-None-Match\u0027: \u0027notthere\u0027})"}],"source_content_type":"text/x-python","patch_set":5,"id":"d699368a_7bf1e8cf","line":1896,"range":{"start_line":1896,"start_character":36,"end_line":1896,"end_character":45},"in_reply_to":"c2db0bb6_3fc1eee3","updated":"2025-12-09 23:00:04.000000000","message":"Done","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":1910,"context_line":"        resp \u003d req.get_response(self.object_controller)"},{"line_number":1911,"context_line":"        self.assertEqual(resp.status_int, 409)"},{"line_number":1912,"context_line":""},{"line_number":1913,"context_line":"    def test_PUT_timestamp_collision_linkat_race(self):"},{"line_number":1914,"context_line":"        t0 \u003d next(self.ts)"},{"line_number":1915,"context_line":"        req \u003d Request.blank("},{"line_number":1916,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f6ee0f4_a189ae4a","line":1913,"updated":"2025-12-09 18:59:36.000000000","message":"please decorate with \n    @requires_o_tmpfile_support_in_tmp\n\n(macos has no linkat)","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ec495c9320b30918a5e704aab796f809d560dff7","unresolved":false,"context_lines":[{"line_number":1910,"context_line":"        resp \u003d req.get_response(self.object_controller)"},{"line_number":1911,"context_line":"        self.assertEqual(resp.status_int, 409)"},{"line_number":1912,"context_line":""},{"line_number":1913,"context_line":"    def test_PUT_timestamp_collision_linkat_race(self):"},{"line_number":1914,"context_line":"        t0 \u003d next(self.ts)"},{"line_number":1915,"context_line":"        req \u003d Request.blank("},{"line_number":1916,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"}],"source_content_type":"text/x-python","patch_set":5,"id":"dcf7e2da_c6dfefae","line":1913,"in_reply_to":"3f6ee0f4_a189ae4a","updated":"2025-12-09 23:00:04.000000000","message":"Done","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":1923,"context_line":""},{"line_number":1924,"context_line":"        def race_linkat(fd, target_path, *args, **kwargs):"},{"line_number":1925,"context_line":"            with open(target_path, \u0027w\u0027) as f:"},{"line_number":1926,"context_line":"                f.write(\u0027VERIFY\u0027)"},{"line_number":1927,"context_line":"            return orig_linkat(fd, target_path, *args, **kwargs)"},{"line_number":1928,"context_line":"        with mock.patch(\u0027swift.obj.diskfile.link_fd_to_path\u0027, race_linkat):"},{"line_number":1929,"context_line":"            resp \u003d req.get_response(self.object_controller)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ca4bd90b_27571f9d","line":1926,"updated":"2025-12-09 18:59:36.000000000","message":"there\u0027s another exception raised from orig_linkat because the target_path has NO metadata - we should write some metadata here too","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ec495c9320b30918a5e704aab796f809d560dff7","unresolved":false,"context_lines":[{"line_number":1923,"context_line":""},{"line_number":1924,"context_line":"        def race_linkat(fd, target_path, *args, **kwargs):"},{"line_number":1925,"context_line":"            with open(target_path, \u0027w\u0027) as f:"},{"line_number":1926,"context_line":"                f.write(\u0027VERIFY\u0027)"},{"line_number":1927,"context_line":"            return orig_linkat(fd, target_path, *args, **kwargs)"},{"line_number":1928,"context_line":"        with mock.patch(\u0027swift.obj.diskfile.link_fd_to_path\u0027, race_linkat):"},{"line_number":1929,"context_line":"            resp \u003d req.get_response(self.object_controller)"}],"source_content_type":"text/x-python","patch_set":5,"id":"43a5d46d_c9083615","line":1926,"in_reply_to":"ca4bd90b_27571f9d","updated":"2025-12-09 23:00:04.000000000","message":"Done","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0735d201e508f03397a8ebbbcb758815bc4c5852","unresolved":true,"context_lines":[{"line_number":1930,"context_line":"        self.assertEqual(resp.status_int, 500)"},{"line_number":1931,"context_line":"        self.assertIn(\u0027linkat: File exists\u0027, self.logger.records[\u0027ERROR\u0027][0])"},{"line_number":1932,"context_line":""},{"line_number":1933,"context_line":"    def test_PUT_timestamp_collision_linkat_race_metadata_match(self):"},{"line_number":1934,"context_line":"        t0 \u003d next(self.ts)"},{"line_number":1935,"context_line":"        req \u003d Request.blank("},{"line_number":1936,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"}],"source_content_type":"text/x-python","patch_set":5,"id":"108fa7a5_c14cff3d","line":1933,"updated":"2025-12-09 18:59:36.000000000","message":"please decorate with \n    @requires_o_tmpfile_support_in_tmp\n\n(macos has no linkat)\n\nThis test actually passes but the race_linkat isn\u0027t being called so it\u0027s misleading to think it passes, better to skip.","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ec495c9320b30918a5e704aab796f809d560dff7","unresolved":false,"context_lines":[{"line_number":1930,"context_line":"        self.assertEqual(resp.status_int, 500)"},{"line_number":1931,"context_line":"        self.assertIn(\u0027linkat: File exists\u0027, self.logger.records[\u0027ERROR\u0027][0])"},{"line_number":1932,"context_line":""},{"line_number":1933,"context_line":"    def test_PUT_timestamp_collision_linkat_race_metadata_match(self):"},{"line_number":1934,"context_line":"        t0 \u003d next(self.ts)"},{"line_number":1935,"context_line":"        req \u003d Request.blank("},{"line_number":1936,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"}],"source_content_type":"text/x-python","patch_set":5,"id":"617a3da9_43d150a5","line":1933,"in_reply_to":"108fa7a5_c14cff3d","updated":"2025-12-09 23:00:04.000000000","message":"Done","commit_id":"9a5df1a5698a8bd8d64168a9eec2db8a64dd0543"}]}
