]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
afs: Sanity-check some AFSFetchStatus structures
authorAndrew Deason <adeason@sinenomine.net>
Fri, 2 Mar 2012 23:06:48 +0000 (17:06 -0600)
committerDerrick Brashear <shadow@dementix.org>
Thu, 30 Aug 2012 12:01:55 +0000 (05:01 -0700)
We currently do not do any sanity checking on the AFSFetchStatus
structures returned from fileservers. Add some sanity checking for
BulkStatus and FetchStatus calls, so we do not screw up our cache if a
fileserver gives us bogus data.

If we do get an invalid AFSFetchStatus structure, act as if the server
gave us a VBUSY error code, so we will retry the request. For OpenAFS
fileservers prior to 1.6.1 that yield this situation, VBUSY is likely
the error code the fileserver should have responded anyway.

Reviewed-on: http://gerrit.openafs.org/6880
Reviewed-by: Alistair Ferguson <alistair.ferguson@mac.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
(cherry picked from commit 5af63fabc553a2fecd4c3080b25fe14483f5bd98)

Change-Id: I88922a75ada96d641bfd0078a8e7d6854c4ea699
Reviewed-on: http://gerrit.openafs.org/7992
Reviewed-by: Derrick Brashear <shadow@dementix.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs_prototypes.h
src/afs/afs_vcache.c

index 580f78b1e010b293f8af16b07948c94610cf2221..b52d21dd59046cb1d341a51dddaffee6cf90dacf 100644 (file)
@@ -622,6 +622,29 @@ Next_AtSys(struct vcache *avc, struct vrequest *areq,
     return 1;
 }
 
+static int
+afs_CheckBulkStatus(struct afs_conn *tc, int nFids, AFSBulkStats *statParm,
+                    AFSCBs *cbParm)
+{
+    int i;
+    int code;
+
+    if (statParm->AFSBulkStats_len != nFids || cbParm->AFSCBs_len != nFids) {
+       return VBUSY;
+    }
+    for (i = 0; i < nFids; i++) {
+       if (statParm->AFSBulkStats_val[i].errorCode) {
+           continue;
+       }
+       code = afs_CheckFetchStatus(tc, &statParm->AFSBulkStats_val[i]);
+       if (code) {
+           return code;
+       }
+    }
+
+    return 0;
+}
+
 extern int BlobScan(struct dcache * afile, afs_int32 ablob);
 
 /* called with an unlocked directory and directory cookie.  Areqp
@@ -1001,6 +1024,10 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                RX_AFS_GLOCK();
            }
            XSTATS_END_TIME;
+
+           if (code == 0) {
+               code = afs_CheckBulkStatus(tcp, fidIndex, &statParm, &cbParm);
+           }
        } else
            code = -1;
     } while (afs_Analyze
index bc72ad846712dfaf2e48e2d598d0a91fe1d077fd..8afda0285d94fcc6c500af3e69533c9410046480 100644 (file)
@@ -1041,6 +1041,8 @@ extern void afs_FlushReclaimedVcaches(void);
 void afs_vcacheInit(int astatSize);
 extern struct vcache *afs_FindVCache(struct VenusFid *afid, afs_int32 * retry,
                                     afs_int32 flag);
+extern int afs_CheckFetchStatus(struct afs_conn *tc,
+                                struct AFSFetchStatus *status);
 extern afs_int32 afs_FetchStatus(struct vcache *avc, struct VenusFid *afid,
                                 struct vrequest *areq,
                                 struct AFSFetchStatus *Outsp);
index 006051fe4c6f5d0789688fa8f1d9b6a09566848b..399eaee1b9305fe57b65edac5601430ea0fa51bd 100644 (file)
@@ -2280,6 +2280,30 @@ afs_UpdateStatus(struct vcache *avc, struct VenusFid *afid,
        afs_PutVolume(volp, READ_LOCK);
 }
 
+/**
+ * Check if a given AFSFetchStatus structure is sane.
+ *
+ * @param[in] tc The server from which we received the status
+ * @param[in] status The status we received
+ *
+ * @return whether the given structure is valid or not
+ *  @retval 0 the structure is fine
+ *  @retval nonzero the structure looks like garbage; act as if we received
+ *                  the returned error code from the server
+ */
+int
+afs_CheckFetchStatus(struct afs_conn *tc, struct AFSFetchStatus *status)
+{
+    if (status->errorCode ||
+        status->InterfaceVersion != 1 ||
+        !(status->FileType > Invalid && status->FileType <= SymbolicLink) ||
+        status->ParentVnode == 0 || status->ParentUnique == 0) {
+
+       return VBUSY;
+    }
+    return 0;
+}
+
 /*!
  * Must be called with avc write-locked
  * don't absolutely have to invalidate the hint unless the dv has
@@ -2311,6 +2335,10 @@ afs_FetchStatus(struct vcache * avc, struct VenusFid * afid,
 
            XSTATS_END_TIME;
 
+           if (code == 0) {
+               code = afs_CheckFetchStatus(tc, Outsp);
+           }
+
        } else
            code = -1;
     } while (afs_Analyze