Re: [PATCH] dd: add a flag to discard cached data

2011-02-24 Thread Pádraig Brady
On 24/02/11 07:52, Jim Meyering wrote:
 One quick question: does the test need
 something to make it skip (not fail)
 on systems that lack kernel support for the feature?

Oops right.
Attached is latest version.

thanks for the review,
Pádraig.
From fe067f8f52defc54636ae862df03a2115ac6266f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= p...@draigbrady.com
Date: Tue, 22 Feb 2011 21:14:00 +
Subject: [PATCH] dd: add a flag to discard cached data

* src/dd.c (FFS_MASK): A new macro (Find First Set) refactored
from the following enum as it's now used twice.
(usage): Mention the new 'nocache' flag.
(cache_round): A new function to help ignore cache
drop requests less than page_size.
(invalidate_cache): A new function to call posix_fadvise()
with the appropriate offset and length.  Note we don't
use fdadvise() so we can detect errors when count=0.
(dd_copy): Call invalidate_cache() for the read portions.
(iwrite): Likewise for the written portions.
(main): Call invalidate_cache for page_size slop or
for full file when count=0.
* cfg.mk (sc_dd_O_FLAGS): Adjust to pass.
* doc/coreutils.texi (dd invocation): Describe the 'nocache' flag,
and give some examples of how it can be used.
* tests/dd/nocache: A new test.
* tests/Makefile.am: Reference the new test.
* NEWS: Mention the new feature.
---
 NEWS   |6 ++
 cfg.mk |4 +-
 doc/coreutils.texi |   25 
 src/dd.c   |  160 +---
 tests/Makefile.am  |1 +
 tests/dd/nocache   |   58 +++
 6 files changed, 244 insertions(+), 10 deletions(-)
 create mode 100755 tests/dd/nocache

diff --git a/NEWS b/NEWS
index a367d8d..9ec24a6 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,12 @@ GNU coreutils NEWS-*- outline -*-
   delimiter and an unbounded range like -f1234567890-.
   [bug introduced in coreutils-5.3.0]
 
+** New features
+
+  dd now accepts the 'nocache' flag to the iflag and oflag options,
+  which will discard any cache associated with the files, or
+  processed portion thereof.
+
 
 * Noteworthy changes in release 8.10 (2011-02-04) [stable]
 
diff --git a/cfg.mk b/cfg.mk
index e4f3faa..c897dc4 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -39,8 +39,8 @@ _hv_file ?= $(srcdir)/tests/misc/help-version
 dd = $(srcdir)/src/dd.c
 sc_dd_O_FLAGS:
 	@rm -f $@.1 $@.2
-	@{ echo O_FULLBLOCK; perl -nle '/^ +\| (O_\w*)$$/ and print $$1' \
-	  $(dd); } | sort  $@.1
+	@{ echo O_FULLBLOCK; echo O_NOCACHE;\
+	  perl -nle '/^ +\| (O_\w*)$$/ and print $$1' $(dd); } | sort  $@.1
 	@{ echo O_NOFOLLOW; perl -nle '/{[a-z]+,\s*(O_\w+)},/ and print $$1' \
 	  $(dd); } | sort  $@.2
 	@diff -u $@.1 $@.2 || diff=1 || diff=;\
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index ea35afe..529adab 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -8168,6 +8168,31 @@ last-access and last-modified time) is not necessarily synchronized.
 @cindex synchronized data and metadata I/O
 Use synchronized I/O for both data and metadata.
 
+@item nocache
+@opindex nocache
+@cindex discarding file cache
+Discard the data cache for a file.
+When count=0 all cache is discarded,
+otherwise the cache is dropped for the processed
+portion of the file.  Also when count=0
+failure to discard the cache is diagnosed
+and reflected in the exit status.
+Here as some usage examples:
+
+@example
+# Advise to drop cache for whole file
+dd if=ifile iflag=nocache count=0
+
+# Ensure drop cache for the whole file
+dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
+
+# Drop cache for part of file
+dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
+
+# Stream data just using read-ahead cache
+dd if=ifile of=ofile iflag=nocache oflag=nocache
+@end example
+
 @item nonblock
 @opindex nonblock
 @cindex nonblocking I/O
diff --git a/src/dd.c b/src/dd.c
index daddc1e..f62aaed 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -225,6 +225,9 @@ static sig_atomic_t volatile interrupt_signal;
 /* A count of the number of pending info signals that have been received.  */
 static sig_atomic_t volatile info_signal_count;
 
+/* Whether to discard cache for input or output.  */
+static bool i_nocache, o_nocache;
+
 /* Function used for read (to handle iflag=fullblock parameter).  */
 static ssize_t (*iread_fnc) (int fd, char *buf, size_t size);
 
@@ -259,6 +262,7 @@ static struct symbol_value const conversions[] =
   {, 0}
 };
 
+#define FFS_MASK(x) ((x) ^ ((x)  ((x) - 1)))
 enum
   {
 /* Compute a value that's bitwise disjoint from the union
@@ -278,17 +282,23 @@ enum
   | O_SYNC
   | O_TEXT
   ),
-/* Use its lowest bit.  */
-O_FULLBLOCK = v ^ (v  (v - 1))
+
+/* Use its lowest bits for private flags.  */
+O_FULLBLOCK = FFS_MASK (v),
+v2 = v ^ O_FULLBLOCK,
+
+O_NOCACHE = FFS_MASK (v2)
   };
 
 /* Ensure that we got something.  */
 verify (O_FULLBLOCK != 0);
+verify (O_NOCACHE != 0);
 
 #define MULTIPLE_BITS_SET(i) (((i

Re: [PATCH] dd: add a flag to discard cached data

2011-02-24 Thread Jim Meyering
Pádraig Brady wrote:

 On 24/02/11 07:52, Jim Meyering wrote:
 One quick question: does the test need
 something to make it skip (not fail)
 on systems that lack kernel support for the feature?

 Oops right.
 Attached is latest version.
...
 +# Advise to drop cache for whole file
 +if ! dd if=ifile iflag=nocache count=0 2err; then
 +  if grep -F 'Operation not supported' err /dev/null; then
 + warn_ 'skipping part; this file system lacks support for 
 posix_fadvise()'
 + skip=1
 +  else
 +fail=1
 +  fi
 +fi

Thanks for the quick fix.
That looks fine, but I'd drop the use of -F,
since it's just an optimization in this case, and
probably not portable to some crufty targets.

Hmm.. but I see uses of grep -F in other tests and
even in bootstrap, so maybe it's not a problem, these days:

$ git grep -l grep.-F
bootstrap
tests/cp/cp-mv-enotsup-xattr
tests/cp/fiemap-perf
tests/misc/xattr



[PATCH] dd: add a flag to discard cached data

2011-02-22 Thread Pádraig Brady
I noticed fadvise(DONTNEED) getting some love in the kernel recently
   http://lkml.org/lkml/2011/2/17/169
Which prompted me to implement this. With the attached one can now:

  # Advise to drop cache for whole file
  dd if=ifile iflag=nocache count=0

  # Ensure drop cache for whole file
  dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0

  # Drop cache for part of file
  dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null

  # Stream data just using readahead cache
  dd if=ifile of=ofile iflag=nocache oflag=nocache

When count=0, i.e. when only manipulating the cache,
we propagate the posix_fadvise() return to the exit status.

Note this will invalidate the cache even if another
process has the file open. That could be avoided with mincor:
   http://insights.oetiker.ch/linux/fadvise.html
However, I don't think that's needed for a tool like dd.

cheers,
Pádraig.
From 5ebe7618f8d62a81e053a57390132e4013218416 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= p...@draigbrady.com
Date: Tue, 22 Feb 2011 21:14:00 +
Subject: [PATCH] dd: add a flag to discard cached data

* src/dd.c (usage): Add the 'nocache' flag.
(cache_round): A new function to help ignore cache
drop requests less than page_size.
(invalidate_cache): A new function to call posix_fadvise()
with the appropriate offset and length.  Note we don't
use fdadvise() so we can detect errors when count=0.
(dd_copy): Call invalidate_cache() for the processed portions.
(main): Call invalidate_cache for page_size slop or
for full file when count=0.
* cfg.mk (sc_dd_O_FLAGS): Adjust to pass.
* doc/coreutils.texi (dd invocation): Describe the 'nocache' flag,
and give some examples of how it can be used.
* tests/dd/nocache: A new test.
* tests/Makefile.am: Reference the new test.
* NEWS: Mention the new feature.
---
 NEWS   |6 ++
 cfg.mk |4 +-
 doc/coreutils.texi |   25 
 src/dd.c   |  160 +---
 tests/Makefile.am  |1 +
 tests/dd/nocache   |   48 
 6 files changed, 234 insertions(+), 10 deletions(-)
 create mode 100755 tests/dd/nocache

diff --git a/NEWS b/NEWS
index a367d8d..bbb8bd3 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,12 @@ GNU coreutils NEWS-*- outline -*-
   delimiter and an unbounded range like -f1234567890-.
   [bug introduced in coreutils-5.3.0]
 
+** New features
+
+  dd now accepts the nocache option to iflag and oflag,
+  which will discard any cache associated with the files,
+  or processed portion thereof.
+
 
 * Noteworthy changes in release 8.10 (2011-02-04) [stable]
 
diff --git a/cfg.mk b/cfg.mk
index e4f3faa..c897dc4 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -39,8 +39,8 @@ _hv_file ?= $(srcdir)/tests/misc/help-version
 dd = $(srcdir)/src/dd.c
 sc_dd_O_FLAGS:
 	@rm -f $@.1 $@.2
-	@{ echo O_FULLBLOCK; perl -nle '/^ +\| (O_\w*)$$/ and print $$1' \
-	  $(dd); } | sort  $@.1
+	@{ echo O_FULLBLOCK; echo O_NOCACHE;\
+	  perl -nle '/^ +\| (O_\w*)$$/ and print $$1' $(dd); } | sort  $@.1
 	@{ echo O_NOFOLLOW; perl -nle '/{[a-z]+,\s*(O_\w+)},/ and print $$1' \
 	  $(dd); } | sort  $@.2
 	@diff -u $@.1 $@.2 || diff=1 || diff=;\
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index ea35afe..529adab 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -8168,6 +8168,31 @@ last-access and last-modified time) is not necessarily synchronized.
 @cindex synchronized data and metadata I/O
 Use synchronized I/O for both data and metadata.
 
+@item nocache
+@opindex nocache
+@cindex discarding file cache
+Discard the data cache for a file.
+When count=0 all cache is discarded,
+otherwise the cache is dropped for the processed
+portion of the file.  Also when count=0
+failure to discard the cache is diagnosed
+and reflected in the exit status.
+Here as some usage examples:
+
+@example
+# Advise to drop cache for whole file
+dd if=ifile iflag=nocache count=0
+
+# Ensure drop cache for the whole file
+dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
+
+# Drop cache for part of file
+dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
+
+# Stream data just using read-ahead cache
+dd if=ifile of=ofile iflag=nocache oflag=nocache
+@end example
+
 @item nonblock
 @opindex nonblock
 @cindex nonblocking I/O
diff --git a/src/dd.c b/src/dd.c
index daddc1e..f62aaed 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -225,6 +225,9 @@ static sig_atomic_t volatile interrupt_signal;
 /* A count of the number of pending info signals that have been received.  */
 static sig_atomic_t volatile info_signal_count;
 
+/* Whether to discard cache for input or output.  */
+static bool i_nocache, o_nocache;
+
 /* Function used for read (to handle iflag=fullblock parameter).  */
 static ssize_t (*iread_fnc) (int fd, char *buf, size_t size);
 
@@ -259,6 +262,7 @@ static struct symbol_value const conversions[] =
   {, 0}
 };
 
+#define FFS_MASK(x) ((x) ^ ((x)  ((x) - 1)))
 enum
   {
 /* Compute