* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
+ *
+ * Portions Copyright (c) 2007-2008 Sine Nomine Associates
*/
#include <afsconfig.h>
#include <stdio.h>
#include <sys/types.h>
+#include <string.h>
#include <errno.h>
#ifdef AFS_NT40_ENV
#include <fcntl.h>
#include <unistd.h>
#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
#include <dirent.h>
#include <sys/stat.h>
#include <rx/xdr.h>
#include <afs/nfs.h>
#include <lwp.h>
#include <lock.h>
-#include <afs/auth.h>
#include <afs/cellconfig.h>
#include <afs/keys.h>
#include <ubik.h>
#endif
#include <afs/vnode.h>
#include <afs/volume.h>
+#include <afs/volume_inline.h>
#include <afs/partition.h>
#include "vol.h"
+#include <afs/daemon_com.h>
#include <afs/fssync.h>
#include <afs/acl.h>
#include "afs/audit.h"
*error = EINVAL;
return NULL;
}
- tv = VAttachVolumeByName(error, pbuf, vbuf, amode);
+ tv = VAttachVolumeByName((Error *)error, pbuf, vbuf, amode);
return tv;
}
struct acl_accessList *ACL;
ViceFid did;
Inode inodeNumber, nearInode;
- char buf[SIZEOF_LARGEDISKVNODE];
- struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf;
+ struct VnodeDiskObject *vnode;
struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge];
IHandle_t *h;
FdHandle_t *fdP;
int code;
afs_fsize_t length;
+ vnode = (struct VnodeDiskObject *)malloc(SIZEOF_LARGEDISKVNODE);
memset(vnode, 0, SIZEOF_LARGEDISKVNODE);
V_pref(vp, nearInode);
VNDISK_GET_LEN(length, vnode);
V_diskused(vp) = nBlocks(length);
+ free(vnode);
return 1;
}
strcpy(tt->lastProcName, "DeleteVolume");
tt->rxCallPtr = acid;
VPurgeVolume(&error, tt->volume); /* don't check error code, it is not set! */
+ V_destroyMe(tt->volume) = DESTROY_ME; /* so endtrans does the right fssync opcode */
tt->vflags |= VTDeleted; /* so we know not to do anything else to it */
tt->rxCallPtr = (struct rx_call *)0;
if (TRELE(tt))
{
struct DiskPartition *tpartp = originalvp->partition;
- FSYNC_askfs(cloneId, tpartp->name, FSYNC_RESTOREVOLUME, 0);
+ FSYNC_VolOp(cloneId, tpartp->name, FSYNC_VOL_BREAKCBKS, 0, NULL);
}
return 0;
}
VUpdateVolume(&error, vp);
tt->vflags = aflags;
- tt->rxCallPtr = (struct rx_call *)0;
if (TRELE(tt) && !error)
return VOLSERTRELE_ERROR;
vp = tt->volume;
strcpy(tt->lastProcName, "ForwardMulti");
- /* (fromDate == 0) ==> incremental dump */
+ /* (fromDate == 0) ==> full dump */
is_incremental = (fromDate ? 1 : 0);
i = results->manyResults_len = destinations->manyDests_len;
{
afs_int32 code;
- code = VolDump(acid, fromTrans, fromDate);
+ code = VolDump(acid, fromTrans, fromDate, 0);
+ osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
+ return code;
+}
+
+afs_int32
+SAFSVolDumpV2(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
+{
+ afs_int32 code;
+
+ code = VolDump(acid, fromTrans, fromDate, flags);
osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
return code;
}
afs_int32
-VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate)
+VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
{
int code = 0;
register struct volser_trans *tt;
}
strcpy(tt->lastProcName, "Dump");
tt->rxCallPtr = acid;
- code = DumpVolume(acid, tt->volume, fromDate, 1); /* squirt out the volume's data, too */
+ code = DumpVolume(acid, tt->volume, fromDate, (flags & VOLDUMPV2_OMITDIRS)
+ ? 0 : 1); /* squirt out the volume's data, too */
if (code) {
tt->rxCallPtr = (struct rx_call *)0;
TRELE(tt);
DFlushVolume(V_parentId(tt->volume)); /* Ensure dir buffers get dropped */
code = RestoreVolume(acid, tt->volume, (aflags & 1), cookie); /* last is incrementalp */
- FSYNC_askfs(tt->volid, NULL, FSYNC_RESTOREVOLUME, 0l); /*break call backs on the
- * restored volume */
+ FSYNC_VolOp(tt->volid, NULL, FSYNC_VOL_BREAKCBKS, 0l, NULL);
tt->rxCallPtr = (struct rx_call *)0;
tcode = TRELE(tt);
}
strcpy(tt->lastProcName, "SetForwarding");
tt->rxCallPtr = acid;
- FSYNC_askfs(tt->volid, NULL, FSYNC_MOVEVOLUME, anewsite);
+ FSYNC_VolOp(tt->volid, NULL, FSYNC_VOL_MOVE, anewsite, NULL);
tt->rxCallPtr = (struct rx_call *)0;
if (TRELE(tt))
return VOLSERTRELE_ERROR;
namehead[7] = '\0';
for (i = 0; i < 26; i++) {
namehead[6] = i + 'a';
- if (VGetPartition(namehead, 0))
- partIds->partIds[i] = VGetPartition(namehead, 0) ? i : -1;
+ partIds->partIds[i] = VGetPartition(namehead, 0) ? i : -1;
}
return 0;
/* Only report attached partitions */
for (i = 0; i < VOLMAXPARTS; i++) {
+#ifdef AFS_DEMAND_ATTACH_FS
+ dp = VGetPartitionById(i, 0);
+#else
if (i < 26) {
namehead[6] = i + 'a';
namehead[7] = '\0';
namehead[8] = '\0';
}
dp = VGetPartition(namehead, 0);
+#endif
if (dp)
partList.partId[j++] = i;
}
}
+/**
+ * volint vol info structure type.
+ */
+typedef enum {
+ VOLINT_INFO_TYPE_BASE, /**< volintInfo type */
+ VOLINT_INFO_TYPE_EXT /**< volintXInfo type */
+} volint_info_type_t;
+
+/**
+ * handle to various on-wire vol info types.
+ */
+typedef struct {
+ volint_info_type_t volinfo_type;
+ union {
+ void * opaque;
+ volintInfo * base;
+ volintXInfo * ext;
+ } volinfo_ptr;
+} volint_info_handle_t;
+
+/**
+ * store value to a field at the appropriate location in on-wire structure.
+ */
+#define VOLINT_INFO_STORE(handle, name, val) \
+ do { \
+ if ((handle)->volinfo_type == VOLINT_INFO_TYPE_BASE) { \
+ (handle)->volinfo_ptr.base->name = (val); \
+ } else { \
+ (handle)->volinfo_ptr.ext->name = (val); \
+ } \
+ } while(0)
+
+/**
+ * get pointer to appropriate offset of field in on-wire structure.
+ */
+#define VOLINT_INFO_PTR(handle, name) \
+ (((handle)->volinfo_type == VOLINT_INFO_TYPE_BASE) ? \
+ &((handle)->volinfo_ptr.base->name) : \
+ &((handle)->volinfo_ptr.ext->name))
+
+/**
+ * fill in appropriate type of on-wire volume metadata structure.
+ *
+ * @param vp pointer to volume object
+ * @param hdr pointer to volume disk data object
+ * @param handle pointer to wire format handle object
+ *
+ * @pre handle object must have a valid pointer and enumeration value
+ *
+ * @return operation status
+ * @retval 0 success
+ * @retval 1 failure
+ */
+static int
+FillVolInfo(Volume * vp, VolumeDiskData * hdr, volint_info_handle_t * handle)
+{
+ unsigned int numStatBytes, now;
+
+ /*read in the relevant info */
+ strcpy(VOLINT_INFO_PTR(handle, name), hdr->name);
+ VOLINT_INFO_STORE(handle, status, VOK); /*its ok */
+ VOLINT_INFO_STORE(handle, volid, hdr->id);
+ VOLINT_INFO_STORE(handle, type, hdr->type); /*if ro volume */
+ VOLINT_INFO_STORE(handle, cloneID, hdr->cloneId); /*if rw volume */
+ VOLINT_INFO_STORE(handle, backupID, hdr->backupId);
+ VOLINT_INFO_STORE(handle, parentID, hdr->parentId);
+ VOLINT_INFO_STORE(handle, copyDate, hdr->copyDate);
+ VOLINT_INFO_STORE(handle, size, hdr->diskused);
+ VOLINT_INFO_STORE(handle, maxquota, hdr->maxquota);
+ VOLINT_INFO_STORE(handle, filecount, hdr->filecount);
+ now = FT_ApproxTime();
+ if ((now - hdr->dayUseDate) > OneDay) {
+ VOLINT_INFO_STORE(handle, dayUse, 0);
+ } else {
+ VOLINT_INFO_STORE(handle, dayUse, hdr->dayUse);
+ }
+ VOLINT_INFO_STORE(handle, creationDate, hdr->creationDate);
+ VOLINT_INFO_STORE(handle, accessDate, hdr->accessDate);
+ VOLINT_INFO_STORE(handle, updateDate, hdr->updateDate);
+ VOLINT_INFO_STORE(handle, backupDate, hdr->backupDate);
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ /*
+ * for DAFS, we "lie" about volume state --
+ * instead of returning the raw state from the disk header,
+ * we compute state based upon the fileserver's internal
+ * in-core state enumeration value reported to us via fssync,
+ * along with the blessed and inService flags from the header.
+ * -- tkeiser 11/27/2007
+ */
+ if ((V_attachState(vp) == VOL_STATE_UNATTACHED) ||
+ VIsErrorState(V_attachState(vp)) ||
+ !hdr->inService ||
+ !hdr->blessed) {
+ VOLINT_INFO_STORE(handle, inUse, 0);
+ } else {
+ VOLINT_INFO_STORE(handle, inUse, 1);
+ }
+#else
+ VOLINT_INFO_STORE(handle, inUse, hdr->inUse);
+#endif
+
+
+ switch(handle->volinfo_type) {
+ case VOLINT_INFO_TYPE_BASE:
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ /* see comment above where we set inUse bit */
+ if (hdr->needsSalvaged || VIsErrorState(V_attachState(vp))) {
+ handle->volinfo_ptr.base->needsSalvaged = 1;
+ } else {
+ handle->volinfo_ptr.base->needsSalvaged = 0;
+ }
+#else
+ handle->volinfo_ptr.base->needsSalvaged = hdr->needsSalvaged;
+#endif
+ handle->volinfo_ptr.base->destroyMe = hdr->destroyMe;
+ handle->volinfo_ptr.base->spare0 = hdr->minquota;
+ handle->volinfo_ptr.base->spare1 =
+ (long)hdr->weekUse[0] +
+ (long)hdr->weekUse[1] +
+ (long)hdr->weekUse[2] +
+ (long)hdr->weekUse[3] +
+ (long)hdr->weekUse[4] +
+ (long)hdr->weekUse[5] +
+ (long)hdr->weekUse[6];
+ handle->volinfo_ptr.base->flags = 0;
+ handle->volinfo_ptr.base->spare2 = hdr->volUpdateCounter;
+ handle->volinfo_ptr.base->spare3 = 0;
+ break;
+
+
+ case VOLINT_INFO_TYPE_EXT:
+ numStatBytes =
+ 4 * ((2 * VOLINT_STATS_NUM_RWINFO_FIELDS) +
+ (4 * VOLINT_STATS_NUM_TIME_FIELDS));
+
+ /*
+ * Copy out the stat fields in a single operation.
+ */
+ if ((now - hdr->dayUseDate) > OneDay) {
+ memset((char *)&(handle->volinfo_ptr.ext->stat_reads[0]),
+ 0, numStatBytes);
+ } else {
+ memcpy((char *)&(handle->volinfo_ptr.ext->stat_reads[0]),
+ (char *)&(hdr->stat_reads[0]),
+ numStatBytes);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * get struct Volume out of the fileserver.
+ *
+ * @param[in] volumeId volumeId for which we want state information
+ * @param[out] vp pointer to Volume object
+ *
+ * @return operation status
+ * @retval 0 success
+ * @retval nonzero failure
+ */
+static int
+GetVolObject(afs_uint32 volumeId, Volume * vp)
+{
+ int code;
+ SYNC_response res;
+
+ res.hdr.response_len = sizeof(res.hdr);
+ res.payload.buf = vp;
+ res.payload.len = sizeof(*vp);
+
+ code = FSYNC_VolOp(volumeId,
+ "",
+ FSYNC_VOL_QUERY,
+ 0,
+ &res);
+
+ return code;
+}
+
+/**
+ * mode of volume list operation.
+ */
+typedef enum {
+ VOL_INFO_LIST_SINGLE, /**< performing a single volume list op */
+ VOL_INFO_LIST_MULTIPLE /**< performing a multi-volume list op */
+} vol_info_list_mode_t;
+
+/**
+ * abstract interface to populate wire-format volume metadata structures.
+ *
+ * @param[in] partId partition id
+ * @param[in] volumeId volume id
+ * @param[in] pname partition name
+ * @param[in] volname volume file name
+ * @param[in] handle handle to on-wire volume metadata object
+ * @param[in] mode listing mode
+ *
+ * @return operation status
+ * @retval 0 success
+ * @retval -2 DESTROY_ME flag is set
+ * @retval -1 general failure; some data filled in
+ * @retval -3 couldn't create vtrans; some data filled in
+ */
+static int
+GetVolInfo(afs_uint32 partId,
+ afs_uint32 volumeId,
+ char * pname,
+ char * volname,
+ volint_info_handle_t * handle,
+ vol_info_list_mode_t mode)
+{
+ int code = -1;
+ afs_int32 error;
+ struct volser_trans *ttc = NULL;
+ struct Volume fs_tv, *tv = NULL;
+
+ ttc = NewTrans(volumeId, partId);
+ if (!ttc) {
+ code = -3;
+ VOLINT_INFO_STORE(handle, status, VBUSY);
+ VOLINT_INFO_STORE(handle, volid, volumeId);
+ goto drop;
+ }
+
+ tv = VAttachVolumeByName(&error, pname, volname, V_PEEK);
+ if (error) {
+ Log("1 Volser: GetVolInfo: Could not attach volume %u (%s:%s) error=%d\n",
+ volumeId, pname, volname, error);
+ goto drop;
+ }
+
+ /*
+ * please note that destroyMe and needsSalvaged checks used to be ordered
+ * in the opposite manner for ListVolumes and XListVolumes. I think it's
+ * more correct to check destroyMe before needsSalvaged.
+ * -- tkeiser 11/28/2007
+ */
+
+ if (tv->header->diskstuff.destroyMe == DESTROY_ME) {
+ switch (mode) {
+ case VOL_INFO_LIST_MULTIPLE:
+ code = -2;
+ goto drop;
+
+ case VOL_INFO_LIST_SINGLE:
+ Log("1 Volser: GetVolInfo: Volume %u (%s:%s) will be destroyed on next salvage\n",
+ volumeId, pname, volname);
+
+ default:
+ goto drop;
+ }
+ }
+
+ if (tv->header->diskstuff.needsSalvaged) {
+ /*this volume will be salvaged */
+ Log("1 Volser: GetVolInfo: Volume %u (%s:%s) needs to be salvaged\n",
+ volumeId, pname, volname);
+ goto drop;
+ }
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ if (GetVolObject(volumeId, &fs_tv)) {
+ goto drop;
+ }
+#endif
+
+ /* ok, we have all the data we need; fill in the on-wire struct */
+ code = FillVolInfo(&fs_tv, &tv->header->diskstuff, handle);
+
+
+ drop:
+ if (code == -1) {
+ VOLINT_INFO_STORE(handle, status, 0);
+ strcpy(VOLINT_INFO_PTR(handle, name), volname);
+ VOLINT_INFO_STORE(handle, volid, volumeId);
+ }
+ if (tv) {
+ VDetachVolume(&error, tv);
+ tv = NULL;
+ if (error) {
+ VOLINT_INFO_STORE(handle, status, 0);
+ strcpy(VOLINT_INFO_PTR(handle, name), volname);
+ Log("1 Volser: GetVolInfo: Could not detach volume %u (%s:%s)\n",
+ volumeId, pname, volname);
+ }
+ }
+ if (ttc) {
+ DeleteTrans(ttc, 1);
+ ttc = NULL;
+ }
+ return code;
+}
+
+
/*return the header information about the <volid> */
afs_int32
SAFSVolListOneVolume(struct rx_call *acid, afs_int32 partid, afs_int32
volumeId, volEntries *volumeInfo)
{
volintInfo *pntr;
- register struct Volume *tv;
struct DiskPartition *partP;
- struct volser_trans *ttc;
char pname[9], volname[20];
afs_int32 error = 0;
DIR *dirp;
afs_int32 volid;
int found = 0;
unsigned int now;
+ int code;
+ volint_info_handle_t handle;
volumeInfo->volEntries_val = (volintInfo *) malloc(sizeof(volintInfo));
pntr = volumeInfo->volEntries_val;
dirp = opendir(VPartitionPath(partP));
if (dirp == NULL)
return VOLSERILLEGAL_PARTITION;
+
strcpy(volname, "");
- ttc = (struct volser_trans *)0;
- tv = (Volume *) 0; /* volume not attached */
while (strcmp(volname, "EOD") && !found) { /*while there are more volumes in the partition */
if (volid == volumeId) { /*copy other things too */
found = 1;
-#ifndef AFS_PTHREAD_ENV
- IOMGR_Poll(); /*make sure that the client doesnot time out */
-#endif
- ttc = NewTrans(volid, partid);
- if (!ttc) {
- pntr->status = VBUSY;
- pntr->volid = volid;
- goto drop;
- }
- tv = VAttachVolumeByName(&error, pname, volname, V_READONLY);
- if (error) {
- pntr->status = 0; /*things are messed up */
- strcpy(pntr->name, volname);
- pntr->volid = volid;
- Log("1 Volser: ListVolumes: Could not attach volume %u (%s:%s), error=%d\n", volid, pname, volname, error);
- goto drop;
- }
- if (tv->header->diskstuff.destroyMe == DESTROY_ME) {
- /*this volume will be salvaged */
- pntr->status = 0;
- strcpy(pntr->name, volname);
- pntr->volid = volid;
- Log("1 Volser: ListVolumes: Volume %u (%s) will be destroyed on next salvage\n", volid, volname);
- goto drop;
- }
-
- if (tv->header->diskstuff.needsSalvaged) {
- /*this volume will be salvaged */
- pntr->status = 0;
- strcpy(pntr->name, volname);
- pntr->volid = volid;
- Log("1 Volser: ListVolumes: Volume %u (%s) needs to be salvaged\n", volid, volname);
- goto drop;
- }
-
- /*read in the relevant info */
- pntr->status = VOK; /*its ok */
- pntr->volid = tv->header->diskstuff.id;
- strcpy(pntr->name, tv->header->diskstuff.name);
- pntr->type = tv->header->diskstuff.type; /*if ro volume */
- pntr->cloneID = tv->header->diskstuff.cloneId; /*if rw volume */
- pntr->backupID = tv->header->diskstuff.backupId;
- pntr->parentID = tv->header->diskstuff.parentId;
- pntr->copyDate = tv->header->diskstuff.copyDate;
- pntr->inUse = tv->header->diskstuff.inUse;
- pntr->size = tv->header->diskstuff.diskused;
- pntr->needsSalvaged = tv->header->diskstuff.needsSalvaged;
- pntr->destroyMe = tv->header->diskstuff.destroyMe;
- pntr->maxquota = tv->header->diskstuff.maxquota;
- pntr->filecount = tv->header->diskstuff.filecount;
- now = FT_ApproxTime();
- if (now - tv->header->diskstuff.dayUseDate > OneDay)
- pntr->dayUse = 0;
- else
- pntr->dayUse = tv->header->diskstuff.dayUse;
- pntr->creationDate = tv->header->diskstuff.creationDate;
- pntr->accessDate = tv->header->diskstuff.accessDate;
- pntr->updateDate = tv->header->diskstuff.updateDate;
- pntr->backupDate = tv->header->diskstuff.backupDate;
- pntr->spare0 = tv->header->diskstuff.minquota;
- pntr->spare1 =
- (long)tv->header->diskstuff.weekUse[0] +
- (long)tv->header->diskstuff.weekUse[1] +
- (long)tv->header->diskstuff.weekUse[2] +
- (long)tv->header->diskstuff.weekUse[3] +
- (long)tv->header->diskstuff.weekUse[4] +
- (long)tv->header->diskstuff.weekUse[5] +
- (long)tv->header->diskstuff.weekUse[6];
- pntr->spare2 = V_volUpCounter(tv);
- pntr->flags = pntr->spare3 = (long)0;
- VDetachVolume(&error, tv); /*free the volume */
- tv = (Volume *) 0;
- if (error) {
- pntr->status = 0; /*things are messed up */
- strcpy(pntr->name, volname);
- Log("1 Volser: ListVolumes: Could not detach volume %s\n",
- volname);
- goto drop;
- }
+ break;
}
+
GetNextVol(dirp, volname, &volid);
}
- drop:
- if (tv) {
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- }
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
+
+ if (found) {
+#ifndef AFS_PTHREAD_ENV
+ IOMGR_Poll(); /*make sure that the client does not time out */
+#endif
+
+ handle.volinfo_type = VOLINT_INFO_TYPE_BASE;
+ handle.volinfo_ptr.base = volumeInfo->volEntries_val;
+
+ code = GetVolInfo(partid,
+ volid,
+ pname,
+ volname,
+ &handle,
+ VOL_INFO_LIST_SINGLE);
}
closedir(dirp);
- if (found)
- return 0;
- else
- return ENODEV;
+ return (found) ? 0 : ENODEV;
}
/*------------------------------------------------------------------------
{ /*SAFSVolXListOneVolume */
volintXInfo *xInfoP; /*Ptr to the extended vol info */
- register struct Volume *tv; /*Volume ptr */
- struct volser_trans *ttc; /*Volume transaction ptr */
struct DiskPartition *partP; /*Ptr to partition */
char pname[9], volname[20]; /*Partition, volume names */
afs_int32 error; /*Error code */
- afs_int32 code; /*Return code */
DIR *dirp; /*Partition directory ptr */
afs_int32 currVolID; /*Current volume ID */
int found = 0; /*Did we find the volume we need? */
- struct VolumeDiskData *volDiskDataP; /*Ptr to on-disk volume data */
- int numStatBytes; /*Num stat bytes to copy per volume */
unsigned int now;
+ int code;
+ volint_info_handle_t handle;
/*
* Set up our pointers for action, marking our structure to hold exactly
if (dirp == NULL)
return (VOLSERILLEGAL_PARTITION);
+ strcpy(volname, "");
+
/*
* Sweep through the partition directory, looking for the desired entry.
* First, of course, figure out how many stat bytes to copy out of each
* volume.
*/
- numStatBytes =
- 4 * ((2 * VOLINT_STATS_NUM_RWINFO_FIELDS) +
- (4 * VOLINT_STATS_NUM_TIME_FIELDS));
- strcpy(volname, "");
- ttc = (struct volser_trans *)0; /*No transaction yet */
- tv = (Volume *) 0; /*Volume not yet attached */
-
while (strcmp(volname, "EOD") && !found) {
/*
* If this is not a volume, move on to the next entry in the
* doesn't time out) and to set up a transaction on the volume.
*/
found = 1;
-#ifndef AFS_PTHREAD_ENV
- IOMGR_Poll();
-#endif
- ttc = NewTrans(currVolID, a_partID);
- if (!ttc) {
- /*
- * Couldn't get a transaction on this volume; let our caller
- * know it's busy.
- */
- xInfoP->status = VBUSY;
- xInfoP->volid = currVolID;
- goto drop;
- }
-
- /*
- * Attach the volume, give up on the volume if we can't.
- */
- tv = VAttachVolumeByName(&error, pname, volname, V_READONLY);
- if (error) {
- xInfoP->status = 0; /*things are messed up */
- strcpy(xInfoP->name, volname);
- xInfoP->volid = currVolID;
- Log("1 Volser: XListOneVolume: Could not attach volume %u\n",
- currVolID);
- goto drop;
- }
-
- /*
- * Also bag out on this volume if it's been marked as needing a
- * salvage or to-be-destroyed.
- */
- volDiskDataP = &(tv->header->diskstuff);
- if (volDiskDataP->destroyMe == DESTROY_ME) {
- xInfoP->status = 0;
- strcpy(xInfoP->name, volname);
- xInfoP->volid = currVolID;
- Log("1 Volser: XListOneVolume: Volume %u will be destroyed on next salvage\n", currVolID);
- goto drop;
- }
+ break;
+ } /*Found desired volume */
- if (volDiskDataP->needsSalvaged) {
- xInfoP->status = 0;
- strcpy(xInfoP->name, volname);
- xInfoP->volid = currVolID;
- Log("1 Volser: XListOneVolume: Volume %u needs to be salvaged\n", currVolID);
- goto drop;
- }
+ GetNextVol(dirp, volname, &currVolID);
+ }
- /*
- * Pull out the desired info and stuff it into the area we'll be
- * returning to our caller.
- */
- strcpy(xInfoP->name, volDiskDataP->name);
- xInfoP->volid = volDiskDataP->id;
- xInfoP->type = volDiskDataP->type;
- xInfoP->backupID = volDiskDataP->backupId;
- xInfoP->parentID = volDiskDataP->parentId;
- xInfoP->cloneID = volDiskDataP->cloneId;
- xInfoP->status = VOK;
- xInfoP->copyDate = volDiskDataP->copyDate;
- xInfoP->inUse = volDiskDataP->inUse;
- xInfoP->creationDate = volDiskDataP->creationDate;
- xInfoP->accessDate = volDiskDataP->accessDate;
- xInfoP->updateDate = volDiskDataP->updateDate;
- xInfoP->backupDate = volDiskDataP->backupDate;
- now = FT_ApproxTime();
- if (now - volDiskDataP->dayUseDate > OneDay)
- xInfoP->dayUse = 0;
- else
- xInfoP->dayUse = volDiskDataP->dayUse;
- xInfoP->filecount = volDiskDataP->filecount;
- xInfoP->maxquota = volDiskDataP->maxquota;
- xInfoP->size = volDiskDataP->diskused;
+ if (found) {
+#ifndef AFS_PTHREAD_ENV
+ IOMGR_Poll();
+#endif
- /*
- * Copy out the stat fields in a single operation.
- */
- memcpy((char *)&(xInfoP->stat_reads[0]),
- (char *)&(volDiskDataP->stat_reads[0]), numStatBytes);
+ handle.volinfo_type = VOLINT_INFO_TYPE_EXT;
+ handle.volinfo_ptr.ext = a_volumeXInfoP->volXEntries_val;
- /*
- * We're done copying. Detach the volume and iterate (at this
- * point, since we found our volume, we'll then drop out of the
- * loop).
- */
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- if (error) {
- xInfoP->status = 0;
- strcpy(xInfoP->name, volname);
- Log("1 Volser: XListOneVolumes Couldn't detach volume %s\n",
- volname);
- goto drop;
- }
+ code = GetVolInfo(a_partID,
+ a_volID,
+ pname,
+ volname,
+ &handle,
+ VOL_INFO_LIST_SINGLE);
- /*
- * At this point, we're golden.
- */
- code = 0;
- } /*Found desired volume */
- GetNextVol(dirp, volname, &currVolID);
- }
-
- /*
- * Drop the transaction we have for this volume.
- */
- drop:
- if (tv) {
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- }
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
}
/*
* return the proper value.
*/
closedir(dirp);
- return (code);
-
+ return (found) ? 0 : ENODEV;
} /*SAFSVolXListOneVolume */
/*returns all the volumes on partition partid. If flags = 1 then all the
volEntries *volumeInfo)
{
volintInfo *pntr;
- register struct Volume *tv;
struct DiskPartition *partP;
- struct volser_trans *ttc;
afs_int32 allocSize = 1000; /*to be changed to a larger figure */
char pname[9], volname[20];
afs_int32 error = 0;
DIR *dirp;
afs_int32 volid;
unsigned int now;
+ int code;
+ volint_info_handle_t handle;
volumeInfo->volEntries_val =
(volintInfo *) malloc(allocSize * sizeof(volintInfo));
if (dirp == NULL)
return VOLSERILLEGAL_PARTITION;
strcpy(volname, "");
+
while (strcmp(volname, "EOD")) { /*while there are more partitions in the partition */
- ttc = (struct volser_trans *)0; /* new one for each pass */
- tv = (Volume *) 0; /* volume not attached */
if (!strcmp(volname, "")) { /* its not a volume, fetch next file */
GetNextVol(dirp, volname, &volid);
if (flags) { /*copy other things too */
#ifndef AFS_PTHREAD_ENV
- IOMGR_Poll(); /*make sure that the client doesnot time out */
+ IOMGR_Poll(); /*make sure that the client does not time out */
#endif
- ttc = NewTrans(volid, partid);
- if (!ttc) {
- pntr->status = VBUSY;
- pntr->volid = volid;
- goto drop;
- }
- tv = VAttachVolumeByName(&error, pname, volname, V_PEEK);
- if (error) {
- pntr->status = 0; /*things are messed up */
- strcpy(pntr->name, volname);
- pntr->volid = volid;
- Log("1 Volser: ListVolumes: Could not attach volume %u (%s) error=%d\n", volid, volname, error);
- goto drop;
- }
- if (tv->header->diskstuff.needsSalvaged) {
- /*this volume will be salvaged */
- pntr->status = 0;
- strcpy(pntr->name, volname);
- pntr->volid = volid;
- Log("1 Volser: ListVolumes: Volume %u (%s) needs to be salvaged\n", volid, volname);
- goto drop;
- }
- if (tv->header->diskstuff.destroyMe == DESTROY_ME) {
- /*this volume will be salvaged */
+ handle.volinfo_type = VOLINT_INFO_TYPE_BASE;
+ handle.volinfo_ptr.base = pntr;
+
+
+ code = GetVolInfo(partid,
+ volid,
+ pname,
+ volname,
+ &handle,
+ VOL_INFO_LIST_MULTIPLE);
+ if (code == -2) { /* DESTROY_ME flag set */
goto drop2;
}
- /*read in the relevant info */
- pntr->status = VOK; /*its ok */
- pntr->volid = tv->header->diskstuff.id;
- strcpy(pntr->name, tv->header->diskstuff.name);
- pntr->type = tv->header->diskstuff.type; /*if ro volume */
- pntr->cloneID = tv->header->diskstuff.cloneId; /*if rw volume */
- pntr->backupID = tv->header->diskstuff.backupId;
- pntr->parentID = tv->header->diskstuff.parentId;
- pntr->copyDate = tv->header->diskstuff.copyDate;
- pntr->inUse = tv->header->diskstuff.inUse;
- pntr->size = tv->header->diskstuff.diskused;
- pntr->needsSalvaged = tv->header->diskstuff.needsSalvaged;
- pntr->maxquota = tv->header->diskstuff.maxquota;
- pntr->filecount = tv->header->diskstuff.filecount;
- now = FT_ApproxTime();
- if (now - tv->header->diskstuff.dayUseDate > OneDay)
- pntr->dayUse = 0;
- else
- pntr->dayUse = tv->header->diskstuff.dayUse;
- pntr->creationDate = tv->header->diskstuff.creationDate;
- pntr->accessDate = tv->header->diskstuff.accessDate;
- pntr->updateDate = tv->header->diskstuff.updateDate;
- pntr->backupDate = tv->header->diskstuff.backupDate;
- pntr->spare0 = tv->header->diskstuff.minquota;
- pntr->spare1 =
- (long)tv->header->diskstuff.weekUse[0] +
- (long)tv->header->diskstuff.weekUse[1] +
- (long)tv->header->diskstuff.weekUse[2] +
- (long)tv->header->diskstuff.weekUse[3] +
- (long)tv->header->diskstuff.weekUse[4] +
- (long)tv->header->diskstuff.weekUse[5] +
- (long)tv->header->diskstuff.weekUse[6];
- pntr->spare2 = V_volUpCounter(tv);
- pntr->flags = pntr->spare3 = (long)0;
- VDetachVolume(&error, tv); /*free the volume */
- tv = (Volume *) 0;
- if (error) {
- pntr->status = 0; /*things are messed up */
- strcpy(pntr->name, volname);
- Log("1 Volser: ListVolumes: Could not detach volume %s\n",
- volname);
- goto drop;
- }
} else {
pntr->volid = volid;
/*just volids are needed */
}
drop:
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
- }
pntr++;
volumeInfo->volEntries_len += 1;
if ((allocSize - volumeInfo->volEntries_len) < 5) {
(volintInfo *) realloc((char *)volumeInfo->volEntries_val,
allocSize * sizeof(volintInfo));
if (pntr == NULL) {
- if (tv) {
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- }
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
- }
- closedir(dirp);
+ closedir(dirp);
return VOLSERNO_MEMORY;
}
volumeInfo->volEntries_val = pntr; /* point to new block */
}
drop2:
- if (tv) {
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- }
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
- }
GetNextVol(dirp, volname, &volid);
}
- closedir(dirp);
- if (ttc)
- DeleteTrans(ttc, 1);
+ closedir(dirp);
return 0;
}
{ /*SAFSVolXListVolumes */
volintXInfo *xInfoP; /*Ptr to the extended vol info */
- register struct Volume *tv; /*Volume ptr */
struct DiskPartition *partP; /*Ptr to partition */
- struct volser_trans *ttc; /*Volume transaction ptr */
afs_int32 allocSize = 1000; /*To be changed to a larger figure */
char pname[9], volname[20]; /*Partition, volume names */
afs_int32 error = 0; /*Return code */
DIR *dirp; /*Partition directory ptr */
afs_int32 volid; /*Current volume ID */
- struct VolumeDiskData *volDiskDataP; /*Ptr to on-disk volume data */
- int numStatBytes; /*Num stat bytes to copy per volume */
unsigned int now;
+ int code;
+ volint_info_handle_t handle;
/*
* Allocate a large array of extended volume info structures, then
dirp = opendir(VPartitionPath(partP));
if (dirp == NULL)
return (VOLSERILLEGAL_PARTITION);
+ strcpy(volname, "");
/*
* Sweep through the partition directory, acting on each entry. First,
* of course, figure out how many stat bytes to copy out of each volume.
*/
- numStatBytes =
- 4 * ((2 * VOLINT_STATS_NUM_RWINFO_FIELDS) +
- (4 * VOLINT_STATS_NUM_TIME_FIELDS));
- strcpy(volname, "");
while (strcmp(volname, "EOD")) {
- ttc = (struct volser_trans *)0; /*New one for each pass */
- tv = (Volume *) 0; /*Volume not yet attached */
/*
* If this is not a volume, move on to the next entry in the
#ifndef AFS_PTHREAD_ENV
IOMGR_Poll();
#endif
- ttc = NewTrans(volid, a_partID);
- if (!ttc) {
- /*
- * Couldn't get a transaction on this volume; let our caller
- * know it's busy.
- */
- xInfoP->status = VBUSY;
- xInfoP->volid = volid;
- goto drop;
- }
-
- /*
- * Attach the volume, give up on this volume if we can't.
- */
- tv = VAttachVolumeByName(&error, pname, volname, V_PEEK);
- if (error) {
- xInfoP->status = 0; /*things are messed up */
- strcpy(xInfoP->name, volname);
- xInfoP->volid = volid;
- Log("1 Volser: XListVolumes: Could not attach volume %u\n",
- volid);
- goto drop;
- }
- /*
- * Also bag out on this volume if it's been marked as needing a
- * salvage or to-be-destroyed.
- */
- volDiskDataP = &(tv->header->diskstuff);
- if (volDiskDataP->needsSalvaged) {
- xInfoP->status = 0;
- strcpy(xInfoP->name, volname);
- xInfoP->volid = volid;
- Log("1 Volser: XListVolumes: Volume %u needs to be salvaged\n", volid);
- goto drop;
- }
+ handle.volinfo_type = VOLINT_INFO_TYPE_EXT;
+ handle.volinfo_ptr.ext = xInfoP;
- if (volDiskDataP->destroyMe == DESTROY_ME)
+ code = GetVolInfo(a_partID,
+ volid,
+ pname,
+ volname,
+ &handle,
+ VOL_INFO_LIST_MULTIPLE);
+ if (code == -2) { /* DESTROY_ME flag set */
goto drop2;
-
- /*
- * Pull out the desired info and stuff it into the area we'll be
- * returning to our caller.
- */
- strcpy(xInfoP->name, volDiskDataP->name);
- xInfoP->volid = volDiskDataP->id;
- xInfoP->type = volDiskDataP->type;
- xInfoP->backupID = volDiskDataP->backupId;
- xInfoP->parentID = volDiskDataP->parentId;
- xInfoP->cloneID = volDiskDataP->cloneId;
- xInfoP->status = VOK;
- xInfoP->copyDate = volDiskDataP->copyDate;
- xInfoP->inUse = volDiskDataP->inUse;
- xInfoP->creationDate = volDiskDataP->creationDate;
- xInfoP->accessDate = volDiskDataP->accessDate;
- xInfoP->updateDate = volDiskDataP->updateDate;
- xInfoP->backupDate = volDiskDataP->backupDate;
- now = FT_ApproxTime();
- if (now - volDiskDataP->dayUseDate > OneDay)
- xInfoP->dayUse = 0;
- else
- xInfoP->dayUse = volDiskDataP->dayUse;
- xInfoP->filecount = volDiskDataP->filecount;
- xInfoP->maxquota = volDiskDataP->maxquota;
- xInfoP->size = volDiskDataP->diskused;
-
- /*
- * Copy out the stat fields in a single operation.
- */
- memcpy((char *)&(xInfoP->stat_reads[0]),
- (char *)&(volDiskDataP->stat_reads[0]), numStatBytes);
-
- /*
- * We're done copying. Detach the volume and iterate.
- */
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- if (error) {
- xInfoP->status = 0;
- strcpy(xInfoP->name, volname);
- Log("1 Volser: XListVolumes: Could not detach volume %s\n",
- volname);
- goto drop;
}
- } /*Full contents desired */
- else
+ } else {
/*
* Just volume IDs are needed.
*/
xInfoP->volid = volid;
-
- drop:
- /*
- * Drop the transaction we have for this volume.
- */
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
}
+ drop:
/*
* Bump the pointer in the data area we're building, along with
* the count of the number of entries it contains.
/*
* Bummer, no memory. Bag it, tell our caller what went wrong.
*/
- if (tv) {
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- }
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
- }
closedir(dirp);
return (VOLSERNO_MEMORY);
}
a_volumeXInfoP->volXEntries_val +
a_volumeXInfoP->volXEntries_len;
}
- /*Need more space */
+
drop2:
- /*
- * Detach our current volume and the transaction on it, then move on
- * to the next volume in the partition directory.
- */
- if (tv) {
- VDetachVolume(&error, tv);
- tv = (Volume *) 0;
- }
- if (ttc) {
- DeleteTrans(ttc, 1);
- ttc = (struct volser_trans *)0;
- }
GetNextVol(dirp, volname, &volid);
} /*Sweep through the partition directory */
* delete our transaction (if any), and go home happy.
*/
closedir(dirp);
- if (ttc)
- DeleteTrans(ttc, 1);
return (0);
} /*SAFSVolXListVolumes */
return error;
}
-#ifdef AFS_NAMEI_ENV
-/*
- * Inode number format (from namei_ops.c):
- * low 26 bits - vnode number - all 1's if volume special file.
- * next 3 bits - tag
- * next 3 bits spare (0's)
- * high 32 bits - uniquifier (regular) or type if spare
- */
-#define NAMEI_VNODEMASK 0x003ffffff
-#define NAMEI_TAGMASK 0x7
-#define NAMEI_TAGSHIFT 26
-#define NAMEI_UNIQMASK 0xffffffff
-#define NAMEI_UNIQSHIFT 32
-#define NAMEI_INODESPECIAL ((Inode)NAMEI_VNODEMASK)
-#define NAMEI_VNODESPECIAL NAMEI_VNODEMASK
-#endif /* AFS_NAMEI_ENV */
-
afs_int32
SAFSVolConvertROtoRWvolume(struct rx_call *acid, afs_int32 partId,
afs_int32 volumeId)
{
-#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
+#ifdef AFS_NT40_ENV
+ return EXDEV;
+#else
+ char caller[MAXKTCNAMELEN];
DIR *dirp;
- char pname[16];
- char volname[20];
- afs_int32 error = 0;
+ register struct volser_trans *ttc;
+ char pname[16], volname[20];
+ struct DiskPartition *partP;
+ afs_int32 ret = ENODEV;
afs_int32 volid;
- int found = 0;
- char caller[MAXKTCNAMELEN];
- char headername[16];
- char opath[256];
- char npath[256];
- struct VolumeDiskHeader h;
- int fd;
- IHandle_t *ih;
- Inode ino;
- struct DiskPartition *dp;
if (!afsconf_SuperUser(tdir, acid, caller))
return VOLSERBAD_ACCESS; /*not a super user */
if (GetPartName(partId, pname))
- return VOLSERILLEGAL_PARTITION;
- dirp = opendir(pname);
+ return VOLSERILLEGAL_PARTITION;
+ if (!(partP = VGetPartition(pname, 0)))
+ return VOLSERILLEGAL_PARTITION;
+ dirp = opendir(VPartitionPath(partP));
if (dirp == NULL)
return VOLSERILLEGAL_PARTITION;
strcpy(volname, "");
+ ttc = (struct volser_trans *)0;
- while (strcmp(volname, "EOD") && !found) { /*while there are more volumes in the partition */
- GetNextVol(dirp, volname, &volid);
- if (strcmp(volname, "")) { /* its a volume */
- if (volid == volumeId)
- found = 1;
+ while (strcmp(volname, "EOD")) {
+ if (!strcmp(volname, "")) { /* its not a volume, fetch next file */
+ GetNextVol(dirp, volname, &volid);
+ continue; /*back to while loop */
+ }
+
+ if (volid == volumeId) { /*copy other things too */
+#ifndef AFS_PTHREAD_ENV
+ IOMGR_Poll(); /*make sure that the client doesnot time out */
+#endif
+ ttc = NewTrans(volumeId, partId);
+ if (!ttc) {
+ return VBUSY;
+ }
+#ifdef AFS_NAMEI_ENV
+ ret = namei_ConvertROtoRWvolume(pname, volumeId);
+#else
+ ret = inode_ConvertROtoRWvolume(pname, volumeId);
+#endif
+ break;
}
+ GetNextVol(dirp, volname, &volid);
}
- if (!found)
- return ENOENT;
- (void)afs_snprintf(headername, sizeof headername, VFORMAT, volumeId);
- (void)afs_snprintf(opath, sizeof opath, "%s/%s", pname, headername);
- fd = open(opath, O_RDONLY);
- if (fd < 0) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't open header for RO-volume %lu.\n", volumeId);
- return ENOENT;
- }
- if (read(fd, &h, sizeof(h)) != sizeof(h)) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't read header for RO-volume %lu.\n", volumeId);
- close(fd);
- return EIO;
- }
- close(fd);
- FSYNC_askfs(volumeId, pname, FSYNC_RESTOREVOLUME, 0);
-
- for (dp = DiskPartitionList; dp && strcmp(dp->name, pname);
- dp = dp->next);
- if (!dp) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't find DiskPartition for %s\n", pname);
- return EIO;
- }
- ino = namei_MakeSpecIno(h.parent, VI_LINKTABLE);
- IH_INIT(ih, dp->device, h.parent, ino);
-
- error = namei_ConvertROtoRWvolume(ih, volumeId);
- if (error)
- return error;
- h.id = h.parent;
- h.volumeInfo_hi = h.id;
- h.smallVnodeIndex_hi = h.id;
- h.largeVnodeIndex_hi = h.id;
- h.linkTable_hi = h.id;
- (void)afs_snprintf(headername, sizeof headername, VFORMAT, h.id);
- (void)afs_snprintf(npath, sizeof npath, "%s/%s", pname, headername);
- fd = open(npath, O_CREAT | O_EXCL | O_RDWR, 0644);
- if (fd < 0) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't create header for RW-volume %lu.\n", h.id);
- return EIO;
- }
- if (write(fd, &h, sizeof(h)) != sizeof(h)) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't write header for RW-volume %lu.\n", h.id);
- close(fd);
- return EIO;
- }
- close(fd);
- if (unlink(opath) < 0) {
- Log("1 SAFS_VolConvertROtoRWvolume: Couldn't unlink RO header, error = %d\n", error);
+
+ if (ttc) {
+ DeleteTrans(ttc, 1);
+ ttc = (struct volser_trans *)0;
}
- FSYNC_askfs(volumeId, pname, FSYNC_DONE, 0);
- FSYNC_askfs(h.id, pname, FSYNC_ON, 0);
- return 0;
-#else /* AFS_NAMEI_ENV */
- return EINVAL;
-#endif /* AFS_NAMEI_ENV */
+
+ closedir(dirp);
+ return ret;
+#endif
}
afs_int32