]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfsprogs: metadump: simplify '/' handling
authorAlex Elder <aelder@sgi.com>
Fri, 18 Feb 2011 21:21:01 +0000 (21:21 +0000)
committerAlex Elder <aelder@sgi.com>
Tue, 8 Mar 2011 18:04:03 +0000 (12:04 -0600)
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@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
db/metadump.c

index 6ab2b2a250c7fc5b0a49fb9e896bfb7627fd071a..25f52efc2bcfa5c829500242655ab442aad7ce9e 100644 (file)
@@ -448,6 +448,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
@@ -468,40 +469,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;
                }