xfs
[Top] [All Lists]

[PATCH v3, 02/16] xfsprogs: metadump: simplify '/' handling in generate_

To: xfs@xxxxxxxxxxx
Subject: [PATCH v3, 02/16] xfsprogs: metadump: simplify '/' handling in generate_obfuscated_name()
From: Alex Elder <aelder@xxxxxxx>
Date: Fri, 18 Feb 2011 15:21:01 -0600
User-agent: Heirloom mailx 12.5 7/5/10
In generate_obfuscated_name(), the incoming name is allowed to start
with a '/' character, in which case it is copied over to the new
name and ignored for the remainder of the hash calculation.  A '/'
character is needlessly included at the beginning of each name
stashed in the duplicates table (regardless of whether one was
present in the name provided).

Simplify the affected code by processing the '/' right away, and
using a pointer thereafter for the start of the new name.  Stop
including a leading '/' in the name used for duplicate detection.

Note:  It is not clear a leading '/' character is ever even present
in a name presented for obfuscation.  I have not investigated this
question; this change merely adjusts the code while preserving its
original functionality.

Signed-off-by: Alex Elder <aelder@xxxxxxx>

No significant changes in this version from the last one posted.

---
 db/metadump.c |   66 ++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 24 deletions(-)

Index: b/db/metadump.c
===================================================================
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -441,6 +441,7 @@ generate_obfuscated_name(
        int                     dup;
        xfs_dahash_t            newhash;
        uchar_t                 newname[NAME_MAX];
+       uchar_t                 *newp = &newname[0];
 
        /*
         * Our obfuscation algorithm requires at least 5-character
@@ -458,40 +459,57 @@ generate_obfuscated_name(
        if (ino && in_lost_found(ino, namelen, name))
                return;
 
-       /* create a random name with the same hash value */
+       /*
+        * If the name starts with a slash, just skip over it.  We
+        * will copy our obfuscated name back into space following
+        * the slash when we're done.  Our new name will not have
+        * the '/', and that's the version we'll keep in our
+        * duplicates table.  Note that the namelen value passed in
+        * does not include the leading slash (if any).
+        */
+       if (*name == '/')
+               name++;
 
        hash = libxfs_da_hashname(name, namelen);
        do {
                dup = 0;
-               newname[0] = '/';
-
                for (;;) {
-                       /* if the first char is a "/", preserve it */
-                       i = (name[0] == '/');
-
-                       for (newhash = 0; i < namelen - 5; i++) {
-                               newname[i] = random_filename_char();
-                               newhash = newname[i] ^ rol32(newhash, 7);
+                       /*
+                        * The beginning of the obfuscated name can
+                        * be pretty much anything, so fill it in
+                        * with random characters.  Accumulate its
+                        * new hash value as we go.
+                        */
+                       newhash = 0;
+                       for (i = 0; i < namelen - 5; i++) {
+                               newp[i] = random_filename_char();
+                               newhash = newp[i] ^ rol32(newhash, 7);
                        }
+
+                       /*
+                        * Compute which five bytes need to be used
+                        * at the end of the name so the hash of the
+                        * obfuscated name is the same as the hash
+                        * of the original.
+                        */
                        newhash = rol32(newhash, 3) ^ hash;
-                       if (name[0] != '/' || namelen > 5) {
-                               newname[namelen - 5] = (newhash >> 28) |
-                                               (random_filename_char() & 0xf0);
-                               if (is_invalid_char(newname[namelen - 5]))
-                                       continue;
-                       }
-                       newname[namelen - 4] = (newhash >> 21) & 0x7f;
-                       if (is_invalid_char(newname[namelen - 4]))
+
+                       newp[namelen - 5] = (newhash >> 28) |
+                                       (random_filename_char() & 0xf0);
+                       if (is_invalid_char(newp[namelen - 5]))
+                               continue;
+                       newp[namelen - 4] = (newhash >> 21) & 0x7f;
+                       if (is_invalid_char(newp[namelen - 4]))
                                continue;
-                       newname[namelen - 3] = (newhash >> 14) & 0x7f;
-                       if (is_invalid_char(newname[namelen - 3]))
+                       newp[namelen - 3] = (newhash >> 14) & 0x7f;
+                       if (is_invalid_char(newp[namelen - 3]))
                                continue;
-                       newname[namelen - 2] = (newhash >> 7) & 0x7f;
-                       if (is_invalid_char(newname[namelen - 2]))
+                       newp[namelen - 2] = (newhash >> 7) & 0x7f;
+                       if (is_invalid_char(newp[namelen - 2]))
                                continue;
-                       newname[namelen - 1] = ((newhash >> 0) ^
-                                       (newname[namelen - 5] >> 4)) & 0x7f;
-                       if (is_invalid_char(newname[namelen - 1]))
+                       newp[namelen - 1] = ((newhash >> 0) ^
+                                       (newp[namelen - 5] >> 4)) & 0x7f;
+                       if (is_invalid_char(newp[namelen - 1]))
                                continue;
                        break;
                }

<Prev in Thread] Current Thread [Next in Thread>