From: Derrick Brashear Date: Mon, 1 Dec 2003 20:16:02 +0000 (+0000) Subject: rpc-rename-avoid-loop-20031201 X-Git-Tag: openafs-devel-1_3_51~68 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=1c5a7b4ea135dcccadea1775922a783c5fc42989;p=packages%2Fo%2Fopenafs.git rpc-rename-avoid-loop-20031201 enumerated solution (n vnodes cannot yield n+1 loop passes) suggested by jhutz@cmu.edu. avoid looping forever on a corrupt parent. --- diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 7da4edfca..5171305b5 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -3949,7 +3949,13 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName, * 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; @@ -3963,10 +3969,16 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName, 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); } }