NTFS-3g capture: sort attributes by starting LCN
authorEric Biggers <ebiggers3@gmail.com>
Sat, 2 May 2015 15:41:47 +0000 (10:41 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 2 May 2015 16:04:18 +0000 (11:04 -0500)
NEWS
include/wimlib/ntfs_3g.h
src/blob_table.c
src/ntfs-3g_capture.c

diff --git a/NEWS b/NEWS
index 7645593aa3a0ddae39fbb2727b12277b847e8ba5..ab71b7c8d9f5ae644f8b568699286057acaf9641 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,8 @@ Version 1.8.1-BETA:
        In mounted WIM images, the disk usage provided for each file (st_blocks)
        is now the compressed size rather than the uncompressed size.
 
+       The performance of NTFS-3g capture mode has been slightly improved.
+
 Version 1.8.0:
        Improved the LZX compressor.  It is now 15-20% faster than before and
        provides a slightly better compression ratio.
index 7eda7c120c81ea52883efc18ca0ca30d894a6721..3d92dffc8d8936532de1a3e81b28ca9d6219e419 100644 (file)
@@ -15,6 +15,7 @@ struct ntfs_location {
        utf16lechar *attr_name;
        unsigned attr_name_nchars;
        unsigned attr_type;
+       u64 sort_key;
 };
 #endif
 
index 39dc865bf048c6e6e7fbde2789be29f4dcc32ba1..0ddd13ad09901413fc23e21893b4ba7f13cebac7 100644 (file)
@@ -448,7 +448,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2)
                return tstrcmp(blob1->file_on_disk, blob2->file_on_disk);
 #ifdef WITH_NTFS_3G
        case BLOB_IN_NTFS_VOLUME:
-               return cmp_u64(blob1->ntfs_loc->mft_no, blob2->ntfs_loc->mft_no);
+               return cmp_u64(blob1->ntfs_loc->sort_key, blob2->ntfs_loc->sort_key);
 #endif
        default:
                /* No additional sorting order defined for this resource
index 75690917aa6a4dc36fb3c133dd1472c06d69cf46..c0bd9076afeb472801d555a2e53dff3f8d70fcf4 100644 (file)
@@ -168,6 +168,30 @@ attr_type_to_wimlib_stream_type(ATTR_TYPES type)
        }
 }
 
+/* When sorting blobs located in NTFS volumes for sequential reading, we sort
+ * first by starting LCN of the attribute if available, otherwise no sort order
+ * is defined.  This usually results in better sequential access to the volume.
+ */
+static int
+set_attr_sort_key(ntfs_inode *ni, struct ntfs_location *loc)
+{
+       ntfs_attr *na;
+       runlist_element *rl;
+
+       na = open_ntfs_attr(ni, loc);
+       if (!na)
+               return WIMLIB_ERR_NTFS_3G;
+
+       rl = ntfs_attr_find_vcn(na, 0);
+       if (rl && rl->lcn != LCN_HOLE)
+               loc->sort_key = rl->lcn;
+       else
+               loc->sort_key = 0;
+
+       ntfs_attr_close(na);
+       return 0;
+}
+
 /* Save information about an NTFS attribute (stream) to a WIM inode.  */
 static int
 scan_ntfs_attr(struct wim_inode *inode,
@@ -225,6 +249,10 @@ scan_ntfs_attr(struct wim_inode *inode,
                        blob->ntfs_loc->attr_name_nchars = name_nchars;
                }
 
+               ret = set_attr_sort_key(ni, blob->ntfs_loc);
+               if (ret)
+                       goto out_cleanup;
+
                if (unlikely(type == AT_REPARSE_POINT)) {
                        if (blob->size < REPARSE_DATA_OFFSET) {
                                ERROR("Reparse data of \"%s\" "