all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@cs.ucla.edu>
To: Eli Zaretskii <eliz@gnu.org>
Cc: sbaugh@catern.com, kieran@kcolford.com, dmantipov@yandex.ru,
	23904-done@debbugs.gnu.org
Subject: bug#23904: Btrfs clone support in copy operations
Date: Sat, 10 Sep 2016 19:16:39 -0700	[thread overview]
Message-ID: <b4d1ddcd-1ba9-ef27-59a6-5abf317bb7c5@cs.ucla.edu> (raw)
In-Reply-To: <577D40AA.9060004@cs.ucla.edu>

[-- Attachment #1: Type: text/plain, Size: 696 bytes --]

I looked into this a bit more, and it appears that there's little point to 
giving the user an option to clone or not clone when copying files, as the 
cloning (or not cloning) can occur anyway.

We plan to release a coreutils version soon and to change the default to clone 
after the release. For Emacs master the next release is far away, so there is 
plenty of time to try out the FICLONE performance improvement. I installed the 
attached two patches and am marking this bug report as done.

The second patch merely updates the documentation to discuss the issue; it is 
logically independent of the first patch, since the issue can occur both with 
and without the first patch.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-copy-file-now-uses-GNU-Linux-file-cloning.patch --]
[-- Type: text/x-diff; name="0001-copy-file-now-uses-GNU-Linux-file-cloning.patch", Size: 2728 bytes --]

From f9527cb5a5cdd05b2c98be089023b64ee9ee318b Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sat, 10 Sep 2016 12:51:27 -0700
Subject: [PATCH 1/2] copy-file now uses GNU/Linux file cloning

From a suggestion by Kieran Colford (see Bug#23904).
* configure.ac: Check for linux/fs.h.
* src/fileio.c [HAVE_LINUX_FS_H]: Include sys/ioctl.h and linux/fs.h.
(clone_file): New function.
(Fcopy_file): Use it.
---
 configure.ac |  1 +
 src/fileio.c | 33 +++++++++++++++++++++++++--------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9856228..82a672b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1638,6 +1638,7 @@ AC_DEFUN
 
 dnl checks for header files
 AC_CHECK_HEADERS_ONCE(
+  linux/fs.h
   malloc.h
   sys/systeminfo.h
   sys/sysinfo.h
diff --git a/src/fileio.c b/src/fileio.c
index bf6bf62..b4316b3 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -52,6 +52,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "region-cache.h"
 #include "frame.h"
 
+#ifdef HAVE_LINUX_FS_H
+# include <sys/ioctl.h>
+# include <linux/fs.h>
+#endif
+
 #ifdef WINDOWSNT
 #define NOMINMAX 1
 #include <windows.h>
@@ -1829,6 +1834,16 @@ barf_or_query_if_file_exists (Lisp_Object absname, bool known_to_exist,
     }
 }
 
+/* Copy data to DEST from SOURCE if possible.  Return true if OK.  */
+static bool
+clone_file (int dest, int source)
+{
+#ifdef FICLONE
+  return ioctl (dest, FICLONE, source) == 0;
+#endif
+  return false;
+}
+
 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6,
        "fCopy file: \nGCopy %s to file: \np\nP",
        doc: /* Copy FILE to NEWNAME.  Both args must be strings.
@@ -1975,7 +1990,7 @@ permissions.  */)
 
   record_unwind_protect_int (close_file_unwind, ofd);
 
-  off_t oldsize = 0, newsize = 0;
+  off_t oldsize = 0, newsize;
 
   if (already_exists)
     {
@@ -1991,17 +2006,19 @@ permissions.  */)
 
   immediate_quit = 1;
   QUIT;
-  while (true)
+
+  if (clone_file (ofd, ifd))
+    newsize = st.st_size;
+  else
     {
       char buf[MAX_ALLOCA];
-      ptrdiff_t n = emacs_read (ifd, buf, sizeof buf);
+      ptrdiff_t n;
+      for (newsize = 0; 0 < (n = emacs_read (ifd, buf, sizeof buf));
+	   newsize += n)
+	if (emacs_write_sig (ofd, buf, n) != n)
+	  report_file_error ("Write error", newname);
       if (n < 0)
 	report_file_error ("Read error", file);
-      if (n == 0)
-	break;
-      if (emacs_write_sig (ofd, buf, n) != n)
-	report_file_error ("Write error", newname);
-      newsize += n;
     }
 
   /* Truncate any existing output file after writing the data.  This
-- 
2.7.4


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Document-file-synchronization-issues.patch --]
[-- Type: text/x-diff; name="0002-Document-file-synchronization-issues.patch", Size: 4130 bytes --]

From 62f0eb5f8ce6a05288c0b7b7cf8ec3dc373583e4 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sat, 10 Sep 2016 19:12:21 -0700
Subject: [PATCH 2/2] Document file synchronization issues

* doc/lispref/files.texi (Files and Storage): New section.
---
 doc/emacs/files.texi     |  4 ++--
 doc/lispref/backups.texi |  5 +++++
 doc/lispref/files.texi   | 25 +++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index f195a41..7bf4690 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -1554,8 +1554,8 @@ Misc File Ops
 
 @findex copy-file
 @cindex copying files
-  @kbd{M-x copy-file} reads the file @var{old} and writes a new file
-named @var{new} with the same contents.
+  @kbd{M-x copy-file} copies the contents of the file @var{old} to the
+file @var{new}.
 
 @findex copy-directory
   @kbd{M-x copy-directory} copies directories, similar to the
diff --git a/doc/lispref/backups.texi b/doc/lispref/backups.texi
index b9e6466..35a1865 100644
--- a/doc/lispref/backups.texi
+++ b/doc/lispref/backups.texi
@@ -41,6 +41,11 @@ Backup Files
 file gets a new name.  You can delete old numbered backups when you
 don't want them any more, or Emacs can delete them automatically.
 
+  For performance, the operating system may not write the backup
+file's contents to secondary storage immediately, or may alias the
+backup data with the original until one or the other is later
+modified.  @xref{Files and Storage}.
+
 @menu
 * Making Backups::     How Emacs makes backup files, and when.
 * Rename or Copy::     Two alternatives: renaming the old file or copying it.
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 0aea1df..b912d7b 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -41,6 +41,7 @@ Files
                                simultaneous editing by two people.
 * Information about Files::  Testing existence, accessibility, size of files.
 * Changing Files::           Renaming files, changing permissions, etc.
+* Files and Storage::        Surviving power and media failures
 * File Names::               Decomposing and expanding file names.
 * Contents of Directories::  Getting a list of the files in a directory.
 * Create/Delete Dirs::       Creating and Deleting Directories.
@@ -1496,6 +1497,10 @@ Changing Files
 system-dependent error message that describes the reason for the
 failure.
 
+  For performance, the operating system may cache or alias changes
+made by these functions instead of writing them immediately to
+secondary storage.  @xref{Files and Storage}.
+
   In the functions that have an argument @var{newname}, if a file by the
 name of @var{newname} already exists, the actions taken depend on the
 value of the argument @var{ok-if-already-exists}:
@@ -1794,6 +1799,26 @@ Changing Files
 @var{filename}, @code{nil} otherwise.
 @end defun
 
+@node Files and Storage
+@section Files and Secondary Storage
+@cindex secondary storage
+
+After Emacs changes a file, there are two reasons the changes might
+not survive later failures of power or media, both having to do with
+efficiency.  First, the operating system might alias written data with
+data already stored elsewhere on secondary storage until one file or
+the other is later modified; this will lose both files if the only
+copy on secondary storage is lost due to media failure.  Second, the
+operating system might not write data to secondary storage
+immediately, which will lose the data if power is lost.
+
+Although both sorts of failures can largely be avoided by a suitably
+configured file system, such systems are typically more expensive or
+less efficient.  In more-typical systems, to survive media failure you
+can copy the file to a different device, and to survive a power
+failure you can invoke the @command{sync} utility (@pxref{sync
+invocation,,, coreutils, The @sc{gnu} @code{Coreutils} Manual}).
+
 @node File Names
 @section File Names
 @cindex file names
-- 
2.7.4


  reply	other threads:[~2016-09-11  2:16 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-05 19:06 Btrfs clone support in copy operations Kieran Colford
2016-07-05 23:39 ` sbaugh
2016-07-06  0:57   ` Paul Eggert
2016-07-06  0:49 ` bug#23904: " Paul Eggert
2016-07-06  2:45   ` Dmitry Antipov
2016-07-06  5:52     ` Helmut Eller
2016-07-06 11:48     ` Paul Eggert
2016-07-06 14:58       ` Eli Zaretskii
2016-07-06 15:08         ` Paul Eggert
2016-07-06 15:26           ` Eli Zaretskii
2016-07-06 17:32             ` Paul Eggert
2016-09-11  2:16               ` Paul Eggert [this message]
2016-09-11 15:25                 ` Eli Zaretskii
2016-09-11 17:17                   ` Paul Eggert
2016-09-11 19:20                     ` Eli Zaretskii
2016-09-11 22:44                       ` Paul Eggert
2016-09-12  2:35                         ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b4d1ddcd-1ba9-ef27-59a6-5abf317bb7c5@cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=23904-done@debbugs.gnu.org \
    --cc=dmantipov@yandex.ru \
    --cc=eliz@gnu.org \
    --cc=kieran@kcolford.com \
    --cc=sbaugh@catern.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.