vol: reset nextVnodeUnique when uniquifier rolls over
authorMichael Meffie <mmeffie@sinenomine.net>
Mon, 23 Dec 2013 17:10:36 +0000 (12:10 -0500)
committerDerrick Brashear <shadow@your-file-system.com>
Sun, 12 Jan 2014 19:47:22 +0000 (11:47 -0800)
The on disk uniquifier counter is set to 200 more than the current
nextVnodeUnique counter when the volume information is updated to disk. When
the nextVnodeUnique is near UINT32_MAX, then the uniquifier counter rolls
over.  This can happen during a volume header update due to
VBumpVolumeUsage_r().

With this change, the nextVnodeUnique customer is reset to 2 and the
uniquifier is reset to 202 when a roll over occurs. (uniquifier of 1 is
reserved for the root vnode.)

With this change, the number of possible uniquifier numbers is limited to
200 less than UINT32_MAX.

The following shows a series of vnode creation/deletions to illustrate
the uniquifier rollover before this commit:

fid = 536870918.4.4294967114, nextVnodeUnique = 4294967115, uniquifier = 4294967295
fid = 536870918.4.4294967115, nextVnodeUnique = 4294967116, uniquifier = 4294967295
fid = 536870918.4.4294967116, nextVnodeUnique = 4294967117, uniquifier = 21
fid = 536870918.4.4294967117, nextVnodeUnique = 4294967118, uniquifier = 22

and after this commit:

fid = 536870918.4.4294967115, nextVnodeUnique = 4294967116, uniquifier = 4294967295
fid = 536870918.4.4294967116, nextVnodeUnique = 2, uniquifier = 202
fid = 536870918.4.2, nextVnodeUnique = 3, uniquifier = 202
fid = 536870918.4.3, nextVnodeUnique = 4, uniquifier = 202

Change-Id: I93c8a7cf47e39b8701265d6507cfc4f8c1352ddc
Reviewed-on: http://gerrit.openafs.org/10617
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>

src/vol/volume.c

index d6c2d38..7eb239d 100644 (file)
@@ -218,6 +218,12 @@ pthread_t vol_glock_holder = 0;
  */
 #define VOLUME_HASH_REORDER_CHAIN_THRESH (VOLUME_HASH_REORDER_THRESHOLD / 2)
 
+/*
+ * The per volume uniquifier is bumped by 200 and and written to disk
+ * every 200 file creates.
+ */
+#define VOLUME_UPDATE_UNIQUIFIER_BUMP 200
+
 #include "rx/rx_queue.h"
 
 
@@ -4929,10 +4935,20 @@ VUpdateVolume_r(Error * ec, Volume * vp, int flags)
 #endif
 
     *ec = 0;
-    if (programType == fileServer)
-       V_uniquifier(vp) =
-           (V_inUse(vp) ? V_nextVnodeUnique(vp) +
-            200 : V_nextVnodeUnique(vp));
+    if (programType == fileServer) {
+       if (!V_inUse(vp)) {
+           V_uniquifier(vp) = V_nextVnodeUnique(vp);
+       } else {
+           V_uniquifier(vp) =
+               V_nextVnodeUnique(vp) + VOLUME_UPDATE_UNIQUIFIER_BUMP;
+           if (V_uniquifier(vp) < V_nextVnodeUnique(vp)) {
+               /* uniquifier rolled over; reset the counters */
+               V_nextVnodeUnique(vp) = 2;      /* 1 is reserved for the root vnode */
+               V_uniquifier(vp) =
+                   V_nextVnodeUnique(vp) + VOLUME_UPDATE_UNIQUIFIER_BUMP;
+           }
+       }
+    }
 
 #ifdef AFS_DEMAND_ATTACH_FS
     state_save = VChangeState_r(vp, VOL_STATE_UPDATING);