Re: auto merging extents

2011-04-06 Thread Pádraig Brady
The last version had a nasty data corruption inducing
off by one issue.  I'll apply the attached this evening.

cheers,
Pádraig.
From 40d1676c087cc79a059b9b0a7207f9eb9f66f074 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= p...@draigbrady.com
Date: Tue, 5 Apr 2011 11:04:13 +0100
Subject: [PATCH] copy: handle mergeable extents across fiemap scans

* extent-scan.h (extent_scan_free): Init the pointer to NULL,
and reset the count to 0, so that we can realloc the buffer.
* src/extent-scan.c (extent_scan_init): Likewise.
(extent_scan_read): Loop over multiple fiemap scans, so we handle
mergeable extents that span across fiemap scan boundaries.  Once
we have enough unique extents, return so as to minimize memory use.
---
 src/extent-scan.c |  194 +
 src/extent-scan.h |2 +
 2 files changed, 108 insertions(+), 88 deletions(-)

diff --git a/src/extent-scan.c b/src/extent-scan.c
index c0a5de6..e56927b 100644
--- a/src/extent-scan.c
+++ b/src/extent-scan.c
@@ -67,6 +67,7 @@ extent_scan_init (int src_fd, struct extent_scan *scan)
 {
   scan-fd = src_fd;
   scan-ei_count = 0;
+  scan-ext_info = NULL;
   scan-scan_start = 0;
   scan-initial_scan_failed = false;
   scan-hit_final_extent = false;
@@ -82,108 +83,125 @@ extent_scan_init (int src_fd, struct extent_scan *scan)
 extern bool
 extent_scan_read (struct extent_scan *scan)
 {
-  union { struct fiemap f; char c[4096]; } fiemap_buf;
-  struct fiemap *fiemap = fiemap_buf.f;
-  struct fiemap_extent *fm_extents = fiemap-fm_extents[0];
-  enum { count = (sizeof fiemap_buf - sizeof *fiemap) / sizeof *fm_extents };
-  verify (count != 0);
-
-  /* This is required at least to initialize fiemap-fm_start,
- but also serves (in mid 2010) to appease valgrind, which
- appears not to know the semantics of the FIEMAP ioctl. */
-  memset (fiemap_buf, 0, sizeof fiemap_buf);
-
-  fiemap-fm_start = scan-scan_start;
-  fiemap-fm_flags = scan-fm_flags;
-  fiemap-fm_extent_count = count;
-  fiemap-fm_length = FIEMAP_MAX_OFFSET - scan-scan_start;
-
-  /* Fall back to the standard copy if call ioctl(2) failed for the
- the first time.  */
-  if (ioctl (scan-fd, FS_IOC_FIEMAP, fiemap)  0)
-{
-  if (scan-scan_start == 0)
-scan-initial_scan_failed = true;
-  return false;
-}
-
-  /* If 0 extents are returned, then more get_extent_table() are not needed.  
*/
-  if (fiemap-fm_mapped_extents == 0)
-{
-  scan-hit_final_extent = true;
-  return false;
-}
-
-  scan-ei_count = fiemap-fm_mapped_extents;
-  scan-ext_info = xnmalloc (scan-ei_count, sizeof (struct extent_info));
-
-  unsigned int i, si = 0;
+  unsigned int si = 0;
   struct extent_info *last_ei IF_LINT ( = scan-ext_info);
 
-  for (i = 0; i  scan-ei_count; i++)
+  while (true)
 {
-  assert (fm_extents[i].fe_logical = OFF_T_MAX - fm_extents[i].fe_length);
+  union { struct fiemap f; char c[4096]; } fiemap_buf;
+  struct fiemap *fiemap = fiemap_buf.f;
+  struct fiemap_extent *fm_extents = fiemap-fm_extents[0];
+  enum { count = (sizeof fiemap_buf - sizeof *fiemap)/sizeof *fm_extents };
+  verify (count  1);
+
+  /* This is required at least to initialize fiemap-fm_start,
+ but also serves (in mid 2010) to appease valgrind, which
+ appears not to know the semantics of the FIEMAP ioctl. */
+  memset (fiemap_buf, 0, sizeof fiemap_buf);
+
+  fiemap-fm_start = scan-scan_start;
+  fiemap-fm_flags = scan-fm_flags;
+  fiemap-fm_extent_count = count;
+  fiemap-fm_length = FIEMAP_MAX_OFFSET - scan-scan_start;
+
+  /* Fall back to the standard copy if call ioctl(2) failed for the
+ the first time.  */
+  if (ioctl (scan-fd, FS_IOC_FIEMAP, fiemap)  0)
+{
+  if (scan-scan_start == 0)
+scan-initial_scan_failed = true;
+  return false;
+}
 
-  if (si  last_ei-ext_flags ==
-  (fm_extents[i].fe_flags  ~FIEMAP_EXTENT_LAST)
-   (last_ei-ext_logical + last_ei-ext_length
-  == fm_extents[i].fe_logical))
+  /* If 0 extents are returned, then no more scans are needed.  */
+  if (fiemap-fm_mapped_extents == 0)
 {
-  /* Merge previous with last.  */
-  last_ei-ext_length += fm_extents[i].fe_length;
-  /* Copy flags in case different.  */
-  last_ei-ext_flags = fm_extents[i].fe_flags;
+  scan-hit_final_extent = true;
+  return scan-scan_start != 0;
 }
-  else if ((si == 0  scan-scan_start  fm_extents[i].fe_logical)
-   || (si  last_ei-ext_logical + last_ei-ext_length 
-   fm_extents[i].fe_logical))
+
+  assert (scan-ei_count = SIZE_MAX - fiemap-fm_mapped_extents);
+  scan-ei_count += fiemap-fm_mapped_extents;
+  scan-ext_info = xnrealloc (scan-ext_info, scan-ei_count,
+  sizeof (struct extent_info));
+
+  unsigned int i = 0;
+  

sort parameters question: -V and -f

2011-04-06 Thread Assaf Gordon
Hello,

I'm wondering if this is a bug (where -f is ignored when using version sort):

=
$ sort --debug -f -k2,2V 
sort: using simple byte comparison
sort: leading blanks are significant in key 1; consider also specifying `b'
sort: option `-f' is ignored
==

My assumption is that using -f as stand alone parameter should have the same 
effect as using it in a specific key (for that key). e.g. the following two 
commands are equivalent:
 sort -f -k1,1
 sort -k1f,1

But the following two commands are not equivalent (because the standalone -f 
is ignored):
 sort -f -k1V,1
 sort -k1Vf,1

Example:
=

## This works
$ printf a\nB\nc\n | sort -k1f,1
a
B
c
$ printf a\nB\nc\n | sort -f -k1,1
a
B
c

## This doesn't work
$ printf a13\nA5\na1\n | sort -k1Vf,1
a1
A5
a13

$ printf a13\nA5\na1\n | sort -f -k1V,1
A5
a1
a13
===

I'm using coreutils 8.10.

-gordon



Re: sort parameters question: -V and -f

2011-04-06 Thread Pádraig Brady
On 06/04/11 22:26, Assaf Gordon wrote:
 Hello,
 
 I'm wondering if this is a bug (where -f is ignored when using version 
 sort):
 
 =
 $ sort --debug -f -k2,2V 
 sort: using simple byte comparison
 sort: leading blanks are significant in key 1; consider also specifying `b'
 sort: option `-f' is ignored

The same happens for any ordering option.
If any is specified for the key, then all global options are ignored.
This is specified by POSIX and here it's demonstrated on solaris:

solaris:~  printf a13\nA5\na1\n | sort -f -k1r,1
a13
a1
A5
solaris:~  printf a13\nA5\na1\n | sort -k1r,1
a13
a1
A5

cheers,
Pádraig.