extern int DoLogging;
extern struct afsconf_dir *tdir;
+extern int DoPreserveVolumeStats;
extern void LogError(afs_int32 errcode);
afs_fsize_t length;
ssize_t nBytes;
- vnode = (struct VnodeDiskObject *)malloc(SIZEOF_LARGEDISKVNODE);
+ vnode = calloc(1, SIZEOF_LARGEDISKVNODE);
if (!vnode)
return ENOMEM;
- memset(vnode, 0, SIZEOF_LARGEDISKVNODE);
V_pref(vp, nearInode);
inodeNumber =
}
newId = *newNumber;
- if (newType != readonlyVolume && newType != backupVolume)
- return EINVAL;
tt = FindTrans(atrans);
if (!tt)
return ENOENT;
purgevp = NULL;
}
originalvp = tt->volume;
- if ((V_type(originalvp) == backupVolume)
- || (V_type(originalvp) == readonlyVolume)) {
- Log("1 Volser: Clone: The volume to be cloned must be a read/write; aborted\n");
- error = EROFS;
- goto fail;
- }
if ((V_destroyMe(originalvp) == DESTROY_ME) || !V_inService(originalvp)) {
Log("1 Volser: Clone: Volume %d is offline and cannot be cloned\n",
V_id(originalvp));
error = EINVAL;
goto fail;
}
- if (V_type(originalvp) == readonlyVolume
- && V_parentId(originalvp) != V_parentId(purgevp)) {
- Log("1 Volser: Clone: Volume %u and volume %u were not cloned from the same parent volume; aborted\n", tt->volid, purgeId);
- error = EXDEV;
- goto fail;
- }
- if (V_type(originalvp) == readwriteVolume
- && tt->volid != V_parentId(purgevp)) {
- Log("1 Volser: Clone: Volume %u was not originally cloned from volume %u; aborted\n", purgeId, tt->volid);
+ if (V_parentId(originalvp) != V_parentId(purgevp)) {
+ Log("1 Volser: Clone: Volume %u and volume %u were not originally cloned from the same parent; aborted\n", purgeId, tt->volid);
error = EXDEV;
goto fail;
}
salv_vp = originalvp;
#endif
- newvp =
- VCreateVolume(&error, originalvp->partition->name, newId,
- V_parentId(originalvp));
- if (error) {
- Log("1 Volser: Clone: Couldn't create new volume; clone aborted\n");
- newvp = (Volume *) 0;
- goto fail;
+ if (purgeId == newId) {
+ newvp = purgevp;
+ } else {
+ newvp =
+ VCreateVolume(&error, originalvp->partition->name, newId,
+ V_parentId(originalvp));
+ if (error) {
+ Log("1 Volser: Clone: Couldn't create new volume; clone aborted\n");
+ newvp = (Volume *) 0;
+ goto fail;
+ }
}
if (newType == readonlyVolume)
V_cloneId(originalvp) = newId;
afs_int32 newType;
struct volser_trans *tt, *ttc;
char caller[MAXKTCNAMELEN];
+ VolumeDiskData saved_header;
/*not a super user */
if (!afsconf_SuperUser(tdir, acid, caller))
error = EXDEV;
goto fail;
}
- if (V_type(clonevp) != readonlyVolume && V_type(clonevp) != backupVolume) {
- Log("1 Volser: Clone: The \"recloned\" volume must be a read only volume; aborted\n");
- error = EINVAL;
- goto fail;
- }
- if (V_type(originalvp) == readonlyVolume
- && V_parentId(originalvp) != V_parentId(clonevp)) {
- Log("1 Volser: Clone: Volume %u and volume %u were not cloned from the same parent volume; aborted\n", tt->volid, cloneId);
- error = EXDEV;
- goto fail;
- }
- if (V_type(originalvp) == readwriteVolume
- && tt->volid != V_parentId(clonevp)) {
+ if (V_parentId(originalvp) != V_parentId(clonevp)) {
Log("1 Volser: Clone: Volume %u was not originally cloned from volume %u; aborted\n", cloneId, tt->volid);
error = EXDEV;
goto fail;
}
+ if (DoPreserveVolumeStats) {
+ CopyVolumeStats(&V_disk(clonevp), &saved_header);
+ }
+
error = 0;
Log("1 Volser: Clone: Recloning volume %u to volume %u\n", tt->volid,
cloneId);
}
/* don't do strcpy onto diskstuff.name, it's still OK from 1st clone */
- /* pretend recloned volume is a totally new instance */
- V_copyDate(clonevp) = time(0);
- V_creationDate(clonevp) = V_copyDate(clonevp);
- ClearVolumeStats(&V_disk(clonevp));
+ /* update the creationDate, since this represents the last cloning date
+ * for ROs. But do not update copyDate; let it stay so we can identify
+ * when the clone was first created. */
+ V_creationDate(clonevp) = time(0);
+ if (DoPreserveVolumeStats) {
+ CopyVolumeStats(&saved_header, &V_disk(clonevp));
+ } else {
+ ClearVolumeStats(&V_disk(clonevp));
+ }
V_destroyMe(clonevp) = 0;
V_inService(clonevp) = 0;
if (newType == backupVolume) {
- V_backupDate(originalvp) = V_copyDate(clonevp);
- V_backupDate(clonevp) = V_copyDate(clonevp);
+ V_backupDate(originalvp) = V_creationDate(clonevp);
+ V_backupDate(clonevp) = V_creationDate(clonevp);
}
V_inUse(clonevp) = 0;
VUpdateVolume(&error, clonevp);
TRELE(tt);
return E2BIG;
}
- *aname = (char *)realloc(*aname, len);
+ *aname = realloc(*aname, len);
strcpy(*aname, td->name);
TClearRxCall(tt);
if (TRELE(tt))
int code;
volint_info_handle_t handle;
- volumeInfo->volEntries_val = (volintInfo *) malloc(sizeof(volintInfo));
+ volumeInfo->volEntries_val = calloc(1, sizeof(volintInfo));
if (!volumeInfo->volEntries_val)
return ENOMEM;
- memset(volumeInfo->volEntries_val, 0, sizeof(volintInfo)); /* Clear structure */
volumeInfo->volEntries_len = 1;
if (GetPartName(partid, pname))
* Set up our pointers for action, marking our structure to hold exactly
* one entry. Also, assume we'll fail in our quest.
*/
- a_volumeXInfoP->volXEntries_val =
- (volintXInfo *) malloc(sizeof(volintXInfo));
+ a_volumeXInfoP->volXEntries_val = calloc(1, sizeof(volintXInfo));
if (!a_volumeXInfoP->volXEntries_val)
return ENOMEM;
- memset(a_volumeXInfoP->volXEntries_val, 0, sizeof(volintXInfo)); /* Clear structure */
a_volumeXInfoP->volXEntries_len = 1;
code = ENODEV;
int code;
volint_info_handle_t handle;
- volumeInfo->volEntries_val =
- (volintInfo *) malloc(allocSize * sizeof(volintInfo));
+ volumeInfo->volEntries_val = calloc(allocSize, sizeof(volintInfo));
if (!volumeInfo->volEntries_val)
return ENOMEM;
- memset(volumeInfo->volEntries_val, 0, sizeof(volintInfo)); /* Clear structure */
pntr = volumeInfo->volEntries_val;
volumeInfo->volEntries_len = 0;
if ((allocSize - volumeInfo->volEntries_len) < 5) {
/*running out of space, allocate more space */
allocSize = (allocSize * 3) / 2;
- pntr =
- (volintInfo *) realloc((char *)volumeInfo->volEntries_val,
- allocSize * sizeof(volintInfo));
+ pntr = realloc(volumeInfo->volEntries_val,
+ allocSize * sizeof(volintInfo));
if (pntr == NULL) {
closedir(dirp);
return VOLSERNO_MEMORY;
* Allocate a large array of extended volume info structures, then
* set it up for action.
*/
- a_volumeXInfoP->volXEntries_val =
- (volintXInfo *) malloc(allocSize * sizeof(volintXInfo));
+ a_volumeXInfoP->volXEntries_val = calloc(allocSize, sizeof(volintXInfo));
if (!a_volumeXInfoP->volXEntries_val)
return ENOMEM;
- memset(a_volumeXInfoP->volXEntries_val, 0, sizeof(volintXInfo)); /* Clear structure */
xInfoP = a_volumeXInfoP->volXEntries_val;
a_volumeXInfoP->volXEntries_len = 0;
pntr->callValid = 0;
if (tt->rxCallPtr) { /*record call related info */
pntr->callValid = 1;
+#if 0
pntr->readNext = tt->rxCallPtr->rnext;
pntr->transmitNext = tt->rxCallPtr->tnext;
pntr->lastSendTime = tt->rxCallPtr->lastSendTime;
pntr->lastReceiveTime = tt->rxCallPtr->lastReceiveTime;
+#endif
}
VTRANS_OBJ_UNLOCK(tt);
pntr++;
transInfo->transDebugEntries_len += 1;
if ((allocSize - transInfo->transDebugEntries_len) < 5) { /*alloc some more space */
allocSize = (allocSize * 3) / 2;
- pntr =
- (transDebugInfo *) realloc((char *)transInfo->
- transDebugEntries_val,
- allocSize *
- sizeof(transDebugInfo));
+ pntr = realloc(transInfo->transDebugEntries_val,
+ allocSize * sizeof(transDebugInfo));
transInfo->transDebugEntries_val = pntr;
pntr =
transInfo->transDebugEntries_val +