volser: Always fetch locked entry in CheckVolume

CheckVolume accepts an optional nvldbentry as an argument.  When this
argument is NULL, CheckVolume correctly locks the nvldbentry before
obtaining the entry and making changes.  However, if an nvldbentry is
passed, CheckVolume merely copies it to a work entry; it also neglects
to obtain the current state of the entry after locking it for
modification.

Change CheckVolume to obtain a locked copy of the nvldbentry if
modifications are required.

Change-Id: Ie98bc57af1cc2955d10982f44abd4c55755c6244
Reviewed-on: https://gerrit.openafs.org/14356
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
This commit is contained in:
Mark Vitale 2020-09-02 15:39:13 -04:00 committed by Andrew Deason
parent 663be53c18
commit c20dceb392

View File

@ -5825,24 +5825,33 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
RWVOL) ? volumeinfo->volid : volumeinfo->parentID);
retry:
createentry = 0; /* Do we need to create a VLDB entry */
modified = 0; /* The VLDB entry was modified */
/* Check to see if the VLDB is ok without locking it (pass 1).
* If it will change, then lock the VLDB entry, read it again,
* then make the changes to it (pass 2).
*/
if (++pass == 2) {
code = ubik_VL_SetLock(cstruct, 0, rwvolid, RWVOL, VLOP_DELETE);
/*
* For pass 2, we must fetch a locked entry from the net. Don't simply
* lock the volume; we must fetch it again in case someone else changed
* it before we locked it.
*/
code = GetLockedEntry(rwvolid, RWVOL, VLOP_DELETE, &entry);
if (code) {
fprintf(STDERR, "Could not lock VLDB entry for %lu\n",
fprintf(STDERR, "Could not fetch locked VLDB entry for volume %lu\n",
(unsigned long)rwvolid);
ERROR_EXIT(code);
}
}
createentry = 0; /* Do we need to create a VLDB entry */
modified = 0; /* The VLDB entry was modified */
if (aentry) {
} else if (aentry != NULL) {
/*
* If we were given a VLDB entry, use that instead of fetching from the
* net.
*/
memcpy(&entry, aentry, sizeof(entry));
} else {
/* Read the entry from VLDB by its RW volume id */
code = VLDB_GetEntryByID(rwvolid, RWVOL, &entry);