)]}'
{"swift/common/linkat.py":[{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    # From include/uapi/linux/fcntl.h"},{"line_number":26,"context_line":"    AT_FDCWD \u003d -100"},{"line_number":27,"context_line":"    AT_SYMLINK_FOLLOW \u003d 1024"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    __slots__ \u003d \u0027_c_linkat\u0027"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_f4819cfb","line":27,"updated":"2015-03-09 16:56:48.000000000","message":"Why not use hex syntax, as in the actual header?\n\n    #define AT_SYMLINK_FOLLOW       0x400   /* Follow symbolic links.  */","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    # From include/uapi/linux/fcntl.h"},{"line_number":26,"context_line":"    AT_FDCWD \u003d -100"},{"line_number":27,"context_line":"    AT_SYMLINK_FOLLOW \u003d 1024"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    __slots__ \u003d \u0027_c_linkat\u0027"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_e7d39901","line":27,"in_reply_to":"9a80dd14_f4819cfb","updated":"2015-03-10 05:49:06.000000000","message":"AT_FDCWD is defined as int in the header file where as AT_SYMLINK_FOLLOW is in hex. Thought, I\u0027ll stick to one syntax. I\u0027ll use hex for AT_SYMLINK_FOLLOW, should be okay.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            self._c_linkat \u003d None"},{"line_number":38,"context_line":"            return"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        c_linkat.argtypes \u003d [ctypes.c_int, ctypes.c_char_p, ctypes.c_int,"},{"line_number":41,"context_line":"                             ctypes.c_char_p, ctypes.c_int]"},{"line_number":42,"context_line":"        c_linkat.restype \u003d ctypes.c_int"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_d4bc98bd","line":40,"updated":"2015-03-09 16:56:48.000000000","message":"A very personal preference, but anyway: how about putting this on 3 lines: 1 for the \u0027old\u0027 pair, one for the \u0027new\u0027 pair and one for the flags?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            self._c_linkat \u003d None"},{"line_number":38,"context_line":"            return"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        c_linkat.argtypes \u003d [ctypes.c_int, ctypes.c_char_p, ctypes.c_int,"},{"line_number":41,"context_line":"                             ctypes.c_char_p, ctypes.c_int]"},{"line_number":42,"context_line":"        c_linkat.restype \u003d ctypes.c_int"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_c785b5cf","line":40,"in_reply_to":"9a80dd14_d4bc98bd","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        return self._c_linkat is not None"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def __call__(self, olddirfd, oldpath, newdirfd, newpath, flags):"},{"line_number":60,"context_line":"        \"\"\"man 2 linkat\"\"\""},{"line_number":61,"context_line":"        if not self.available:"},{"line_number":62,"context_line":"            raise EnvironmentError(\u0027linkat not available\u0027)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_74f12c94","line":60,"updated":"2015-03-09 16:56:48.000000000","message":"I\u0027d put some more information. Maybe consider accepting file-like objects as FDs and call the appropriate `fileno` method?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        return self._c_linkat is not None"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def __call__(self, olddirfd, oldpath, newdirfd, newpath, flags):"},{"line_number":60,"context_line":"        \"\"\"man 2 linkat\"\"\""},{"line_number":61,"context_line":"        if not self.available:"},{"line_number":62,"context_line":"            raise EnvironmentError(\u0027linkat not available\u0027)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_877f3ddf","line":60,"in_reply_to":"9a80dd14_74f12c94","updated":"2015-03-10 05:49:06.000000000","message":"I did see it earlier in your splice bindings (after which this linkat.py binding is modeled, thanks to you) and decided against it as it would be dead code. I don\u0027t see any consumers passing File object. If required, this can be done on the consumer side. It\u0027s good to keep the binding very minimal and implement most of validation and pre processing in the wrapper that\u0027s using this which in this case is flink()","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"}],"swift/common/utils.py":[{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":3386,"context_line":"    :param path: path of hard link to be created"},{"line_number":3387,"context_line":"    \"\"\""},{"line_number":3388,"context_line":""},{"line_number":3389,"context_line":"    assert(isinstance(fd, int))"},{"line_number":3390,"context_line":""},{"line_number":3391,"context_line":"    return linkat(linkat.AT_FDCWD, \"/proc/self/fd/%s\" % (fd), linkat.AT_FDCWD,"},{"line_number":3392,"context_line":"                  path, linkat.AT_SYMLINK_FOLLOW)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_74768c07","line":3389,"updated":"2015-03-09 16:56:48.000000000","message":"This should be handled by `ctypes` in `linkat`. If a type-check is really necessary, raise an appropriate `TypeError` instead?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":3386,"context_line":"    :param path: path of hard link to be created"},{"line_number":3387,"context_line":"    \"\"\""},{"line_number":3388,"context_line":""},{"line_number":3389,"context_line":"    assert(isinstance(fd, int))"},{"line_number":3390,"context_line":""},{"line_number":3391,"context_line":"    return linkat(linkat.AT_FDCWD, \"/proc/self/fd/%s\" % (fd), linkat.AT_FDCWD,"},{"line_number":3392,"context_line":"                  path, linkat.AT_SYMLINK_FOLLOW)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_c7a13547","line":3389,"in_reply_to":"9a80dd14_74768c07","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":3388,"context_line":""},{"line_number":3389,"context_line":"    assert(isinstance(fd, int))"},{"line_number":3390,"context_line":""},{"line_number":3391,"context_line":"    return linkat(linkat.AT_FDCWD, \"/proc/self/fd/%s\" % (fd), linkat.AT_FDCWD,"},{"line_number":3392,"context_line":"                  path, linkat.AT_SYMLINK_FOLLOW)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_f7a43e09","line":3391,"updated":"2015-03-09 16:56:48.000000000","message":"`fd` is supposed to be an `int`, so use `%d` in the format string.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":3388,"context_line":""},{"line_number":3389,"context_line":"    assert(isinstance(fd, int))"},{"line_number":3390,"context_line":""},{"line_number":3391,"context_line":"    return linkat(linkat.AT_FDCWD, \"/proc/self/fd/%s\" % (fd), linkat.AT_FDCWD,"},{"line_number":3392,"context_line":"                  path, linkat.AT_SYMLINK_FOLLOW)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_a79e0105","line":3391,"in_reply_to":"9a80dd14_f7a43e09","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":934,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":935,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":936,"context_line":"        # directories created by makedirs_count()"},{"line_number":937,"context_line":"        for i in range(0, count + 1):"},{"line_number":938,"context_line":"            fsync_dir(dirpath)"},{"line_number":939,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":940,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_2b64d820","side":"PARENT","line":937,"updated":"2015-03-13 14:53:09.000000000","message":"Prefer `xrange` over `range` for a counter?","commit_id":"09474f28b780453d034d3fe3acee73d764202544"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":934,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":935,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":936,"context_line":"        # directories created by makedirs_count()"},{"line_number":937,"context_line":"        for i in range(0, count + 1):"},{"line_number":938,"context_line":"            fsync_dir(dirpath)"},{"line_number":939,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":940,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_016fc22b","side":"PARENT","line":937,"in_reply_to":"9a80dd14_2b64d820","updated":"2015-03-16 05:51:27.000000000","message":"Done","commit_id":"09474f28b780453d034d3fe3acee73d764202544"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":939,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":940,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":941,"context_line":"        # directories created by makedirs_count()"},{"line_number":942,"context_line":"        for i in range(0, count + 1):"},{"line_number":943,"context_line":"            fsync_dir(dirpath)"},{"line_number":944,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":945,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_eb4560b4","line":942,"updated":"2015-03-13 14:53:09.000000000","message":"Prefer `xrange` over `range` for a counter?","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":939,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":940,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":941,"context_line":"        # directories created by makedirs_count()"},{"line_number":942,"context_line":"        for i in range(0, count + 1):"},{"line_number":943,"context_line":"            fsync_dir(dirpath)"},{"line_number":944,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":945,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_c1812ac4","line":942,"in_reply_to":"9a80dd14_eb4560b4","updated":"2015-03-16 05:51:27.000000000","message":"Done","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":974,"context_line":"            # Very rare for object path, but theoretically not impossible!"},{"line_number":975,"context_line":"            # Fall back to using os.rename() in such case"},{"line_number":976,"context_line":"            unique_tmp_path \u003d os.path.join(tmpdir, \".\".join("},{"line_number":977,"context_line":"                [md5(target_path).hexdigest(), uuid4().hex]))"},{"line_number":978,"context_line":"            logging.warning(_(\u0027link_fd_to_path: Path %s exists. Attempting to\u0027"},{"line_number":979,"context_line":"                              \u0027link at %s\u0027), target_path, unique_tmp_path)"},{"line_number":980,"context_line":"            linkat(linkat.AT_FDCWD, \"/proc/self/fd/%d\" % (fd),"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_cbadfc32","line":977,"updated":"2015-03-13 14:53:09.000000000","message":"Is there a reason to use the MD5 if you use a UUID anyway?","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":974,"context_line":"            # Very rare for object path, but theoretically not impossible!"},{"line_number":975,"context_line":"            # Fall back to using os.rename() in such case"},{"line_number":976,"context_line":"            unique_tmp_path \u003d os.path.join(tmpdir, \".\".join("},{"line_number":977,"context_line":"                [md5(target_path).hexdigest(), uuid4().hex]))"},{"line_number":978,"context_line":"            logging.warning(_(\u0027link_fd_to_path: Path %s exists. Attempting to\u0027"},{"line_number":979,"context_line":"                              \u0027link at %s\u0027), target_path, unique_tmp_path)"},{"line_number":980,"context_line":"            linkat(linkat.AT_FDCWD, \"/proc/self/fd/%d\" % (fd),"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_deaca5a1","line":977,"in_reply_to":"9a80dd14_cbadfc32","updated":"2015-03-16 05:51:27.000000000","message":"Well, not really. Was just being extra sure. I can remove it. Anyways, chances of actually hitting this code block is very slim though.","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":3472,"context_line":"    \"\"\""},{"line_number":3473,"context_line":"    Returns True if O_TMPFILE flag is supported in xfs and ext4 filesystems."},{"line_number":3474,"context_line":"    \"\"\""},{"line_number":3475,"context_line":"    return linkat.available and platform.system() \u003d\u003d \u0027Linux\u0027 \\"},{"line_number":3476,"context_line":"        and LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.15\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_4b502c32","line":3475,"updated":"2015-03-13 14:53:09.000000000","message":"Personal preference: I\u0027d write something along the lines of\n\n    return all([linkat.available,\n                platform.system() \u003d\u003d \u0027Linux\u0027,\n                LooseVersion ...,\n        ])\n\ninstead of a chain of `and`s.","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":3472,"context_line":"    \"\"\""},{"line_number":3473,"context_line":"    Returns True if O_TMPFILE flag is supported in xfs and ext4 filesystems."},{"line_number":3474,"context_line":"    \"\"\""},{"line_number":3475,"context_line":"    return linkat.available and platform.system() \u003d\u003d \u0027Linux\u0027 \\"},{"line_number":3476,"context_line":"        and LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.15\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_7e065987","line":3475,"in_reply_to":"9a80dd14_4b502c32","updated":"2015-03-16 05:51:27.000000000","message":"Done","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":16206,"name":"chenhuayi","email":"chenhuayi@huawei.com","username":"chenhuayi2"},"change_message_id":"ce5ef6c60e6c86c5b1ddf54c379af50cc5443fa2","unresolved":false,"context_lines":[{"line_number":939,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":940,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":941,"context_line":"        # directories created by makedirs_count()"},{"line_number":942,"context_line":"        for i in xrange(0, count + 1):"},{"line_number":943,"context_line":"            fsync_dir(dirpath)"},{"line_number":944,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":945,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa32b979_d21d9067","line":942,"updated":"2015-06-15 08:06:22.000000000","message":"Now, the swift is upgrade the Python2.x to Python3.x.\nhttps://review.openstack.org/#/c/185460/\n\nIs better to use six in this patch?","commit_id":"841ca5918d615db50282a5a7a77421bfb29c0198"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"70e4629ab70d46ce574370796787ff8a7bc4397a","unresolved":false,"context_lines":[{"line_number":965,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":966,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":967,"context_line":"        # directories created by makedirs_count()"},{"line_number":968,"context_line":"        for i in xrange(0, count + 1):"},{"line_number":969,"context_line":"            fsync_dir(dirpath)"},{"line_number":970,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":971,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a2fa921_0eb3ea0b","line":968,"updated":"2015-10-12 14:54:53.000000000","message":"Please, don\u0027t use xrange for compatibility with Python 3.\n\nThe file starts with \"from six.moves import range\", so range() is in fact xrange() in this file ;-)","commit_id":"0ae76ce78e89e1c302abb4fe3041b275fa646a7d"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"23a323f99801e51453ca7966599662675457e45f","unresolved":false,"context_lines":[{"line_number":965,"context_line":"        # fsync leaf dir after os.rename()."},{"line_number":966,"context_line":"        # If count\u003e0, starting from leaf dir, fsync parent dirs of all"},{"line_number":967,"context_line":"        # directories created by makedirs_count()"},{"line_number":968,"context_line":"        for i in xrange(0, count + 1):"},{"line_number":969,"context_line":"            fsync_dir(dirpath)"},{"line_number":970,"context_line":"            dirpath \u003d os.path.dirname(dirpath)"},{"line_number":971,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a2fa921_f7e428ad","line":968,"in_reply_to":"7a2fa921_0eb3ea0b","updated":"2015-10-13 05:33:25.000000000","message":"Thanks! Will do.","commit_id":"0ae76ce78e89e1c302abb4fe3041b275fa646a7d"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"70e4629ab70d46ce574370796787ff8a7bc4397a","unresolved":false,"context_lines":[{"line_number":3820,"context_line":"    \"\"\""},{"line_number":3821,"context_line":"    return all([linkat.available,"},{"line_number":3822,"context_line":"                platform.system() \u003d\u003d \u0027Linux\u0027,"},{"line_number":3823,"context_line":"                LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.15\u0027)])"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a2fa921_2eb4a6cf","line":3823,"updated":"2015-10-12 14:54:53.000000000","message":"FYI tempfile.TemporaryFile() uses O_TMPFILE if available in Python 3.5 and newer, but it doesn\u0027t check for the Linux kernel version. Instead, we try to create a file with a flag. If it fails, we store in a variable that the flag doesn\u0027t work:\nhttps://hg.python.org/cpython/file/288953a787ce/Lib/tempfile.py#l564\n\nWe use the same idea for other OS specific flags, like O_CLOEXEC or SOCK_CLOEXEC for example.\n\nBy the way, since O_TMPFILE is not supported by all operating systems, you must check at runtime on the directory that will store files.\n\nSee http://bugs.python.org/issue21515 for more information.\n\n(Is it really 3.15? CPython comment mentions 3.11.)","commit_id":"0ae76ce78e89e1c302abb4fe3041b275fa646a7d"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"4bf0353637e627ce08ec1bd02ff26294eb5488ae","unresolved":false,"context_lines":[{"line_number":3820,"context_line":"    \"\"\""},{"line_number":3821,"context_line":"    return all([linkat.available,"},{"line_number":3822,"context_line":"                platform.system() \u003d\u003d \u0027Linux\u0027,"},{"line_number":3823,"context_line":"                LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.15\u0027)])"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a2fa921_e3a9c325","line":3823,"in_reply_to":"7a2fa921_22e49c39","updated":"2015-10-13 08:23:13.000000000","message":"Ok, thanks for your explanation. It makes sense :-)\n\nBy the way, I tried on /tmp and it fails but in fact I misused the flag... I should open /tmp, not try to create /tmp/x, and os.O_CREAT must not be used with os.O_TMPFILE. tempfile of Python 3 uses flags:\n\n \u003e\u003e\u003e fd\u003dos.open(\"/tmp\", os.O_RDWR | os.O_EXCL | os.O_TMPFILE | os.O_NOFOLLOW)\n \u003e\u003e\u003e os.close(fd)","commit_id":"0ae76ce78e89e1c302abb4fe3041b275fa646a7d"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"23a323f99801e51453ca7966599662675457e45f","unresolved":false,"context_lines":[{"line_number":3820,"context_line":"    \"\"\""},{"line_number":3821,"context_line":"    return all([linkat.available,"},{"line_number":3822,"context_line":"                platform.system() \u003d\u003d \u0027Linux\u0027,"},{"line_number":3823,"context_line":"                LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.15\u0027)])"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a2fa921_22e49c39","line":3823,"in_reply_to":"7a2fa921_2eb4a6cf","updated":"2015-10-13 05:33:25.000000000","message":"Thanks for the feedback Victor. Yes, I\u0027m aware of tempfile.TemporaryFile() using O_TMPFILE in python 3.5. This was mentioned in commit message of earlier patchsets. Take a look.\n\nO_TMPFILE support was added to kernel in 3.11. All filesystems did not add support in 3.11 itself. tmpfs (3.11), ext3 (3.11), ext4 (3.11), XFS (3.15), btrfs (3.16). For most default installations (XFS), checking Linux \u003e\u003d 3.15 at object server start should work fine. Unlike other flags such as O_CLOEXEC where it\u0027s only dependent on kernel version (\u003e\u003d2.6.23), O_TMPFILE requires support from kernel AND the mounted filesystems too. The \"check once and store in variable\" isn\u0027t a good fit here because there can be many devices, each with a different filesystem (thanks to storage policies) and these devices get added and removed too. BUT, it might just work if we have this variable on a per device basis, which personally is an overkill I think.\n\nAnd the runtime check is indeed done during os.open(). We fallback to mkstemp() if the flag doesn\u0027t work. Refer to line 1847 in swift/obj/diskfile.py.\nI have tested this on recent lernel with glusterfs (no O_TMPFILE) and it throws a EOPNOTSUPP. Also tested this on rhel6 (2.x kernel) which throws EISDIR.","commit_id":"0ae76ce78e89e1c302abb4fe3041b275fa646a7d"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"2fda9b2d2ec0d3c8b40fa57223ae2b27a8e02386","unresolved":false,"context_lines":[{"line_number":1216,"context_line":"                  the newly created directories."},{"line_number":1217,"context_line":"    \"\"\""},{"line_number":1218,"context_line":"    dirpath \u003d os.path.dirname(target_path)"},{"line_number":1219,"context_line":"    for _junk in range(0, 2):"},{"line_number":1220,"context_line":"        try:"},{"line_number":1221,"context_line":"            linkat(linkat.AT_FDCWD, \"/proc/self/fd/%d\" % (fd),"},{"line_number":1222,"context_line":"                   linkat.AT_FDCWD, target_path, linkat.AT_SYMLINK_FOLLOW)"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_a8465c4c","line":1219,"updated":"2016-08-23 14:17:57.000000000","message":"can retries be passed in instead of hard coded? why 2? it seems a little magig","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c07fc46d9a2dfb98e51711aa9340f837b85ec11a","unresolved":false,"context_lines":[{"line_number":1216,"context_line":"                  the newly created directories."},{"line_number":1217,"context_line":"    \"\"\""},{"line_number":1218,"context_line":"    dirpath \u003d os.path.dirname(target_path)"},{"line_number":1219,"context_line":"    for _junk in range(0, 2):"},{"line_number":1220,"context_line":"        try:"},{"line_number":1221,"context_line":"            linkat(linkat.AT_FDCWD, \"/proc/self/fd/%d\" % (fd),"},{"line_number":1222,"context_line":"                   linkat.AT_FDCWD, target_path, linkat.AT_SYMLINK_FOLLOW)"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_d966dfb9","line":1219,"in_reply_to":"1ac06dbe_a8465c4c","updated":"2016-08-24 02:24:19.000000000","message":"The renamer() method above tries it twice to handle races. The directory may not exist (we get ENOENT) if someone else has cleaned it up in the time window between when PUT started and completed. Same applies here too.\n\n\nI\u0027ll pass a \u0027retries\u0027 arg with default set to 2.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"2fda9b2d2ec0d3c8b40fa57223ae2b27a8e02386","unresolved":false,"context_lines":[{"line_number":1219,"context_line":"    for _junk in range(0, 2):"},{"line_number":1220,"context_line":"        try:"},{"line_number":1221,"context_line":"            linkat(linkat.AT_FDCWD, \"/proc/self/fd/%d\" % (fd),"},{"line_number":1222,"context_line":"                   linkat.AT_FDCWD, target_path, linkat.AT_SYMLINK_FOLLOW)"},{"line_number":1223,"context_line":"            break"},{"line_number":1224,"context_line":"        except IOError as err:"},{"line_number":1225,"context_line":"            if err.errno \u003d\u003d errno.ENOENT:"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_9579f9ca","line":1222,"updated":"2016-08-23 14:17:57.000000000","message":"This matches the syscall interface, so that\u0027s ok.\n\nBut as an alternative, do we need to expose the constants outside of the new linkat module at all? What if that were all kept in the module and the linkat() interface was only the source and target?\n\nOverall, I\u0027m fine either way.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c07fc46d9a2dfb98e51711aa9340f837b85ec11a","unresolved":false,"context_lines":[{"line_number":1219,"context_line":"    for _junk in range(0, 2):"},{"line_number":1220,"context_line":"        try:"},{"line_number":1221,"context_line":"            linkat(linkat.AT_FDCWD, \"/proc/self/fd/%d\" % (fd),"},{"line_number":1222,"context_line":"                   linkat.AT_FDCWD, target_path, linkat.AT_SYMLINK_FOLLOW)"},{"line_number":1223,"context_line":"            break"},{"line_number":1224,"context_line":"        except IOError as err:"},{"line_number":1225,"context_line":"            if err.errno \u003d\u003d errno.ENOENT:"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_1931975a","line":1222,"in_reply_to":"1ac06dbe_9579f9ca","updated":"2016-08-24 02:24:19.000000000","message":"At this point in time, linkat is only used for one purpose which only needs the source and target. linkat module is generic enough to be used elsewhere too if need be in future.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"2fda9b2d2ec0d3c8b40fa57223ae2b27a8e02386","unresolved":false,"context_lines":[{"line_number":1226,"context_line":"                dirs_created \u003d makedirs_count(dirpath)"},{"line_number":1227,"context_line":"            elif err.errno \u003d\u003d errno.EEXIST:"},{"line_number":1228,"context_line":"                try:"},{"line_number":1229,"context_line":"                    os.unlink(target_path)"},{"line_number":1230,"context_line":"                except OSError as e:"},{"line_number":1231,"context_line":"                    if e.errno !\u003d errno.ENOENT:"},{"line_number":1232,"context_line":"                        raise"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_6840e434","line":1229,"updated":"2016-08-23 14:17:57.000000000","message":"I think is see why this is done, but yikes! It seems a little scary.\n\nWhat are the conditions you\u0027re thinking of where this could happen? Might be good to add that to a comment here.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c07fc46d9a2dfb98e51711aa9340f837b85ec11a","unresolved":false,"context_lines":[{"line_number":1226,"context_line":"                dirs_created \u003d makedirs_count(dirpath)"},{"line_number":1227,"context_line":"            elif err.errno \u003d\u003d errno.EEXIST:"},{"line_number":1228,"context_line":"                try:"},{"line_number":1229,"context_line":"                    os.unlink(target_path)"},{"line_number":1230,"context_line":"                except OSError as e:"},{"line_number":1231,"context_line":"                    if e.errno !\u003d errno.ENOENT:"},{"line_number":1232,"context_line":"                        raise"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_19cd1731","line":1229,"in_reply_to":"1ac06dbe_6840e434","updated":"2016-08-24 02:24:19.000000000","message":"It all boils down to this question - can two objects get same timestamp ? Highly unlikely but I don\u0027t know. Until this change, even if it was possible, no one could notice as rename() syscall can replace target without complaining.\n\n\nI\u0027m ok removing this error handling if not required.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"2fda9b2d2ec0d3c8b40fa57223ae2b27a8e02386","unresolved":false,"context_lines":[{"line_number":4086,"context_line":"    \"\"\""},{"line_number":4087,"context_line":"    return all([linkat.available,"},{"line_number":4088,"context_line":"                platform.system() \u003d\u003d \u0027Linux\u0027,"},{"line_number":4089,"context_line":"                LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.16\u0027)])"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_c88e3878","line":4089,"updated":"2016-08-23 14:17:57.000000000","message":"why 3.16 instead of 3.15? Do we know of anyone actually using btrfs?","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c07fc46d9a2dfb98e51711aa9340f837b85ec11a","unresolved":false,"context_lines":[{"line_number":4086,"context_line":"    \"\"\""},{"line_number":4087,"context_line":"    return all([linkat.available,"},{"line_number":4088,"context_line":"                platform.system() \u003d\u003d \u0027Linux\u0027,"},{"line_number":4089,"context_line":"                LooseVersion(platform.release()) \u003e\u003d LooseVersion(\u00273.16\u0027)])"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_0e314f5a","line":4089,"in_reply_to":"1ac06dbe_c88e3878","updated":"2016-08-24 02:24:19.000000000","message":"For completeness. I don\u0027t know if anybody uses it. Although the fedora community has had plans earlier to make it the default filesystem in future releases. And opensuse has already made it the default in their recent versions.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e741e0f92761b75583748fec47ac2df3f3e9ceb3","unresolved":false,"context_lines":[{"line_number":168,"context_line":"# The values were copied from the Linux 3.x kernel headers."},{"line_number":169,"context_line":"AF_ALG \u003d getattr(socket, \u0027AF_ALG\u0027, 38)"},{"line_number":170,"context_line":"F_SETPIPE_SZ \u003d getattr(fcntl, \u0027F_SETPIPE_SZ\u0027, 1031)"},{"line_number":171,"context_line":"O_TMPFILE \u003d getattr(os, \u0027O_TMPFILE\u0027, 0o20000000 | os.O_DIRECTORY)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"# Used by the parse_socket_string() function to validate IPv6 addresses"},{"line_number":174,"context_line":"IPV6_RE \u003d re.compile(\"^\\[(?P\u003caddress\u003e.*)\\](:(?P\u003cport\u003e[0-9]+))?$\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a89bdaa_59544720","line":171,"range":{"start_line":171,"start_character":38,"end_line":171,"end_character":39},"updated":"2016-09-12 08:25:03.000000000","message":"I think that \u0027o\u0027 is misplaced and shouldn\u0027t be there: The kernel headers have it as (tho this is in a much newer kernel\u0027s headers):\n\n  #define __O_TMPFILE 020000000\n  ...\n  #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)\n\nBut having it seems it doesn\u0027t make a difference, at least in Python:\n\n  In [6]: 0o20000000 | os.O_DIRECTORY\n  Out[6]: 4259840\n\n  In [7]: 0020000000 | os.O_DIRECTORY\n  Out[7]: 4259840\n\n  In [8]: 020000000 | os.O_DIRECTORY\n  Out[8]: 4259840\n\nIt\u0027s only for correctness.\n\nUnless I\u0027m missing something.","commit_id":"773edb4a5dd22b22f5fcab57820bcbdd4176dfcd"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"25325c47db9c665c0b88707c3cb3a9f06ab0cebc","unresolved":false,"context_lines":[{"line_number":168,"context_line":"# The values were copied from the Linux 3.x kernel headers."},{"line_number":169,"context_line":"AF_ALG \u003d getattr(socket, \u0027AF_ALG\u0027, 38)"},{"line_number":170,"context_line":"F_SETPIPE_SZ \u003d getattr(fcntl, \u0027F_SETPIPE_SZ\u0027, 1031)"},{"line_number":171,"context_line":"O_TMPFILE \u003d getattr(os, \u0027O_TMPFILE\u0027, 0o20000000 | os.O_DIRECTORY)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"# Used by the parse_socket_string() function to validate IPv6 addresses"},{"line_number":174,"context_line":"IPV6_RE \u003d re.compile(\"^\\[(?P\u003caddress\u003e.*)\\](:(?P\u003cport\u003e[0-9]+))?$\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a89bdaa_1fbffafb","line":171,"range":{"start_line":171,"start_character":38,"end_line":171,"end_character":39},"in_reply_to":"9a89bdaa_59544720","updated":"2016-09-12 08:45:23.000000000","message":"Python 3 dropped support[1] for old way of representing octal numbers.\n\n[1]:https://www.python.org/dev/peps/pep-3127/#removal-of-old-octal-syntax\n\n\n    [ppai@pp ~]$ python\n    Python 2.7.12 (default, Sep  2 2016, 14:46:00)\n    [GCC 6.1.1 20160621 (Red Hat 6.1.1-3)] on linux2\n    Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n    \u003e\u003e\u003e import os\n    \u003e\u003e\u003e 0o20000000 | os.O_DIRECTORY\n    4259840\n    \u003e\u003e\u003e 0020000000 | os.O_DIRECTORY\n    4259840\n    \u003e\u003e\u003e 020000000 | os.O_DIRECTORY\n    4259840\n    \u003e\u003e\u003e\n\n\n    [ppai@pp ~]$ python3\n    Python 3.5.1 (default, Aug  9 2016, 15:35:51)\n    [GCC 6.1.1 20160621 (Red Hat 6.1.1-3)] on linux\n    Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n    \u003e\u003e\u003e import os\n    \u003e\u003e\u003e 0o20000000 | os.O_DIRECTORY\n    4259840\n    \u003e\u003e\u003e 0020000000 | os.O_DIRECTORY\n      File \"\u003cstdin\u003e\", line 1\n        0020000000 | os.O_DIRECTORY\n                 ^\n    SyntaxError: invalid token\n    \u003e\u003e\u003e 020000000 | os.O_DIRECTORY\n      File \"\u003cstdin\u003e\", line 1\n        020000000 | os.O_DIRECTORY\n                ^\n    SyntaxError: invalid token\n    \u003e\u003e\u003e","commit_id":"773edb4a5dd22b22f5fcab57820bcbdd4176dfcd"}],"swift/obj/diskfile.py":[{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"ec3059f9488149720fe330b4e6d5f66cbe3b23f4","unresolved":false,"context_lines":[{"line_number":573,"context_line":"                    max_pipe_size \u003d int(f.read())"},{"line_number":574,"context_line":"                self.pipe_size \u003d min(max_pipe_size, self.disk_chunk_size)"},{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_39ddf742","line":576,"updated":"2015-03-09 11:42:50.000000000","message":"I\u0027d rework this and the check below a bit, rather than using a float. How about\n\n    rel \u003d tuple(int(i) for i in platform.release().split(\u0027.\u0027)[:2])\n    if rel \u003e\u003d (3, 15): ...","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"d58f27859d30852762a99329657c692ab505e458","unresolved":false,"context_lines":[{"line_number":573,"context_line":"                    max_pipe_size \u003d int(f.read())"},{"line_number":574,"context_line":"                self.pipe_size \u003d min(max_pipe_size, self.disk_chunk_size)"},{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_178632db","line":576,"updated":"2015-03-09 17:11:55.000000000","message":"this patch https://review.openstack.org/#/c/137659/7/swift/common/utils.py is using another method to check platform and kernel version, should we find a common way and provide a common method?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":573,"context_line":"                    max_pipe_size \u003d int(f.read())"},{"line_number":574,"context_line":"                self.pipe_size \u003d min(max_pipe_size, self.disk_chunk_size)"},{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_ba437411","line":576,"in_reply_to":"9a80dd14_178632db","updated":"2015-03-10 05:49:06.000000000","message":"I like that approach.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"d58f27859d30852762a99329657c692ab505e458","unresolved":false,"context_lines":[{"line_number":574,"context_line":"                self.pipe_size \u003d min(max_pipe_size, self.disk_chunk_size)"},{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"},{"line_number":580,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_974862b4","line":577,"updated":"2015-03-09 17:11:55.000000000","message":"I\u0027m not sure I see the value of providing an option. Why not just default to use linkat if available?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":574,"context_line":"                self.pipe_size \u003d min(max_pipe_size, self.disk_chunk_size)"},{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"},{"line_number":580,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_7a2c9c99","line":577,"in_reply_to":"9a80dd14_974862b4","updated":"2015-03-10 05:49:06.000000000","message":"linkat() has been available since Linux 2.6.18. The O_TMPFILE flag was added to open in 3.11 (includes ext4 support) and XFS support was added in 3.15. linkat() in our case is only used in tandem with open() having O_TMPFILE.\n\nWe could skip the config option if we know we\u0027re running at least 3.15 and underlying file system is ext4/xfs. If someone wants to use the default DiskFile with for example, btrfs..Without a config option, it would be unusable even though linux version \u003e\u003d 3.15 and linkat() is available. \n\nI\u0027m all up for making \"on/true\" the default value. (unless the jenkins CI machines run on really old kernels). I did see a test fail in py26 environment.\n\nhttps://8b86aea46fb38e6450f2-0e5f4c086da474abc1df58826577db2f.ssl.cf1.rackcdn.com/162243/32/py26unit/console.txt","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"3c9e7297f3e43a190b062cd4a28c06cfffce2938","unresolved":false,"context_lines":[{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"    def construct_dev_path(self, device):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_247f7967","line":578,"updated":"2015-03-09 22:05:58.000000000","message":"Instead of hard-coding a kernel version, how about not putting any constraints (or maybe only 3.11), and handling EOPNOTSUPP at the appropriate call sites, falling back to other mechanisms? This would handle different FSes etc. as well.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":575,"context_line":"        self.use_linkat \u003d False"},{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"    def construct_dev_path(self, device):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_3a5ce418","line":578,"in_reply_to":"9a80dd14_247f7967","updated":"2015-03-10 05:49:06.000000000","message":"I did consider that, Underlying file systems on older kernels (they don\u0027t know yet that the arg to open() can be a dir) may not throw proper errno. For example:\n\n        fd \u003d os.open(\u0027/tmp\u0027, O_TMPFILE | os.O_WRONLY)\n        OSError: [Errno 21] Is a directory: \u0027/tmp\u0027","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"    def construct_dev_path(self, device):"},{"line_number":582,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_14eb9078","line":579,"updated":"2015-03-09 16:56:48.000000000","message":"Maybe log something if `linkat` is requested/configured, but not available on the system.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":576,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":577,"context_line":"        if config_true_value(conf.get(\u0027use_linkat\u0027, \u0027false\u0027)) and\\"},{"line_number":578,"context_line":"                linkat.available and linux_version \u003e\u003d 3.15:"},{"line_number":579,"context_line":"            self.use_linkat \u003d True"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"    def construct_dev_path(self, device):"},{"line_number":582,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_5a9ef8b9","line":579,"in_reply_to":"9a80dd14_14eb9078","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":854,"context_line":"        return self._upload_size"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"    def _link_target_path(self, fd, target_path):"},{"line_number":857,"context_line":"        mkdirs(os.path.dirname(target_path))"},{"line_number":858,"context_line":"        try:"},{"line_number":859,"context_line":"            flink(fd, target_path)"},{"line_number":860,"context_line":"        except OSError as err:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_348c14da","line":857,"updated":"2015-03-09 16:56:48.000000000","message":"I\u0027d push the responsibility of only passing a pre-existing `target_path` to this method to the caller. Only the caller knows which permissions to set etc.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":854,"context_line":"        return self._upload_size"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"    def _link_target_path(self, fd, target_path):"},{"line_number":857,"context_line":"        mkdirs(os.path.dirname(target_path))"},{"line_number":858,"context_line":"        try:"},{"line_number":859,"context_line":"            flink(fd, target_path)"},{"line_number":860,"context_line":"        except OSError as err:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_da22e850","line":857,"in_reply_to":"9a80dd14_348c14da","updated":"2015-03-10 05:49:06.000000000","message":"To keep code simple, I\u0027ve made this similar to what renamer() today does - renamer() internally calls mkdirs(). Another reason is: in future, I\u0027d like to extend the \"fsync on dir\" patch (https://review.openstack.org/126923) to this case as well. Once that merges, we can do some tiny re-factoring here.\n\nIf linkat() supported overwriting destination path, this could have been drop in replacement to renamer().","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":857,"context_line":"        mkdirs(os.path.dirname(target_path))"},{"line_number":858,"context_line":"        try:"},{"line_number":859,"context_line":"            flink(fd, target_path)"},{"line_number":860,"context_line":"        except OSError as err:"},{"line_number":861,"context_line":"            if err.errno \u003d\u003d errno.EEXIST:"},{"line_number":862,"context_line":"                # Very rare, but theoretically not impossible!"},{"line_number":863,"context_line":"                # Fall back to using renamer() in such case"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_947b00bd","line":860,"updated":"2015-03-09 16:56:48.000000000","message":"`linkat`, which is called by `flink`, will raise an `IOError`, not `OSError`.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":857,"context_line":"        mkdirs(os.path.dirname(target_path))"},{"line_number":858,"context_line":"        try:"},{"line_number":859,"context_line":"            flink(fd, target_path)"},{"line_number":860,"context_line":"        except OSError as err:"},{"line_number":861,"context_line":"            if err.errno \u003d\u003d errno.EEXIST:"},{"line_number":862,"context_line":"                # Very rare, but theoretically not impossible!"},{"line_number":863,"context_line":"                # Fall back to using renamer() in such case"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_7a649cb8","line":860,"in_reply_to":"9a80dd14_947b00bd","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"30ef47ca88beb62d5c214b73696e0c89deb25d9b","unresolved":false,"context_lines":[{"line_number":1225,"context_line":"    def __init__(self, mgr, device_path, threadpool, partition,"},{"line_number":1226,"context_line":"                 account\u003dNone, container\u003dNone, obj\u003dNone, _datadir\u003dNone,"},{"line_number":1227,"context_line":"                 policy_idx\u003d0, use_splice\u003dFalse, pipe_size\u003dNone,"},{"line_number":1228,"context_line":"                 use_linkat\u003dNone):"},{"line_number":1229,"context_line":"        self._mgr \u003d mgr"},{"line_number":1230,"context_line":"        self._device_path \u003d device_path"},{"line_number":1231,"context_line":"        self._threadpool \u003d threadpool or ThreadPool(nthreads\u003d0)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a6ced46_ed5599fa","line":1228,"updated":"2015-03-25 13:32:21.000000000","message":"`use_linkat` is a `bool`, so consider using `False` as the default rather than `None`?","commit_id":"22ec17f750caadd0c853ba339d96d3685ad5a1fb"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"73616a4b56793d3b5867b31a9066765a13719cc2","unresolved":false,"context_lines":[{"line_number":1225,"context_line":"    def __init__(self, mgr, device_path, threadpool, partition,"},{"line_number":1226,"context_line":"                 account\u003dNone, container\u003dNone, obj\u003dNone, _datadir\u003dNone,"},{"line_number":1227,"context_line":"                 policy_idx\u003d0, use_splice\u003dFalse, pipe_size\u003dNone,"},{"line_number":1228,"context_line":"                 use_linkat\u003dNone):"},{"line_number":1229,"context_line":"        self._mgr \u003d mgr"},{"line_number":1230,"context_line":"        self._device_path \u003d device_path"},{"line_number":1231,"context_line":"        self._threadpool \u003d threadpool or ThreadPool(nthreads\u003d0)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a6ced46_11c67068","line":1228,"in_reply_to":"1a6ced46_ed5599fa","updated":"2015-03-26 05:08:15.000000000","message":"Done","commit_id":"22ec17f750caadd0c853ba339d96d3685ad5a1fb"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5c86ca544890c46cd57e82709d33b8fa9f83a0d4","unresolved":false,"context_lines":[{"line_number":1738,"context_line":"                # in XFS a fair chance to do it\u0027s work."},{"line_number":1739,"context_line":"                # http://www.spinics.net/lists/xfs/msg32986.html"},{"line_number":1740,"context_line":"                # But datadir may not exist at this point. Is it wise to"},{"line_number":1741,"context_line":"                # prematurely create it here ?"},{"line_number":1742,"context_line":"            else:"},{"line_number":1743,"context_line":"                if not exists(self._tmpdir):"},{"line_number":1744,"context_line":"                    mkdirs(self._tmpdir)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3afb71cf_58ea3875","line":1741,"updated":"2015-06-10 18:38:05.000000000","message":"Yes, the directory matters in this case too, so it should use the final path for the object. Isn\u0027t self._datadir set in __init__? am I missing something?","commit_id":"841ca5918d615db50282a5a7a77421bfb29c0198"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"8b21b09dd3ede383b4a9e2c509c8185d38aa81bf","unresolved":false,"context_lines":[{"line_number":1738,"context_line":"                # in XFS a fair chance to do it\u0027s work."},{"line_number":1739,"context_line":"                # http://www.spinics.net/lists/xfs/msg32986.html"},{"line_number":1740,"context_line":"                # But datadir may not exist at this point. Is it wise to"},{"line_number":1741,"context_line":"                # prematurely create it here ?"},{"line_number":1742,"context_line":"            else:"},{"line_number":1743,"context_line":"                if not exists(self._tmpdir):"},{"line_number":1744,"context_line":"                    mkdirs(self._tmpdir)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3afb71cf_16591d8e","line":1741,"in_reply_to":"3afb71cf_58ea3875","updated":"2015-07-06 08:58:56.000000000","message":"The directory path you pass to open should already exist. Which translates to:\n\n    os.makedirs(self._datadir)\n    fd \u003d os.open(self._datadir, O_TMPFILE | os.O_WRONLY)\n\nI have a few concerns with this:\n\n1. In case the PUT fails, the object needs no removing/cleaning if things go wrong before linkat. But who will delete self._datadir ?\n\n2. This may bring in races. If makedirs will succeed above and let\u0027s say some one else deletes it before we do a linkat ?\n\n3. The \"extra durability\" thingy that we did with \"fsync on dir\" patch will not fsync the parent directories already created here.","commit_id":"841ca5918d615db50282a5a7a77421bfb29c0198"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"c7e98358fd06835b2476a348741702d45a42e5b4","unresolved":false,"context_lines":[{"line_number":1846,"context_line":"            try:"},{"line_number":1847,"context_line":"                fd \u003d os.open(self._datadir, O_TMPFILE | os.O_WRONLY)"},{"line_number":1848,"context_line":"            except OSError as err:"},{"line_number":1849,"context_line":"                if err.errno in (errno.EOPNOTSUPP, errno.EISDIR, errno.EINVAL):"},{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a2fa921_9e25c8af","line":1849,"updated":"2015-10-13 08:28:59.000000000","message":"You may catch any OSError and always fallback to mkstemp(), no?","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"150685c18fc911db302b2f99b6b83cb7eec9dbfc","unresolved":false,"context_lines":[{"line_number":1846,"context_line":"            try:"},{"line_number":1847,"context_line":"                fd \u003d os.open(self._datadir, O_TMPFILE | os.O_WRONLY)"},{"line_number":1848,"context_line":"            except OSError as err:"},{"line_number":1849,"context_line":"                if err.errno in (errno.EOPNOTSUPP, errno.EISDIR, errno.EINVAL):"},{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a2ca52d_bef79df4","line":1849,"in_reply_to":"5a2ca52d_18ad8988","updated":"2015-10-13 12:37:10.000000000","message":"I don\u0027t see any advantage in catching all errors (like ENOSPC), only to further call mkstemp() which again fails with same error (ENOSPC in this case) :(","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"5a0d535a641eb4cc79d5e7076f545624455a9deb","unresolved":false,"context_lines":[{"line_number":1846,"context_line":"            try:"},{"line_number":1847,"context_line":"                fd \u003d os.open(self._datadir, O_TMPFILE | os.O_WRONLY)"},{"line_number":1848,"context_line":"            except OSError as err:"},{"line_number":1849,"context_line":"                if err.errno in (errno.EOPNOTSUPP, errno.EISDIR, errno.EINVAL):"},{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a2ca52d_18ad8988","line":1849,"in_reply_to":"7a2fa921_39928e58","updated":"2015-10-13 09:58:21.000000000","message":"But ENOSPC will also be raised by mkstemp() no?\n\nIn fact I suggest to replace the \"raise\" below with \"fallback_to_mkstemp \u003d True\", to try mkstemp() if open(O_TMPFILE) failed for an unknown reason.","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"40906f81bc527be426011d4562f02b77ca81074a","unresolved":false,"context_lines":[{"line_number":1846,"context_line":"            try:"},{"line_number":1847,"context_line":"                fd \u003d os.open(self._datadir, O_TMPFILE | os.O_WRONLY)"},{"line_number":1848,"context_line":"            except OSError as err:"},{"line_number":1849,"context_line":"                if err.errno in (errno.EOPNOTSUPP, errno.EISDIR, errno.EINVAL):"},{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a2fa921_39928e58","line":1849,"in_reply_to":"7a2fa921_9e25c8af","updated":"2015-10-13 09:42:12.000000000","message":"We still do not want to catch errors such as ENOSPC here. It is caught by the caller and DiskFileNoSpace is raised which results in the client gracefully getting HTTP 507 (Insufficient Storage). We only catch errors that indicate O_TMPFILE is not supported or available. Other errors like EPERM/EACCES/EMFILE/ENOENT which indicate something wrong with the device or node should fail and result in a traceback.","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"c7e98358fd06835b2476a348741702d45a42e5b4","unresolved":false,"context_lines":[{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"},{"line_number":1853,"context_line":"                    self._logger.warn(msg)"},{"line_number":1854,"context_line":"                    fallback_to_mkstemp \u003d True"},{"line_number":1855,"context_line":"                else:"},{"line_number":1856,"context_line":"                    raise"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a2fa921_de4a6055","line":1853,"updated":"2015-10-13 08:28:59.000000000","message":"Hum, you may log a lot of messages if O_TMPFILE never works on a device, no? (I mean flood the logs). I\u0027m not sure that the message is very helpful. You may want to use linkat() on some devices but fallback to mkstemp() on others, no?","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"150685c18fc911db302b2f99b6b83cb7eec9dbfc","unresolved":false,"context_lines":[{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"},{"line_number":1853,"context_line":"                    self._logger.warn(msg)"},{"line_number":1854,"context_line":"                    fallback_to_mkstemp \u003d True"},{"line_number":1855,"context_line":"                else:"},{"line_number":1856,"context_line":"                    raise"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a2ca52d_9e0e61e4","line":1853,"in_reply_to":"5a2ca52d_989e7906","updated":"2015-10-13 12:37:10.000000000","message":"Good point, it definitely makes sense. However, from implementation point of view, it\u0027s an overkill to maintain that state per device across requests.","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"5a0d535a641eb4cc79d5e7076f545624455a9deb","unresolved":false,"context_lines":[{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"},{"line_number":1853,"context_line":"                    self._logger.warn(msg)"},{"line_number":1854,"context_line":"                    fallback_to_mkstemp \u003d True"},{"line_number":1855,"context_line":"                else:"},{"line_number":1856,"context_line":"                    raise"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a2ca52d_989e7906","line":1853,"in_reply_to":"7a2fa921_1995523f","updated":"2015-10-13 09:58:21.000000000","message":"Would it make sense to only emit the warning once for each data store? (For each instance for BaseDiskFile if I understood correctly.)","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"40906f81bc527be426011d4562f02b77ca81074a","unresolved":false,"context_lines":[{"line_number":1850,"context_line":"                    msg \u003d \u0027open(%s, O_TMPFILE | O_WRONLY) failed: %s \\"},{"line_number":1851,"context_line":"                           Falling back to using mkstemp()\u0027 \\"},{"line_number":1852,"context_line":"                           % (self._datadir, os.strerror(err.errno))"},{"line_number":1853,"context_line":"                    self._logger.warn(msg)"},{"line_number":1854,"context_line":"                    fallback_to_mkstemp \u003d True"},{"line_number":1855,"context_line":"                else:"},{"line_number":1856,"context_line":"                    raise"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a2fa921_1995523f","line":1853,"in_reply_to":"7a2fa921_de4a6055","updated":"2015-10-13 09:42:12.000000000","message":"True about the flooding of logs. For most deployments (xfs,ext4 etc), you won\u0027t ever hit into this at all. The log msg in some cases indicates mis-configurations such as the wrong FS mounted. For deployments where one deliberately has FS such as glusterfs in the backend, it\u0027s probably a good idea to make this a tunable in object server conf i.e ability to turn off using O_TMPFILE. After the initial feedback against providing the tunable, I\u0027m not so keen on doing it unless there\u0027s a demand for it.\n\nThe error message is still of some help. It indicates why it failed (EOPNOTSUPP indicates fs doesn\u0027t support, EISDIR indicates kernel doesn\u0027t support) and also where it failed (filesystem path).","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"c7e98358fd06835b2476a348741702d45a42e5b4","unresolved":false,"context_lines":[{"line_number":1908,"context_line":"                # dfw.put_succeeded is set to True after renamer() succeeds in"},{"line_number":1909,"context_line":"                # DiskFileWriter._finalize_put()"},{"line_number":1910,"context_line":"                try:"},{"line_number":1911,"context_line":"                    if tmppath:"},{"line_number":1912,"context_line":"                        # when mkstemp() was used"},{"line_number":1913,"context_line":"                        os.unlink(tmppath)"},{"line_number":1914,"context_line":"                except OSError:"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a2fa921_5e6df0ca","line":1911,"updated":"2015-10-13 08:28:59.000000000","message":"you may put the if outside the try/except.","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"40906f81bc527be426011d4562f02b77ca81074a","unresolved":false,"context_lines":[{"line_number":1908,"context_line":"                # dfw.put_succeeded is set to True after renamer() succeeds in"},{"line_number":1909,"context_line":"                # DiskFileWriter._finalize_put()"},{"line_number":1910,"context_line":"                try:"},{"line_number":1911,"context_line":"                    if tmppath:"},{"line_number":1912,"context_line":"                        # when mkstemp() was used"},{"line_number":1913,"context_line":"                        os.unlink(tmppath)"},{"line_number":1914,"context_line":"                except OSError:"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a2fa921_b98c5e36","line":1911,"in_reply_to":"7a2fa921_5e6df0ca","updated":"2015-10-13 09:42:12.000000000","message":"Sure.","commit_id":"4327eacea80339034b895e9e95bf7ad8e5c79683"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"2fda9b2d2ec0d3c8b40fa57223ae2b27a8e02386","unresolved":false,"context_lines":[{"line_number":574,"context_line":"                with open(\u0027/proc/sys/fs/pipe-max-size\u0027) as f:"},{"line_number":575,"context_line":"                    max_pipe_size \u003d int(f.read())"},{"line_number":576,"context_line":"                self.pipe_size \u003d min(max_pipe_size, self.disk_chunk_size)"},{"line_number":577,"context_line":"        self.use_linkat \u003d o_tmpfile_supported()"},{"line_number":578,"context_line":""},{"line_number":579,"context_line":"    def make_on_disk_filename(self, timestamp, ext\u003dNone,"},{"line_number":580,"context_line":"                              ctype_timestamp\u003dNone, *a, **kw):"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_48a9a88f","line":577,"updated":"2016-08-23 14:17:57.000000000","message":"YES! I LOVE this. No config options; just use the best thing available. Upgrade and things get better.","commit_id":"2013304a225157f09010309d334bd609ad68b0c6"}],"test/unit/common/test_linkat.py":[{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":29,"context_line":"class TestLinkat(unittest.TestCase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":33,"context_line":"        if linux_version \u003c 3.15 or linkat.available:"},{"line_number":34,"context_line":"            raise nose.SkipTest(\u0027linkat not available\u0027)"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_9429409d","line":32,"updated":"2015-03-09 16:56:48.000000000","message":"Same `float` remark.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":29,"context_line":"class TestLinkat(unittest.TestCase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":33,"context_line":"        if linux_version \u003c 3.15 or linkat.available:"},{"line_number":34,"context_line":"            raise nose.SkipTest(\u0027linkat not available\u0027)"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_dae908e7","line":32,"in_reply_to":"9a80dd14_9429409d","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":33,"context_line":"        if linux_version \u003c 3.15 or linkat.available:"},{"line_number":34,"context_line":"            raise nose.SkipTest(\u0027linkat not available\u0027)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def test_flags(self):"},{"line_number":37,"context_line":"        self.assert_(hasattr(linkat, \u0027AT_FDCWD\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_57118a50","line":34,"updated":"2015-03-09 16:56:48.000000000","message":"If all tests fail on this condition, I\u0027d use a single `skip` decorator on the test class.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":33,"context_line":"        if linux_version \u003c 3.15 or linkat.available:"},{"line_number":34,"context_line":"            raise nose.SkipTest(\u0027linkat not available\u0027)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def test_flags(self):"},{"line_number":37,"context_line":"        self.assert_(hasattr(linkat, \u0027AT_FDCWD\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_1af000c8","line":34,"in_reply_to":"9a80dd14_57118a50","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def test_linkat_success(self):"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        O_TMPFILE \u003d (0o20000000 | os.O_DIRECTORY)"},{"line_number":89,"context_line":"        fd \u003d None"},{"line_number":90,"context_line":"        path \u003d None"},{"line_number":91,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_d753ba14","line":88,"updated":"2015-03-09 16:56:48.000000000","message":"Any way not to have this magic constant coded twice?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def test_linkat_success(self):"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        O_TMPFILE \u003d (0o20000000 | os.O_DIRECTORY)"},{"line_number":89,"context_line":"        fd \u003d None"},{"line_number":90,"context_line":"        path \u003d None"},{"line_number":91,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_5abd18d7","line":88,"in_reply_to":"9a80dd14_d753ba14","updated":"2015-03-10 05:49:06.000000000","message":"May be push this definition to diskfile.py and import from that wherever needed.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        try:"},{"line_number":92,"context_line":"            fd \u003d os.open(\u0027/tmp\u0027, O_TMPFILE | os.O_WRONLY)"},{"line_number":93,"context_line":"            path \u003d os.path.join(\u0027/tmp\u0027, uuid4().hex)"},{"line_number":94,"context_line":"            ret \u003d linkat(linkat.AT_FDCWD, \"/proc/self/fd/%s\" % (fd),"},{"line_number":95,"context_line":"                         linkat.AT_FDCWD, path, linkat.AT_SYMLINK_FOLLOW)"},{"line_number":96,"context_line":"            self.assertEqual(ret, 0)"},{"line_number":97,"context_line":"            self.assertTrue(os.path.exists(path))"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_d77ada86","line":94,"updated":"2015-03-09 16:56:48.000000000","message":"`fd` is supposed to be an `int`, so use `%d` in the formatter.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        try:"},{"line_number":92,"context_line":"            fd \u003d os.open(\u0027/tmp\u0027, O_TMPFILE | os.O_WRONLY)"},{"line_number":93,"context_line":"            path \u003d os.path.join(\u0027/tmp\u0027, uuid4().hex)"},{"line_number":94,"context_line":"            ret \u003d linkat(linkat.AT_FDCWD, \"/proc/self/fd/%s\" % (fd),"},{"line_number":95,"context_line":"                         linkat.AT_FDCWD, path, linkat.AT_SYMLINK_FOLLOW)"},{"line_number":96,"context_line":"            self.assertEqual(ret, 0)"},{"line_number":97,"context_line":"            self.assertTrue(os.path.exists(path))"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_dad02821","line":94,"in_reply_to":"9a80dd14_d77ada86","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":45,"context_line":"                       linkat.AT_FDCWD, \"/tmp/testlinkat\","},{"line_number":46,"context_line":"                       linkat.AT_SYMLINK_FOLLOW)"},{"line_number":47,"context_line":"            except IOError:"},{"line_number":48,"context_line":"                pass"},{"line_number":49,"context_line":"            else:"},{"line_number":50,"context_line":"                self.fail(\u0027Expected IOError was not raised\u0027)"},{"line_number":51,"context_line":"        self.assertEqual(ctypes.get_errno(), 0)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_a63abfca","line":48,"updated":"2015-03-13 14:53:09.000000000","message":"Can this be reworked into `assertRaises`?","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":45,"context_line":"                       linkat.AT_FDCWD, \"/tmp/testlinkat\","},{"line_number":46,"context_line":"                       linkat.AT_SYMLINK_FOLLOW)"},{"line_number":47,"context_line":"            except IOError:"},{"line_number":48,"context_line":"                pass"},{"line_number":49,"context_line":"            else:"},{"line_number":50,"context_line":"                self.fail(\u0027Expected IOError was not raised\u0027)"},{"line_number":51,"context_line":"        self.assertEqual(ctypes.get_errno(), 0)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_5eeb55a3","line":48,"in_reply_to":"9a80dd14_a63abfca","updated":"2015-03-16 05:51:27.000000000","message":"Done","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        mock_cdll \u003d mock.Mock(return_value\u003dlibc)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        with mock.patch(\u0027ctypes.CDLL\u0027, new\u003dmock_cdll):"},{"line_number":73,"context_line":"            # Force re-construction of a `Splice` instance"},{"line_number":74,"context_line":"            # Something you\u0027re not supposed to do in actual code"},{"line_number":75,"context_line":"            new_linkat \u003d type(linkat)()"},{"line_number":76,"context_line":"            self.assertFalse(new_linkat.available)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_e647574a","line":73,"updated":"2015-03-13 14:53:09.000000000","message":"Hehe, `Linkat`, not `Splice` ;-)","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        mock_cdll \u003d mock.Mock(return_value\u003dlibc)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        with mock.patch(\u0027ctypes.CDLL\u0027, new\u003dmock_cdll):"},{"line_number":73,"context_line":"            # Force re-construction of a `Splice` instance"},{"line_number":74,"context_line":"            # Something you\u0027re not supposed to do in actual code"},{"line_number":75,"context_line":"            new_linkat \u003d type(linkat)()"},{"line_number":76,"context_line":"            self.assertFalse(new_linkat.available)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_3ef06190","line":73,"in_reply_to":"9a80dd14_e647574a","updated":"2015-03-16 05:51:27.000000000","message":"Done","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            if fd:"},{"line_number":97,"context_line":"                os.close(fd)"},{"line_number":98,"context_line":"            if path:"},{"line_number":99,"context_line":"                os.unlink(path)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    @mock.patch(\u0027swift.common.linkat.linkat._c_linkat\u0027)"},{"line_number":102,"context_line":"    def test_linkat_fd_not_integer(self, _mock_linkat):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_6679a781","line":99,"updated":"2015-03-13 14:53:09.000000000","message":"I believe this can fail if `path` is calculated currectly but `linkat` failed, which will cause the original exception to be lost.","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"f5ab18161d0b54278e93d798ae301268907545b7","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            if fd:"},{"line_number":97,"context_line":"                os.close(fd)"},{"line_number":98,"context_line":"            if path:"},{"line_number":99,"context_line":"                os.unlink(path)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    @mock.patch(\u0027swift.common.linkat.linkat._c_linkat\u0027)"},{"line_number":102,"context_line":"    def test_linkat_fd_not_integer(self, _mock_linkat):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_5e4275ab","line":99,"in_reply_to":"9a80dd14_6679a781","updated":"2015-03-16 05:51:27.000000000","message":"Done","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":2809,"context_line":"            self.assertEqual(0, len(logger.get_lines_for_level(\u0027error\u0027)))"},{"line_number":2810,"context_line":""},{"line_number":2811,"context_line":"    def test_tempinode(self):"},{"line_number":2812,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":2813,"context_line":"        if linux_version \u003c 3.15:"},{"line_number":2814,"context_line":"            raise SkipTest(\u0027O_TMPFILE not available\u0027)"},{"line_number":2815,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_778f6e75","line":2812,"updated":"2015-03-09 16:56:48.000000000","message":"I\u0027d create a decorator abstracting this (also useful in other test modules, see comment before). Also applies to `test_flink`.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":2809,"context_line":"            self.assertEqual(0, len(logger.get_lines_for_level(\u0027error\u0027)))"},{"line_number":2810,"context_line":""},{"line_number":2811,"context_line":"    def test_tempinode(self):"},{"line_number":2812,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":2813,"context_line":"        if linux_version \u003c 3.15:"},{"line_number":2814,"context_line":"            raise SkipTest(\u0027O_TMPFILE not available\u0027)"},{"line_number":2815,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_5aa438b9","line":2812,"in_reply_to":"9a80dd14_778f6e75","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":2815,"context_line":""},{"line_number":2816,"context_line":"        fd \u003d None"},{"line_number":2817,"context_line":"        try:"},{"line_number":2818,"context_line":"            fd \u003d utils.tempinode(\u0027/tmp\u0027)"},{"line_number":2819,"context_line":"            self.assertTrue(isinstance(fd, int))"},{"line_number":2820,"context_line":"            self.assertEqual(os.write(fd, \u0027123\u0027), 3)"},{"line_number":2821,"context_line":"            # fd is O_WRONLY"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_57c26a85","line":2818,"updated":"2015-03-09 16:56:48.000000000","message":"`fd` is never `None` if this succeeds, or it\u0027s always `None` if it fails, so why not\n\n    fd \u003d utils.tempinode(\u0027/tmp\u0027)\n    try:\n        ...\n    finally:\n        os.close(fd)","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":2815,"context_line":""},{"line_number":2816,"context_line":"        fd \u003d None"},{"line_number":2817,"context_line":"        try:"},{"line_number":2818,"context_line":"            fd \u003d utils.tempinode(\u0027/tmp\u0027)"},{"line_number":2819,"context_line":"            self.assertTrue(isinstance(fd, int))"},{"line_number":2820,"context_line":"            self.assertEqual(os.write(fd, \u0027123\u0027), 3)"},{"line_number":2821,"context_line":"            # fd is O_WRONLY"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_1a9e4063","line":2818,"in_reply_to":"9a80dd14_57c26a85","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":2818,"context_line":"            fd \u003d utils.tempinode(\u0027/tmp\u0027)"},{"line_number":2819,"context_line":"            self.assertTrue(isinstance(fd, int))"},{"line_number":2820,"context_line":"            self.assertEqual(os.write(fd, \u0027123\u0027), 3)"},{"line_number":2821,"context_line":"            # fd is O_WRONLY"},{"line_number":2822,"context_line":"            self.assertRaises(OSError, os.read, fd, 3)"},{"line_number":2823,"context_line":"        finally:"},{"line_number":2824,"context_line":"            if fd:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_57db4a7b","line":2821,"updated":"2015-03-09 16:56:48.000000000","message":"Actually, maybe this shouldn\u0027t be the case. Consider allowing passing in an open mode to `tempinode`?","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":2818,"context_line":"            fd \u003d utils.tempinode(\u0027/tmp\u0027)"},{"line_number":2819,"context_line":"            self.assertTrue(isinstance(fd, int))"},{"line_number":2820,"context_line":"            self.assertEqual(os.write(fd, \u0027123\u0027), 3)"},{"line_number":2821,"context_line":"            # fd is O_WRONLY"},{"line_number":2822,"context_line":"            self.assertRaises(OSError, os.read, fd, 3)"},{"line_number":2823,"context_line":"        finally:"},{"line_number":2824,"context_line":"            if fd:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_fac7ac42","line":2821,"in_reply_to":"9a80dd14_57db4a7b","updated":"2015-03-10 05:49:06.000000000","message":"From the man page,\n\nO_TMPFILE must be specified with one of O_RDWR or O_WRONLY and, optionally, O_EXCL.  If O_EXCL is not specified, then linkat(2) can be used to link the temporary file into the filesystem.\n\nI couldn\u0027t think of a use case in Swift where one would need a O_RDWR in the PUT path. But anyways, I\u0027ll add allowing O_RDWR.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":2831,"context_line":""},{"line_number":2832,"context_line":"        fd \u003d None"},{"line_number":2833,"context_line":"        try:"},{"line_number":2834,"context_line":"            fd \u003d utils.tempinode(\u0027/tmp\u0027)"},{"line_number":2835,"context_line":"            self.assertTrue(isinstance(fd, int))"},{"line_number":2836,"context_line":"            self.assertEqual(os.write(fd, \u0027123\u0027), 3)"},{"line_number":2837,"context_line":"            path \u003d os.path.join(\u0027/tmp\u0027, uuid4().hex)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_77bdae01","line":2834,"updated":"2015-03-09 16:56:48.000000000","message":"Same remark as above.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":2831,"context_line":""},{"line_number":2832,"context_line":"        fd \u003d None"},{"line_number":2833,"context_line":"        try:"},{"line_number":2834,"context_line":"            fd \u003d utils.tempinode(\u0027/tmp\u0027)"},{"line_number":2835,"context_line":"            self.assertTrue(isinstance(fd, int))"},{"line_number":2836,"context_line":"            self.assertEqual(os.write(fd, \u0027123\u0027), 3)"},{"line_number":2837,"context_line":"            path \u003d os.path.join(\u0027/tmp\u0027, uuid4().hex)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_bae9b4b8","line":2834,"in_reply_to":"9a80dd14_77bdae01","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":2845,"context_line":"        with open(path) as f:"},{"line_number":2846,"context_line":"            content \u003d f.readlines()"},{"line_number":2847,"context_line":"        self.assertEqual(content[0], \u0027123\u0027)"},{"line_number":2848,"context_line":"        os.unlink(path)"},{"line_number":2849,"context_line":""},{"line_number":2850,"context_line":""},{"line_number":2851,"context_line":"class ResellerConfReader(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_d7649aba","line":2848,"updated":"2015-03-09 16:56:48.000000000","message":"This cleanup won\u0027t be done if the assertion above (or whatever else fails after the call too `flink`) fails.","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":2845,"context_line":"        with open(path) as f:"},{"line_number":2846,"context_line":"            content \u003d f.readlines()"},{"line_number":2847,"context_line":"        self.assertEqual(content[0], \u0027123\u0027)"},{"line_number":2848,"context_line":"        os.unlink(path)"},{"line_number":2849,"context_line":""},{"line_number":2850,"context_line":""},{"line_number":2851,"context_line":"class ResellerConfReader(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_dad3c801","line":2848,"in_reply_to":"9a80dd14_d7649aba","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"51b6f05a596d5119d12348ffbb6e3f7df377827c","unresolved":false,"context_lines":[{"line_number":2917,"context_line":"        self.assertRaises(TypeError, utils.link_fd_to_path, \"not_int\", \u0027/path\u0027)"},{"line_number":2918,"context_line":""},{"line_number":2919,"context_line":"    def test_link_fd_to_path_errno_not_EEXIST(self):"},{"line_number":2920,"context_line":"        _m_linkat \u003d mock.Mock(side_effect\u003dIOError(errno.EACCES,"},{"line_number":2921,"context_line":"                              os.strerror(errno.EACCES)))"},{"line_number":2922,"context_line":"        _m_makedirs_count \u003d mock.Mock(return_value\u003d0)"},{"line_number":2923,"context_line":"        with mock.patch(\u0027swift.common.utils.linkat\u0027, _m_linkat):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a80dd14_86adbb9d","line":2920,"updated":"2015-03-13 14:53:09.000000000","message":"Nit, and personal preference: I\u0027d format this as\n\n    mock_linkat \u003d mock.Mock(\n        side_effect\u003dIOError(errno.EACCESS, os.strerror(errno.EACCESS))","commit_id":"d574c4c0039606af66c5804267c3428f2bea15e4"}],"test/unit/obj/test_diskfile.py":[{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"6582a57dfe3770df9d0716a584b45e2afee382c9","unresolved":false,"context_lines":[{"line_number":2477,"context_line":"    def test_create_use_linkat_renamer_not_called(self):"},{"line_number":2478,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":2479,"context_line":"        if linux_version \u003c 3.15:"},{"line_number":2480,"context_line":"            raise SkipTest(\u0027O_TMPFILE not available\u0027)"},{"line_number":2481,"context_line":""},{"line_number":2482,"context_line":"        df \u003d self._simple_get_diskfile()"},{"line_number":2483,"context_line":"        df._use_linkat \u003d True"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_776bee84","line":2480,"updated":"2015-03-09 16:56:48.000000000","message":"Really, a single decorator would be nice :-)","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"c77d83063a055d8578d420b5090b1f97e497b170","unresolved":false,"context_lines":[{"line_number":2477,"context_line":"    def test_create_use_linkat_renamer_not_called(self):"},{"line_number":2478,"context_line":"        linux_version \u003d float(\".\".join(platform.release().split(\u0027.\u0027)[0:2]))"},{"line_number":2479,"context_line":"        if linux_version \u003c 3.15:"},{"line_number":2480,"context_line":"            raise SkipTest(\u0027O_TMPFILE not available\u0027)"},{"line_number":2481,"context_line":""},{"line_number":2482,"context_line":"        df \u003d self._simple_get_diskfile()"},{"line_number":2483,"context_line":"        df._use_linkat \u003d True"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_5a07d881","line":2480,"in_reply_to":"9a80dd14_776bee84","updated":"2015-03-10 05:49:06.000000000","message":"Done","commit_id":"0fa015776fbb181e720aa32e81b1473a9dc71ea3"}]}
