]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE12-rpc-rename-avoid-loop-20031201
authorDerrick Brashear <shadow@dementia.org>
Mon, 18 Oct 2004 04:15:42 +0000 (04:15 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 18 Oct 2004 04:15:42 +0000 (04:15 +0000)
enumerated solution (n vnodes cannot yield n+1 loop passes) suggested by
jhutz@cmu.edu. avoid looping forever on a corrupt parent.

(cherry picked from commit 1c5a7b4ea135dcccadea1775922a783c5fc42989)

src/viced/afsfileprocs.c

index 2e92218c8fe3140ab588caf3dda0fef773b4bdbc..ffef0e281b0bc52898163b18d63270823ee32eb5 100644 (file)
@@ -2256,7 +2256,13 @@ SAFSS_Rename (tcon, OldDirFid, OldName, NewDirFid, NewName, OutOldDirStatus,
      * directory structure.  This is to prevent removing a subtree alltogether
      */
     if ((oldvptr != newvptr) && (fileptr->disk.type == vDirectory)) {
-       for (testnode = newvptr->disk.parent; testnode != 0;) {
+        afs_int32 forpass = 0, vnum = 0, top = 0;
+        for (testnode = newvptr->disk.parent; testnode != 0; forpass++) {
+            if (testnode > vnum) vnum = testnode;
+            if (forpass > vnum) {
+                errorCode = FSERR_ELOOP;
+                goto Bad_Rename;
+            }
            if (testnode == oldvptr->vnodeNumber) {
                testnode = oldvptr->disk.parent;
                continue;
@@ -2270,10 +2276,16 @@ SAFSS_Rename (tcon, OldDirFid, OldName, NewDirFid, NewName, OutOldDirStatus,
                errorCode = FSERR_ELOOP;
                goto Bad_Rename;
            }
+           if (testnode == 1) top = 1;
            testvptr = VGetVnode(&errorCode, volptr, testnode, READ_LOCK);
            assert(errorCode == 0);
            testnode = testvptr->disk.parent;
            VPutVnode(&errorCode, testvptr);
+            if ((top == 1) && (testnode != 0)) {
+                VTakeOffline(volptr);
+                errorCode = EIO;
+                goto Bad_Rename;
+            }
            assert(errorCode == 0);
        }
     }