#include <afs/param.h>
#include <roken.h>
+#include <afs/opr.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <errno.h>
-#ifdef AFS_NT40_ENV
-#include <time.h>
-#include <fcntl.h>
-#else
-#include <sys/time.h>
+#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
-#include <unistd.h>
#endif
-#include <dirent.h>
-#include <sys/stat.h>
-#include <afs/afs_assert.h>
+#ifdef HAVE_SYS_LOCKF_H
+#include <sys/lockf.h>
+#endif
+
+#ifdef AFS_PTHREAD_ENV
+# include <opr/lock.h>
+#else
+# include <opr/lockstub.h>
+#endif
+
+#include <rx/rx_queue.h>
#include <rx/xdr.h>
#include <afs/afsint.h>
#include "nfs.h"
#include <afs/afsutil.h>
#ifdef AFS_NT40_ENV
#include "ntops.h"
-#include <io.h>
#endif
#include "vnode.h"
#include "volume.h"
#include "vol_prototypes.h"
#include "common.h"
-#ifdef AFS_AIX_ENV
-#include <sys/lockf.h>
-#endif
-#if defined(AFS_SUN5_ENV) || defined(AFS_NT40_ENV) || defined(AFS_LINUX20_ENV)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
#ifndef AFS_NT40_ENV
# ifdef O_LARGEFILE
# define AFS_SETLKW F_SETLKW64
#ifdef FSSYNC_BUILD_CLIENT
static void
-RemoveInodes(struct afs_inode_info *stuff, Device dev, VolumeId vid)
+RemoveInodes(struct afs_inode_info *stuff, Device dev, VolumeId parent,
+ VolumeId vid)
{
int i;
IHandle_t *handle;
/* This relies on the fact that IDEC only needs the device and NT only
* needs the dev and vid to decrement volume special files.
*/
- IH_INIT(handle, dev, vid, -1);
+ IH_INIT(handle, dev, parent, -1);
for (i = 0; i < MAXINODETYPE; i++) {
Inode inode = *stuff[i].inode;
- if (VALID_INO(inode))
- IH_DEC(handle, inode, vid);
+ if (VALID_INO(inode)) {
+ if (stuff[i].inodeType == VI_LINKTABLE) {
+ IH_DEC(handle, inode, parent);
+ } else {
+ IH_DEC(handle, inode, vid);
+ }
+ }
}
IH_RELEASE(handle);
}
Volume *
-VCreateVolume(Error * ec, char *partname, VolId volumeId, VolId parentId)
+VCreateVolume(Error * ec, char *partname, VolumeId volumeId, VolumeId parentId)
{ /* Should be the same as volumeId if there is
* no parent */
Volume *retVal;
}
Volume *
-VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
+VCreateVolume_r(Error * ec, char *partname, VolumeId volumeId, VolumeId parentId)
{ /* Should be the same as volumeId if there is
* no parent */
VolumeDiskData vol;
int i, rc;
- char headerName[VMAXPATHLEN], volumePath[VMAXPATHLEN];
+ char headerName[VMAXPATHLEN], volumePath[VMAXPATHLEN + 1];
Device device;
struct DiskPartition64 *partition;
struct VolumeDiskHeader diskHeader;
IHandle_t *handle;
FdHandle_t *fdP;
- Inode nearInode = 0;
+ Inode nearInode AFS_UNUSED = 0;
char *part, *name;
struct stat st;
struct VolumeHeader tempHeader;
if (*ec == VNOVOL || !strcmp(partition->name, part)) {
/* this case is ok */
} else {
- /* return EXDEV if it's a clone to an alternate partition
+ /* return EXDEV if it's a clone or read-only to an alternate partition
* otherwise assume it's a move */
if (vol.parentId != vol.id) {
+ Log("VCreateVolume: volume %" AFS_VOLID_FMT " for parent %" AFS_VOLID_FMT
+ " found on %s; unable to create volume on %s.\n",
+ afs_printable_VolumeId_lu(vol.id),
+ afs_printable_VolumeId_lu(vol.parentId), part, partition->name);
*ec = EXDEV;
return NULL;
}
vol.stamp.magic = VOLUMEINFOMAGIC;
vol.stamp.version = VOLUMEINFOVERSION;
vol.destroyMe = DESTROY_ME;
- (void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_printable_uint32_lu(vol.id));
- (void)afs_snprintf(volumePath, sizeof volumePath, "%s" OS_DIRSEP "%s",
- VPartitionPath(partition), headerName);
+ snprintf(headerName, sizeof headerName, VFORMAT,
+ afs_printable_VolumeId_lu(vol.id));
+ snprintf(volumePath, sizeof volumePath, "%s" OS_DIRSEP "%s",
+ VPartitionPath(partition), headerName);
rc = stat(volumePath, &st);
if (rc == 0 || errno != ENOENT) {
if (rc == 0) {
bad:
if (handle)
IH_RELEASE(handle);
- RemoveInodes(stuff, device, vol.id);
+ RemoveInodes(stuff, device, vol.parentId, vol.id);
if (!*ec) {
*ec = VNOVOL;
}
rc = VCreateVolumeDiskHeader(&diskHeader, partition);
if (rc) {
Log("VCreateVolume: Error %d trying to write volume header for "
- "volume %u on partition %s; volume not created\n", rc,
- vol.id, VPartitionPath(partition));
+ "volume %" AFS_VOLID_FMT " on partition %s; volume not created\n", rc,
+ afs_printable_VolumeId_lu(vol.id), VPartitionPath(partition));
if (rc == EEXIST) {
*ec = VVOLEXISTS;
}
vol->dayUseDate = 0;
}
+void
+CopyVolumeStats_r(VolumeDiskData * from, VolumeDiskData * to)
+{
+ memcpy(to->weekUse, from->weekUse, sizeof(to->weekUse));
+ to->dayUse = from->dayUse;
+ to->dayUseDate = from->dayUseDate;
+ if (from->stat_initialized) {
+ memcpy(to->stat_reads, from->stat_reads, sizeof(to->stat_reads));
+ memcpy(to->stat_writes, from->stat_writes, sizeof(to->stat_writes));
+ memcpy(to->stat_fileSameAuthor, from->stat_fileSameAuthor,
+ sizeof(to->stat_fileSameAuthor));
+ memcpy(to->stat_fileDiffAuthor, from->stat_fileDiffAuthor,
+ sizeof(to->stat_fileDiffAuthor));
+ memcpy(to->stat_dirSameAuthor, from->stat_dirSameAuthor,
+ sizeof(to->stat_dirSameAuthor));
+ memcpy(to->stat_dirDiffAuthor, from->stat_dirDiffAuthor,
+ sizeof(to->stat_dirDiffAuthor));
+ }
+}
+
+void
+CopyVolumeStats(VolumeDiskData * from, VolumeDiskData * to)
+{
+ VOL_LOCK;
+ CopyVolumeStats_r(from, to);
+ VOL_UNLOCK;
+}
+
/**
* read an existing volume disk header.
*
int fd;
char path[MAXPATHLEN];
- (void)afs_snprintf(path, sizeof(path),
- "%s" OS_DIRSEP VFORMAT,
- VPartitionPath(dp), afs_printable_uint32_lu(volid));
+ snprintf(path, sizeof(path), "%s" OS_DIRSEP VFORMAT,
+ VPartitionPath(dp), afs_printable_VolumeId_lu(volid));
fd = open(path, O_RDONLY);
if (fd < 0) {
- Log("VReadVolumeDiskHeader: Couldn't open header for volume %lu (errno %d).\n",
- afs_printable_uint32_lu(volid), errno);
+ Log("VReadVolumeDiskHeader: Couldn't open header for volume %" AFS_VOLID_FMT " (errno %d).\n",
+ afs_printable_VolumeId_lu(volid), errno);
code = -1;
} else if (hdr && read(fd, hdr, sizeof(*hdr)) != sizeof(*hdr)) {
- Log("VReadVolumeDiskHeader: Couldn't read header for volume %lu.\n",
- afs_printable_uint32_lu(volid));
+ Log("VReadVolumeDiskHeader: Couldn't read header for volume %" AFS_VOLID_FMT ".\n",
+ afs_printable_VolumeId_lu(volid));
code = EIO;
}
flags |= O_RDWR;
- (void)afs_snprintf(path, sizeof(path),
- "%s" OS_DIRSEP VFORMAT,
- VPartitionPath(dp), afs_printable_uint32_lu(hdr->id));
+ snprintf(path, sizeof(path), "%s" OS_DIRSEP VFORMAT,
+ VPartitionPath(dp), afs_printable_VolumeId_lu(hdr->id));
fd = open(path, flags, 0644);
if (fd < 0) {
code = errno;
* @return operation status
* @retval 0 success
*
- * @note if parent is 0, the parent volume ID will be looked up from the
- * fileserver
- *
* @note for non-DAFS, parent is currently ignored
*/
afs_int32
SYNC_response res;
#endif /* AFS_DEMAND_ATTACH_FS */
- (void)afs_snprintf(path, sizeof(path),
- "%s" OS_DIRSEP VFORMAT,
- VPartitionPath(dp), afs_printable_uint32_lu(volid));
+ snprintf(path, sizeof(path), "%s" OS_DIRSEP VFORMAT,
+ VPartitionPath(dp), afs_printable_VolumeId_lu(volid));
code = unlink(path);
if (code) {
Log("VDestroyVolumeDiskHeader: Couldn't unlink disk header, error = %d\n", errno);
}
#ifdef AFS_DEMAND_ATTACH_FS
+ /* Remove the volume entry from the fileserver's volume group cache, if found. */
memset(&res, 0, sizeof(res));
- if (!parent) {
- FSSYNC_VGQry_response_t q_res;
-
- code = FSYNC_VGCQuery(dp->name, volid, &q_res, &res);
- if (code) {
- Log("VDestroyVolumeDiskHeader: FSYNC_VGCQuery(%s, %lu) failed "
- "with code %ld, reason %ld\n", dp->name,
- afs_printable_uint32_lu(volid), afs_printable_int32_ld(code),
- afs_printable_int32_ld(res.hdr.reason));
- goto done;
- }
-
- parent = q_res.rw;
-
- }
code = FSYNC_VGCDel(dp->name, parent, volid, FSYNC_WHATEVER, &res);
if (code) {
- Log("VDestroyVolumeDiskHeader: FSYNC_VGCDel(%s, %lu, %lu) failed "
+ Log("VDestroyVolumeDiskHeader: FSYNC_VGCDel(%s, %" AFS_VOLID_FMT ", %" AFS_VOLID_FMT ") failed "
"with code %ld reason %ld\n", dp->name,
- afs_printable_uint32_lu(parent),
- afs_printable_uint32_lu(volid),
+ afs_printable_VolumeId_lu(parent),
+ afs_printable_VolumeId_lu(volid),
afs_printable_int32_ld(code),
afs_printable_int32_ld(res.hdr.reason));
}
VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
VWalkVolFunc volfunc, VWalkErrFunc errfunc, void *rock)
{
- DIR *dirp = NULL;
- struct dirent *dentry = NULL;
+ DIR *dirp;
+ struct dirent *dentry;
int code = 0;
struct VolumeDiskHeader diskHeader;
goto done;
}
- while ((dentry = readdir(dirp))) {
- char *p = dentry->d_name;
+ while ((dentry = readdir(dirp)) != NULL) {
+ char *p;
p = strrchr(dentry->d_name, '.');
if (p != NULL && strcmp(p, VHDREXT) == 0) {
char name[VMAXPATHLEN];
- sprintf(name, "%s" OS_DIRSEP "%s", partpath, dentry->d_name);
+ snprintf(name, VMAXPATHLEN, "%s" OS_DIRSEP "%s", partpath, dentry->d_name);
code = _VHandleVolumeHeader(dp, volfunc, name, &diskHeader, -1, rock);
if (code < 0) {
memset(lf, 0, sizeof(*lf));
lf->path = strdup(path);
lf->fd = INVALID_FD;
- MUTEX_INIT(&lf->mutex, "vlockfile", MUTEX_DEFAULT, 0);
+ opr_mutex_init(&lf->mutex);
}
#ifdef AFS_NT40_ENV
int cmd = AFS_SETLKW;
struct afs_st_flock sf;
+ opr_Assert(fd >= 0);
+
if (locktype == READ_LOCK) {
l_type = F_RDLCK;
}
void
VLockFileReinit(struct VLockFile *lf)
{
- MUTEX_ENTER(&lf->mutex);
+ opr_mutex_enter(&lf->mutex);
if (lf->fd != INVALID_FD) {
_VCloseFd(lf->fd);
lf->refcount = 0;
- MUTEX_EXIT(&lf->mutex);
+ opr_mutex_exit(&lf->mutex);
}
/**
{
int code;
- osi_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);
+ opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);
- MUTEX_ENTER(&lf->mutex);
+ opr_mutex_enter(&lf->mutex);
if (lf->fd == INVALID_FD) {
+ opr_Assert(lf->refcount == 0);
lf->fd = _VOpenPath(lf->path);
if (lf->fd == INVALID_FD) {
- MUTEX_EXIT(&lf->mutex);
+ opr_mutex_exit(&lf->mutex);
return EIO;
}
}
lf->refcount++;
- MUTEX_EXIT(&lf->mutex);
+ opr_Assert(lf->refcount > 0);
+
+ opr_mutex_exit(&lf->mutex);
code = _VLockFd(lf->fd, offset, locktype, nonblock);
if (code) {
- MUTEX_ENTER(&lf->mutex);
+ opr_mutex_enter(&lf->mutex);
+ opr_Assert(lf->refcount > 0);
if (--lf->refcount < 1) {
_VCloseFd(lf->fd);
lf->fd = INVALID_FD;
}
- MUTEX_EXIT(&lf->mutex);
+ opr_mutex_exit(&lf->mutex);
}
return code;
void
VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset)
{
- MUTEX_ENTER(&lf->mutex);
+ opr_mutex_enter(&lf->mutex);
- osi_Assert(lf->fd != INVALID_FD);
+ opr_Assert(lf->fd != INVALID_FD);
+ opr_Assert(lf->refcount > 0);
if (--lf->refcount < 1) {
_VCloseFd(lf->fd);
_VUnlockFd(lf->fd, offset);
}
- MUTEX_EXIT(&lf->mutex);
+ opr_mutex_exit(&lf->mutex);
}
#ifdef AFS_DEMAND_ATTACH_FS
void
VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf, afs_uint32 offset)
{
- osi_Assert(lf);
+ opr_Assert(lf);
memset(dl, 0, sizeof(*dl));
Lock_Init(&dl->rwlock);
- MUTEX_INIT(&dl->mutex, "disklock", MUTEX_DEFAULT, 0);
- CV_INIT(&dl->cv, "disklock cv", CV_DEFAULT, 0);
+ opr_mutex_init(&dl->mutex);
+ opr_cv_init(&dl->cv);
dl->lockfile = lf;
dl->offset = offset;
}
VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock)
{
int code = 0;
- osi_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);
+ opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);
if (nonblock) {
if (locktype == READ_LOCK) {
ObtainWriteLock(&dl->rwlock);
}
- MUTEX_ENTER(&dl->mutex);
+ opr_mutex_enter(&dl->mutex);
if ((dl->flags & VDISKLOCK_ACQUIRING)) {
/* Some other thread is waiting to acquire an fs lock. If nonblock=1,
code = EBUSY;
} else {
while ((dl->flags & VDISKLOCK_ACQUIRING)) {
- CV_WAIT(&dl->cv, &dl->mutex);
+ opr_cv_wait(&dl->cv, &dl->mutex);
}
}
}
/* mark that we are waiting on the fs lock */
dl->flags |= VDISKLOCK_ACQUIRING;
- MUTEX_EXIT(&dl->mutex);
+ opr_mutex_exit(&dl->mutex);
code = VLockFileLock(dl->lockfile, dl->offset, locktype, nonblock);
- MUTEX_ENTER(&dl->mutex);
+ opr_mutex_enter(&dl->mutex);
dl->flags &= ~VDISKLOCK_ACQUIRING;
dl->flags |= VDISKLOCK_ACQUIRED;
}
- CV_BROADCAST(&dl->cv);
+ opr_cv_broadcast(&dl->cv);
}
}
++dl->lockers;
}
- MUTEX_EXIT(&dl->mutex);
+ opr_mutex_exit(&dl->mutex);
return code;
}
void
VReleaseDiskLock(struct VDiskLock *dl, int locktype)
{
- osi_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);
+ opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);
- MUTEX_ENTER(&dl->mutex);
- osi_Assert(dl->lockers > 0);
+ opr_mutex_enter(&dl->mutex);
+ opr_Assert(dl->lockers > 0);
if (--dl->lockers < 1) {
/* no threads are holding this lock anymore, so we can release the
dl->flags &= ~VDISKLOCK_ACQUIRED;
}
- MUTEX_EXIT(&dl->mutex);
+ opr_mutex_exit(&dl->mutex);
if (locktype == READ_LOCK) {
ReleaseReadLock(&dl->rwlock);