Steffen Daode Nurpmeso <sdao...@googlemail.com> added the comment:

Ronald Oussoren wrote:
> Adding the F_FULLSYNC option to os.fsync would be fine though

To show you that i'm not unteachable i'll attach a patch which
does that.
This approach can be heavily extended, then, e.g. by using
sync_file_range(all_the_flags) on Linux if the "full_fsync"
argument is true?!  (And then there is sync_file_range2() on
PowerPC and nice ARM...)

(The first time that i use PyArg_xy plus plus - please review.
test_os is ok and using "os.fsync(xy, True)" makes test_zlib
succeed on unpatched hg checkout.
os.rst change is really ugly.)

----------
Added file: http://bugs.python.org/file21742/11877.optarg-1.diff

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue11877>
_______________________________________
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -798,7 +798,7 @@
    Availability: Unix.
 
 
-.. function:: fsync(fd)
+.. function:: fsync(fd, full_fsync=False)
 
    Force write of file with filedescriptor *fd* to disk.  On Unix, this calls 
the
    native :c:func:`fsync` function; on Windows, the MS :c:func:`_commit` 
function.
@@ -807,6 +807,13 @@
    ``f.flush()``, and then do ``os.fsync(f.fileno())``, to ensure that all 
internal
    buffers associated with *f* are written to disk.
 
+   Note that :c:func:`fsync` only ensures that the OS flushs all data to
+   the disk device, *not* that the data is actually written by the
+   device itself.  For this to happen, use the *full_fsync* argument.
+   If this is true Python tries to accomplish even the device write,
+   e.g. on Mac OS X by calling  :c:func:`fcntl` with the
+   :data:`F_FULLFSYNC` command.
+
    Availability: Unix, and Windows.
 
 
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -2119,12 +2119,38 @@
 
 #ifdef HAVE_FSYNC
 PyDoc_STRVAR(posix_fsync__doc__,
-"fsync(fildes)\n\n\
-force write of file with filedescriptor to disk.");
-
-static PyObject *
-posix_fsync(PyObject *self, PyObject *fdobj)
-{
+"fsync(fildes, full_fsync=False)\n\n"
+"force write of file with filedescriptor to disk.\n"
+"if full_fsync is True it also ensures write to physical backing store.");
+
+static PyObject *
+posix_fsync(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    auto PyObject *fdobj;
+    auto int full_fsync = 1;
+    static char *keywords[] = {"fd", "full_fsync", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i", keywords,
+                                     &fdobj, &full_fsync))
+        return NULL;
+
+# ifdef __APPLE__
+    /* See issue 11877 discussion and issue 11277 for OS X sparse file bug */
+    if (full_fsync != 0) {
+        int res, fd = PyObject_AsFileDescriptor(fdobj);
+        if (fd < 0)
+            return NULL;
+        if (!_PyVerify_fd(fd))
+            return posix_error();
+        Py_BEGIN_ALLOW_THREADS
+        res = fcntl(fd, F_FULLFSYNC);
+        Py_END_ALLOW_THREADS
+        if (res < 0)
+            return posix_error();
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+# endif
     return posix_fildes(fdobj, fsync);
 }
 #endif /* HAVE_FSYNC */
@@ -9484,7 +9510,8 @@
     {"fchdir",          posix_fchdir, METH_O, posix_fchdir__doc__},
 #endif
 #ifdef HAVE_FSYNC
-    {"fsync",       posix_fsync, METH_O, posix_fsync__doc__},
+    {"fsync",           (PyCFunction)posix_fsync, METH_VARARGS|METH_KEYWORDS,
+                        posix_fsync__doc__},
 #endif
 #ifdef HAVE_SYNC
     {"sync",        posix_sync, METH_NOARGS, posix_sync__doc__},
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to