/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* 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
#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
+#include <roken.h>
+
+#include <ctype.h>
#ifndef AFS_NAMEI_ENV
#if defined(AFS_LINUX20_ENV) || defined(AFS_SUN4_ENV)
* -2 - Unable to completely write temp file. Produces warning message in log.
*/
int
-ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (), int judgeParam, int *forcep, int forceR,
- char *wpath)
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
+ afs_uint32 (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
+ char *wpath, void *rock)
{
Log("ListViceInodes not implemented for this platform!\n");
return -1;
}
#else
-#include <ctype.h>
-#include <sys/param.h>
-#if defined(AFS_SGI_ENV)
-#else
+#if !defined(AFS_SGI_ENV)
#ifdef AFS_OSF_ENV
#include <ufs/fs.h>
#else /* AFS_OSF_ENV */
#endif
#endif /* AFS_VFSINCL_ENV */
#endif /* AFS_OSF_ENV */
-#include <sys/time.h>
#ifdef AFS_VFSINCL_ENV
#include <sys/vnode.h>
#ifdef AFS_SUN5_ENV
#endif
#endif
#else /* AFS_VFSINCL_ENV */
-#ifdef AFS_DEC_ENV
-#include <sys/time.h>
-#endif /* AFS_DEC_ENV */
#ifdef AFS_OSF_ENV
#include <ufs/inode.h>
#else /* AFS_OSF_ENV */
#endif /* AFS_SGI_ENV */
#include <afs/osi_inode.h>
#include <sys/file.h>
-#include <stdio.h>
#include <rx/xdr.h>
#include <afs/afsint.h>
#include "nfs.h"
#include <afs/afssyscalls.h>
#include "viceinode.h"
-#include <sys/stat.h>
#if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV)
#include <sys/ino.h>
#endif
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#if defined(AFS_HPUX101_ENV)
-#include <unistd.h>
-#endif
+#include <afs/afs_assert.h>
+
+#include "lock.h"
+#include "ihandle.h"
+#include "vnode.h"
+#include "volume.h"
+#include "volinodes.h"
#include "partition.h"
+#include "fssync.h"
+#include "volume_inline.h"
/* Notice: parts of this module have been cribbed from vfsck.c */
#define ROOTINODE 2
static char *partition;
-extern int Testing;
-int pfd;
+int Testing=0;
+FD_t pfd;
#ifdef AFS_AIX32_ENV
#include <jfs/filsys.h>
int
-ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (), int judgeParam, int *forcep, int forceR,
- char *wpath)
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
+ int (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
+ char *wpath, void *rock)
{
- FILE *inodeFile = NULL;
char dev[50], rdev[51];
struct stat status;
struct dinode *p;
struct stat root_inode;
int ninodes = 0, err = 0;
- pfd = -1; /* initialize so we don't close on error output below. */
+ pfd = INVALID_FD; /* initialize so we don't close on error output below. */
*forcep = 0;
sync();
sleep(1); /* simulate operator */
fmax = fs.s_fsize / (FSBSIZE / 512); /* first invalid blk num */
- pfd = open(rdev, O_RDONLY);
- if (pfd < 0) {
+ pfd = OS_OPEN(rdev, O_RDONLY, 0666);
+ if (pfd == INVALID_FD) {
Log("Unable to open `%s' inode for reading\n", rdev);
return -1;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- goto out;
- }
-
/*
* calculate the maximum number of inodes possible
*/
* LAST_RSVD_I is a vice inode, with dead beef, and
* di_nlink == 2 to indicate the FORCE.
*/
- assert(p = ginode(LAST_RSVD_I));
+ osi_Assert(p = ginode(LAST_RSVD_I));
if (p->di_vicemagic == VICEMAGIC && p->di_vicep1 == 0xdeadbeef
&& p->di_nlink == 2) {
info.u.param[2] = p->di_vicep3;
info.u.param[3] = p->di_vicep4;
- if (judgeInode && (*judgeInode) (&info, judgeParam) == 0)
+ if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n", partition);
- goto out;
+ if (inodeFile != INVALID_FD) {
+ if (OS_WRITE(inodeFile, &info, sizeof(info)) != sizeof(info)) {
+ Log("Error writing inode file for partition %s\n", partition);
+ goto out;
+ }
}
++ninodes;
}
- if (fflush(inodeFile) == EOF) {
- Log("Unable to successfully flush inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
+ if (inodeFile != INVALID_FD) {
+ if (OS_SYNC(inodeFile) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (status.st_size != ninodes * sizeof(struct ViceInodeInfo)) {
- Log("Wrong size (%d instead of %d) in inode file for %s\n",
- status.st_size, ninodes * sizeof(struct ViceInodeInfo),
- partition);
- err = -2;
- goto out1;
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (OS_SIZE(inodeFile) != ninodes * sizeof(struct ViceInodeInfo)) {
+ Log("Wrong size (%d instead of %d) in inode file for %s\n",
+ status.st_size, ninodes * sizeof(struct ViceInodeInfo),
+ partition);
+ err = -2;
+ goto out1;
+ }
}
- close(pfd);
+ OS_CLOSE(pfd);
return 0;
out:
err = -1;
out1:
- if (pfd >= 0)
- close(pfd);
- if (inodeFile)
- fclose(inodeFile);
+ if (pfd != INVALID_FD)
+ OS_CLOSE(pfd);
return err;
}
int
ReadSuper(struct superblock *fs, char *devName)
{
- int pfd;
+ FD_t pfd;
- pfd = open(devName, O_RDONLY);
- if (pfd < 0) {
+ pfd = OS_OPEN(devName, O_RDONLY, 0666);
+ if (pfd == INVALID_FD) {
Log("Unable to open inode on %s for reading superblock.\n", devName);
return -1;
}
Log("Unable to read superblock on %s.\n", devName);
return -1;
}
- close(pfd);
+ OS_CLOSE(pfd);
return (0);
}
/* libefs.h includes <assert.h>, which we don't want */
#define __ASSERT_H__
-#ifdef AFS_SGI_EFS_IOPS_ENV
-#include "sgiefs/libefs.h"
-extern int Log();
-
-/* afs_efs_figet() replaces the SGI library routine because we are malloc'ing
- * memory for all the inodes on all the cylinder groups without releasing
- * it when we're done. Using afs_efs_figet ensures more efficient use of
- * memory.
- */
-struct efs_dinode *
-afs_efs_figet(EFS_MOUNT * mp, struct efs_dinode *dinodeBuf, int *last_cgno,
- ino_t inum)
-{
- int cgno = EFS_ITOCG(mp->m_fs, inum);
-
-
- if (cgno != *last_cgno) {
- if (efs_readb
- (mp->m_fd, (char *)dinodeBuf, EFS_CGIMIN(mp->m_fs, cgno),
- mp->m_fs->fs_cgisize) != mp->m_fs->fs_cgisize) {
- Log("Unable to read inodes for cylinder group %d.\n", cgno);
- return NULL;
- }
- *last_cgno = cgno;
- }
-
- return dinodeBuf + (inum % (mp->m_fs->fs_cgisize * EFS_INOPBB));
-}
-
-
-int
-efs_ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (), int judgeParam, int *forcep,
- int forceR, char *wpath)
-{
- FILE *inodeFile = NULL;
- char dev[50], rdev[51];
- struct stat status;
- struct efs_dinode *p;
- struct ViceInodeInfo info;
- int ninodes = 0, err = 0;
- struct efs_dinode *dinodeBuf = NULL;
- int last_cgno;
- EFS_MOUNT *mp;
- ino_t imax, inum; /* total number of I-nodes in file system */
-
- *forcep = 0;
-
- partition = mountedOn;
- sprintf(dev, "/dev/dsk/%s", devname);
- sprintf(rdev, "/dev/rdsk/%s", devname);
-
-
- /*
- * open raw device
- */
- efs_init(Log);
- if ((stat(rdev, &status) == -1)
- || ((mp = efs_mount(rdev, O_RDONLY)) == NULL)) {
- sprintf(rdev, "/dev/r%s", devname);
- mp = efs_mount(rdev, O_RDONLY);
- }
- if (mp == NULL) {
- Log("Unable to open `%s' inode for reading\n", rdev);
- return -1;
- }
-
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- goto out;
- }
-
- /* Allocate space for one cylinder group's worth of inodes. */
- dinodeBuf = (struct efs_dinode *)malloc(mp->m_fs->fs_cgisize * BBSIZE);
- if (!dinodeBuf) {
- Log("Unable to malloc %lu bytes for inode buffer.\n",
- mp->m_fs->fs_cgisize * BBSIZE);
- goto out;
- }
-
- /*
- * calculate the maximum number of inodes possible
- */
- imax = mp->m_fs->fs_ncg * mp->m_fs->fs_ipcg;
-
- last_cgno = -1;
- for (inum = 2; inum < imax; ++inum) {
- p = afs_efs_figet(mp, dinodeBuf, &last_cgno, inum);
- if (!p) {
- Log("Unable to read all inodes from partition.\n");
- goto out;
- }
- if (!IS_DVICEMAGIC(p) || !((p->di_mode & IFMT) == IFREG)) {
- continue;
- }
-#if defined(AFS_SGI_EXMAG)
- /* volume ID */
- info.u.param[0] =
- dmag(p, 0) << 24 | dmag(p, 1) << 16 | dmag(p, 2) << 8 | dmag(p,
- 3) <<
- 0;
- if ((p)->di_version == EFS_IVER_AFSSPEC) {
- info.u.param[1] = INODESPECIAL;
- /* type */
- info.u.param[2] = dmag(p, 8);
- /* parentId */
- info.u.param[3] =
- dmag(p, 4) << 24 | dmag(p, 5) << 16 | dmag(p,
- 6) << 8 | dmag(p,
- 7)
- << 0;
- } else {
- /* vnode number */
- info.u.param[1] =
- dmag(p, 4) << 16 | dmag(p, 5) << 8 | dmag(p, 6) << 0;
- /* disk uniqifier */
- info.u.param[2] =
- dmag(p, 7) << 16 | dmag(p, 8) << 8 | dmag(p, 9) << 0;
- /* data version */
- info.u.param[3] =
- dmag(p, 10) << 16 | dmag(p, 11) << 8 | (p)->di_spare;
- }
-#else
- BOMB ! !
-#endif
- info.inodeNumber = inum;
- info.byteCount = p->di_size;
- info.linkCount = p->di_nlink;
-#ifdef notdef
- Log("Ino=%d, bytes=%d, linkCnt=%d, [%x,%x,%x,%x]\n", inum, p->di_size,
- p->di_nlink, info.u.param[0], info.u.param[1], info.u.param[2],
- info.u.param[3]);
-#endif
- if (judgeInode && (*judgeInode) (&info, judgeParam) == 0)
- continue;
-
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n", partition);
- goto out;
- }
- ++ninodes;
- }
-
- if (fflush(inodeFile) == EOF) {
- Log("Unable to successfully flush inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
-
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (status.st_size != ninodes * sizeof(struct ViceInodeInfo)) {
- Log("Wrong size (%d instead of %d) in inode file for %s\n",
- status.st_size, ninodes * sizeof(struct ViceInodeInfo),
- partition);
- err = -2;
- goto out1;
- }
- efs_umount(mp);
- if (dinodeBuf) {
- free(dinodeBuf);
- }
- return 0;
-
- out:
- err = -1;
- out1:
- if (dinodeBuf) {
- free(dinodeBuf);
- }
- efs_umount(mp);
- if (inodeFile)
- fclose(inodeFile);
-
- return err;
-}
-#endif /* AFS_SGI_EFS_IOPS_ENV */
-
#ifdef AFS_SGI_XFS_IOPS_ENV
#include <dirent.h>
#include <afs/xfsattrs.h>
/* xfs_ListViceInodes
*
* xfs_ListViceInodes verifies and correct the XFS namespace as it collects
- * the inode information. The name is required for the idec operation to work.
+ * the inode information. The name is required for the idec operation to work.
* Steps 2 and 3 below are for the AFS_XFS_NAME_VERS == 1. If the name space
- * changes, the algorithm will need to change.
+ * changes, the algorithm will need to change.
* 1) If the parent inode number does not match the directory's inod number,
* change it in the attribute.
* 2) If the unqifier in the attribute does not match the name, rename the
*/
/* xfs_VerifyInode
- *
+ *
* Does the verifications listed above.
* We can't change the names until the readdir is complete, so we set the
* rename flag if the file needs renaming.
char tmpName[32];
b64_string_t stmp;
int tag;
+ afs_ino_str_t stmp;
*rename = 0;
(void)sprintf(path, "%s/%s", dir, name);
if (info->ili_magic != XFS_VICEMAGIC) {
Log("%s magic for %s/%s (inode %s) from %d to %d\n",
Testing ? "Would have changed" : "Changing", dir, name,
- PrintInode(NULL, info->ili_info.inodeNumber), info->ili_magic,
+ PrintInode(stmp, info->ili_info.inodeNumber), info->ili_magic,
XFS_VICEMAGIC);
if (!Testing)
update_chown = 1;
if (info->ili_vno != AFS_XFS_VNO_CLIP(vno)) {
Log("%s volume id for %s/%s (inode %s) from %d to %d\n",
Testing ? "Would have changed" : "Changing", dir, name,
- PrintInode(NULL, info->ili_info.inodeNumber), info->ili_vno,
+ PrintInode(stmp, info->ili_info.inodeNumber), info->ili_vno,
AFS_XFS_VNO_CLIP(vno));
if (!Testing)
update_chown = 1;
if (strncmp(name, tmpName, strlen(tmpName))) {
Log("%s name %s (inode %s) in directory %s, unique=%d, tag=%d\n",
Testing ? "Would have returned bad" : "Bad", name,
- PrintInode(NULL, info->ili_info.inodeNumber), dir,
+ PrintInode(stmp, info->ili_info.inodeNumber), dir,
info->ili_info.param[2], info->ili_tag);
if (!Testing)
*rename = 1;
p = strchr(tmpName + 1, '.');
if (!p) {
Log("No tag found on name %s (inode %s)in directory, %s.\n",
- name, PrintInode(NULL, info->ili_info.inodeNumber), dir,
+ name, PrintInode(stmp, info->ili_info.inodeNumber), dir,
Testing ? "would have renamed" : "will rename");
if (!Testing)
*rename = 1;
tag = base64_to_int(p + 1);
Log("%s the tag for %s (inode %s) from %d to %d.\n",
Testing ? "Would have changed" : "Will change", path,
- PrintInode(NULL, info->ili_info.inodeNumber), dir, tag,
+ PrintInode(stmp, info->ili_info.inodeNumber), dir, tag,
info->ili_tag);
if (!Testing)
update_tag = 1;
int_to_base64(stmp, renames[i].uniq));
for (tag = 2, j = 0; j < 64; tag++, j++) {
(void)sprintf(npath, "%s.%s", nbase, int_to_base64(stmp, tag));
- fd = open(npath, O_CREAT | O_EXCL | O_RDWR, 0);
+ fd = afs_open(npath, O_CREAT | O_EXCL | O_RDWR, 0);
if (fd > 0) {
close(fd);
break;
int
-xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (), int judgeParam, int *forcep,
- int forceR, char *wpath)
+xfs_ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
+ int (*judgeInode) (), afs_uint32 judgeParam, int *forcep,
+ int forceR, char *wpath, void *rock)
{
- FILE *inodeFile = NULL;
i_list_inode_t info;
int info_size = sizeof(i_list_inode_t);
int fd;
int n_renames = 0;
int n_avail = 0;
uint64_t pino;
- struct stat status;
int errors = 0;
*forcep = 0;
return -1;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- return -1;
- }
-
if ((top_dirp = opendir(mountedOn)) == NULL) {
Log("Can't open directory %s to read inodes.\n", mountedOn);
return -1;
goto err1_exit;
}
- if (judgeInode && (*judgeInode) (&info.ili_info, judgeParam) == 0)
+ if (judgeInode && (*judgeInode) (&info.ili_info, judgeParam, rock) == 0)
continue;
rename = 0;
n_renames++;
}
- if (fwrite
- (&info.ili_info, sizeof(vice_inode_info_t), 1, inodeFile)
- != 1) {
- Log("Error writing inode file for partition %s\n", mountedOn);
- goto err1_exit;
+ if (inodeFile != INVALID_FD) {
+ if (OS_WRITE
+ (inodeFile, &info.ili_info, sizeof(vice_inode_info_t))
+ != sizeof(vice_inode_info_t)) {
+ Log("Error writing inode file for partition %s\n", mountedOn);
+ goto err1_exit;
+ }
}
ninodes++;
closedir(top_dirp);
if (renames)
free((char *)renames);
- if (fflush(inodeFile) == EOF) {
- ("Unable to successfully flush inode file for %s\n", mountedOn);
- fclose(inodeFile);
- return errors ? -1 : -2;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", mountedOn);
- fclose(inodeFile);
- return errors ? -1 : -2;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", mountedOn);
- return errors ? -1 : -2;
- }
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- return errors ? -1 : -2;
- }
- if (status.st_size != ninodes * sizeof(struct ViceInodeInfo)) {
- Log("Wrong size (%d instead of %d) in inode file for %s\n",
- status.st_size, ninodes * sizeof(struct ViceInodeInfo),
- partition);
- return errors ? -1 : -2;
+ if (inodeFile != INVALID_FD) {
+ if (OS_SYNC(inodeFile) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", mountedOn);
+ return errors ? -1 : -2;
+ }
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (OS_SIZE(inodeFile) != ninodes * sizeof(struct ViceInodeInfo)) {
+ Log("Wrong size (%d instead of %d) in inode file for %s\n",
+ OS_SIZE(inodeFile), ninodes * sizeof(struct ViceInodeInfo),
+ partition);
+ return errors ? -1 : -2;
+ }
}
if (errors) {
closedir(top_dirp);
if (renames)
free((char *)renames);
- if (inodeFile)
- fclose(inodeFile);
return -1;
}
#endif
int
-ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (), int judgeParam, int *forcep, int forceR,
- char *wpath)
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
+ int (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
+ char *wpath, void *rock)
{
- FILE *inodeFile = NULL;
char dev[50], rdev[51];
struct stat status;
struct efs_dinode *p;
int ninodes = 0, err = 0;
struct efs_dinode *dinodeBuf = NULL;
int last_cgno;
-#ifdef AFS_SGI_EFS_IOPS_ENV
- EFS_MOUNT *mp;
-#endif
ino_t imax, inum; /* total number of I-nodes in file system */
*forcep = 0;
}
#ifdef AFS_SGI_XFS_IOPS_ENV
if (!strcmp("xfs", root_inode.st_fstype)) {
- return xfs_ListViceInodes(devname, mountedOn, resultFile, judgeInode,
- judgeParam, forcep, forceR, wpath);
- } else
-#endif
-#ifdef AFS_SGI_EFS_IOPS_ENV
- if (root_inode.st_ino == EFS_ROOTINO) {
- return efs_ListViceInodes(devname, mountedOn, resultFile, judgeInode,
- judgeParam, forcep, forceR, wpath);
+ return xfs_ListViceInodes(devname, mountedOn, inodeFile, judgeInode,
+ judgeParam, forcep, forceR, wpath, rock);
} else
#endif
{
extern char *afs_rawname();
int
-ListViceInodes(char *devname, char *mountedOn, char *resultFile,
- int (*judgeInode) (), int judgeParam, int *forcep, int forceR,
- char *wpath)
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
+ int (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
+ char *wpath, void *rock)
{
union {
#ifdef AFS_AIX_ENV
#endif
} super;
int i, c, e, bufsize, code, err = 0;
- FILE *inodeFile = NULL;
char dev[50], rdev[100], err1[512], *ptr1;
struct dinode *inodes = NULL, *einodes, *dptr;
- struct stat status;
int ninodes = 0;
struct dinode *p;
struct ViceInodeInfo info;
sleep(10);
#endif
- pfd = open(rdev, O_RDONLY);
- if (pfd <= 0) {
+ pfd = OS_OPEN(rdev, O_RDONLY, 0666);
+ if (pfd == INVALID_FD) {
sprintf(err1, "Could not open device %s to get inode list\n", rdev);
perror(err1);
return -1;
goto out;
}
- inodeFile = fopen(resultFile, "w");
- if (inodeFile == NULL) {
- Log("Unable to create inode description file %s\n", resultFile);
- goto out;
- }
#ifdef AFS_AIX_ENV
/*
* char *FSlabel(), *fslabel=0;
info.u.param[1] = auxp->aux_param2;
info.u.param[2] = auxp->aux_param3;
info.u.param[3] = auxp->aux_param4;
- if (judgeInode && (*judgeInode) (&info, judgeParam) == 0)
+ if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n", partition);
- goto out;
+ if (inodeFile != INVALID_FD) {
+ if (OS_WRITE(inodeFile, &info, sizeof(info)) != sizeof(info)) {
+ Log("Error writing inode file for partition %s\n", partition);
+ goto out;
+ }
}
ninodes++;
}
i = c * sblock.fs_ipg;
e = i + sblock.fs_ipg;
#if defined(AFS_HPUX102_ENV)
- if (lseek(pfd, dbtoo(fsbtodb(&sblock, itod(&sblock, i))), L_SET) ==
+ if (OS_SEEK(pfd, dbtoo(fsbtodb(&sblock, itod(&sblock, i))), L_SET) ==
-1) {
#else
- if (lseek(pfd, dbtob(fsbtodb(&sblock, itod(&sblock, i))), L_SET) ==
+ if (OS_SEEK(pfd, dbtob(fsbtodb(&sblock, itod(&sblock, i))), L_SET) ==
-1) {
#endif
#else
e = i + super.fs.fs_ipg;
#ifdef AFS_OSF_ENV
dblk1 = fsbtodb(&super.fs, itod(&super.fs, i));
- if (lseek(pfd, (off_t) ((off_t) dblk1 * DEV_BSIZE), L_SET) == -1) {
+ if (OS_SEEK(pfd, (off_t) ((off_t) dblk1 * DEV_BSIZE), L_SET) == -1) {
#else
#if defined(AFS_SUN5_ENV) || defined(AFS_DARWIN_ENV)
f1 = fsbtodb(&super.fs, itod(&super.fs, i));
off = (offset_t) f1 << DEV_BSHIFT;
- if (llseek(pfd, off, L_SET) == -1) {
+ if (OS_SEEK(pfd, off, L_SET) == -1) {
#else
- if (lseek(pfd, dbtob(fsbtodb(&super.fs, itod(&super.fs, i))), L_SET)
+ if (OS_SEEK(pfd, dbtob(fsbtodb(&super.fs, itod(&super.fs, i))), L_SET)
== -1) {
#endif /* AFS_SUN5_ENV */
#endif /* AFS_OSF_ENV */
}
while (i < e) {
if (!forceR) {
- if (read(pfd, inodes, bufsize) != bufsize) {
+ if (OS_READ(pfd, inodes, bufsize) != bufsize) {
Log("Error reading inodes for partition %s; run vfsck\n",
partition);
goto out;
}
} else {
- register int bj, bk;
+ int bj, bk;
dptr = inodes;
for (bj = bk = 0; bj < bufsize; bj = bj + 512, bk++) {
- if ((code = read(pfd, dptr, 512)) != 512) {
+ if ((code = OS_READ(pfd, dptr, 512)) != 512) {
Log("Error reading inode %d? for partition %s (errno = %d); run vfsck\n", bk + i, partition, errno);
- if (lseek(pfd, 512, L_SET) == -1) {
- Log("Lseek failed\n");
+ if (OS_SEEK(pfd, 512, L_SET) == -1) {
+ Log("OS_SEEK failed\n");
goto out;
}
dptr->di_mode = 0;
goto out;
}
#else
- assert(0); /* define AFS_3DISPARES in param.h */
+ osi_Panic("Tru64 needs AFS_3DISPARES\n");
#endif
#endif
-#if defined(AFS_SUN56_ENV)
+#if defined(AFS_SUN5_ENV)
/* if this is a pre-sol2.6 unconverted inode, bail out */
{
afs_uint32 p1, p2, p3, p4;
info.inodeNumber = i;
info.byteCount = p->di_size;
info.linkCount = p->di_nlink;
- if (judgeInode && (*judgeInode) (&info, judgeParam) == 0)
+ if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
continue;
- if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
- Log("Error writing inode file for partition %s\n",
- partition);
- goto out;
+ if (inodeFile != INVALID_FD) {
+ if (OS_WRITE(inodeFile, &info, sizeof(info)) != sizeof(info)) {
+ Log("Error writing inode file for partition %s\n",
+ partition);
+ goto out;
+ }
}
ninodes++;
}
if (inodes)
free(inodes);
#endif
- if (fflush(inodeFile) == EOF) {
- Log("Unable to successfully flush inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fsync(fileno(inodeFile)) == -1) {
- Log("Unable to successfully fsync inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (fclose(inodeFile) == EOF) {
- Log("Unable to successfully close inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
+ if (inodeFile != INVALID_FD) {
+ if (OS_SYNC(inodeFile) == -1) {
+ Log("Unable to successfully fsync inode file for %s\n", partition);
+ err = -2;
+ goto out1;
+ }
- /*
- * Paranoia: check that the file is really the right size
- */
- if (stat(resultFile, &status) == -1) {
- Log("Unable to successfully stat inode file for %s\n", partition);
- err = -2;
- goto out1;
- }
- if (status.st_size != ninodes * sizeof(struct ViceInodeInfo)) {
- Log("Wrong size (%d instead of %d) in inode file for %s\n",
- status.st_size, ninodes * sizeof(struct ViceInodeInfo),
- partition);
- err = -2;
- goto out1;
+ /*
+ * Paranoia: check that the file is really the right size
+ */
+ if (OS_SIZE(inodeFile) != ninodes * sizeof(struct ViceInodeInfo)) {
+ Log("Wrong size (%d instead of %d) in inode file for %s\n",
+ OS_SIZE(inodeFile), ninodes * sizeof(struct ViceInodeInfo),
+ partition);
+ err = -2;
+ goto out1;
+ }
}
- close(pfd);
+ OS_CLOSE(pfd);
return 0;
out:
err = -1;
out1:
- close(pfd);
- if (inodeFile)
- fclose(inodeFile);
+ OS_CLOSE(pfd);
if (inodes)
free(inodes);
return err;
#endif
int
-bread(int fd, char *buf, daddr_t blk, afs_int32 size)
+bread(FD_t fd, char *buf, daddr_t blk, afs_int32 size)
{
#ifdef AFS_AIX_ENV
#ifdef AFS_AIX41_ENV
offset_t off = (offset_t) blk << FSBSHIFT;
- if (llseek(fd, off, 0) < 0) {
+ if (OS_SEEK(fd, off, 0) < 0) {
Log("Unable to seek to offset %llu for block %u\n", off, blk);
return -1;
}
#else /* AFS_AIX41_ENV */
- if (lseek(fd, blk * Bsize, 0) < 0) {
+ if (OS_SEEK(fd, blk * Bsize, 0) < 0) {
Log("Unable to seek to offset %u for block %u\n", blk * Bsize, blk);
}
#endif /* AFS_AIX41_ENV */
#else
- if (lseek(fd, (off_t) dbtob(blk), L_SET) < 0) {
+ if (OS_SEEK(fd, (off_t) dbtob(blk), L_SET) < 0) {
Log("Unable to seek to offset %u for block %u\n", dbtob(blk), blk);
}
#endif
- if (read(fd, buf, size) != size) {
+ if (OS_READ(fd, buf, size) != size) {
Log("Unable to read block %d, partition %s\n", blk, partition);
return -1;
}
}
#endif /* AFS_LINUX20_ENV */
+static afs_int32
+convertVolumeInfo(FdHandle_t *fdhr, FdHandle_t *fdhw, afs_uint32 vid)
+{
+ struct VolumeDiskData vd;
+ char *p;
+
+ if (FDH_PREAD(fdhr, &vd, sizeof(struct VolumeDiskData), 0) !=
+ sizeof(struct VolumeDiskData)) {
+ Log("1 convertiVolumeInfo: read failed for %lu with code %d\n", vid,
+ errno);
+ return -1;
+ }
+ vd.restoredFromId = vd.id; /* remember the RO volume here */
+ vd.cloneId = vd.id;
+ vd.id = vd.parentId;
+ vd.type = RWVOL;
+ vd.dontSalvage = 0;
+ vd.inUse = 0;
+ vd.uniquifier += 5000; /* just in case there are still file copies
+ from the old RW volume around */
+
+ /* For ROs, the copyDate contains the time that the RO volume was actually
+ * created, and the creationDate just contains the last time the RO was
+ * copied from the RW data. So, make the new RW creationDate more accurate
+ * by setting it to copyDate, if copyDate is older. Since, we know the
+ * volume is at least as old as copyDate. */
+ if (vd.copyDate < vd.creationDate) {
+ vd.creationDate = vd.copyDate;
+ } else {
+ /* If copyDate is newer, just make copyDate and creationDate the same,
+ * for consistency with other RWs */
+ vd.copyDate = vd.creationDate;
+ }
+
+ p = strrchr(vd.name, '.');
+ if (p && !strcmp(p, ".readonly")) {
+ memset(p, 0, 9);
+ }
+
+ if (FDH_PWRITE(fdhw, &vd, sizeof(struct VolumeDiskData), 0) !=
+ sizeof(struct VolumeDiskData)) {
+ Log("1 convertiVolumeInfo: write failed for %lu with code %d\n", vid,
+ errno);
+ return -1;
+ }
+ return 0;
+}
+
+struct specino {
+ afs_int32 inodeType;
+ Inode inodeNumber;
+ Inode ninodeNumber;
+};
+
+
+int
+UpdateThisVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber,
+ struct specino *specinos)
+{
+ struct dinode *p;
+ if ((inodeinfo->u.vnode.vnodeNumber == INODESPECIAL) &&
+ (inodeinfo->u.vnode.volumeId == singleVolumeNumber)) {
+ specinos[inodeinfo->u.special.type].inodeNumber =
+ inodeinfo->inodeNumber;
+ }
+ return 0; /* We aren't using a result file, we're caching */
+}
+
+static char *
+getDevName(char *pbuffer, char *wpath)
+{
+ char pbuf[128], *ptr;
+ strcpy(pbuf, pbuffer);
+ ptr = (char *)strrchr(pbuf, OS_DIRSEPC);
+ if (ptr) {
+ *ptr = '\0';
+ strcpy(wpath, pbuf);
+ } else
+ return NULL;
+ ptr = (char *)strrchr(pbuffer, OS_DIRSEPC);
+ if (ptr) {
+ strcpy(pbuffer, ptr + 1);
+ return pbuffer;
+ } else
+ return NULL;
+}
+
+#ifdef FSSYNC_BUILD_CLIENT
+int
+inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
+{
+ char dir_name[512], oldpath[512], newpath[512];
+ char volname[20];
+ char headername[16];
+ char *name;
+ int fd, err, forcep, j;
+ ssize_t len, nBytes;
+ struct dirent *dp;
+ struct DiskPartition64 *partP;
+ struct ViceInodeInfo info;
+ struct VolumeDiskHeader h;
+ IHandle_t *ih, *ih2;
+ FdHandle_t *fdP, *fdP2;
+ afs_foff_t offset;
+ char wpath[100];
+ char tmpDevName[100];
+ char buffer[128];
+ struct specino specinos[VI_LINKTABLE+1];
+ Inode nearInode = 0;
+# ifdef AFS_DEMAND_ATTACH_FS
+ int locktype = 0;
+# endif /* AFS_DEMAND_ATTACH_FS */
+ int code = 0;
+
+ memset(&specinos, 0, sizeof(specinos));
+
+ /* now do the work */
+
+ for (partP = DiskPartitionList; partP && strcmp(partP->name, pname);
+ partP = partP->next);
+ if (!partP) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't find DiskPartition for %s\n", pname);
+ code = EIO;
+ goto done;
+ }
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ locktype = VVolLockType(V_VOLUPD, 1);
+ code = VLockVolumeByIdNB(volumeId, partP, locktype);
+ if (code) {
+ locktype = 0;
+ code = EIO;
+ goto done;
+ }
+#endif
+
+ if (VReadVolumeDiskHeader(volumeId, partP, &h)) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't read header for RO-volume %lu.\n",
+ afs_printable_uint32_lu(volumeId));
+ return EIO;
+ }
+
+ FSYNC_VolOp(volumeId, pname, FSYNC_VOL_BREAKCBKS, 0, NULL);
+
+ strcpy(tmpDevName, partP->devName);
+ name = getDevName(tmpDevName, wpath);
+
+ if ((err = ListViceInodes(name, VPartitionPath(partP),
+ NULL, UpdateThisVolume, volumeId,
+ &forcep, 0, wpath, &specinos)) < 0)
+ {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't get special inodes\n");
+ code = EIO;
+ goto done;
+ }
+
+#if defined(NEARINODE_HINT)
+ nearInodeHash(volumeId, nearInode);
+ nearInode %= partP->f_files;
+#endif
+
+ for (j = VI_VOLINFO; j < VI_LINKTABLE+1; j++) {
+ if (specinos[j].inodeNumber > 0) {
+ specinos[j].ninodeNumber =
+ IH_CREATE(NULL, partP->device, VPartitionPath(partP),
+ nearInode, h.parent, INODESPECIAL, j, h.parent);
+ IH_INIT(ih, partP->device, volumeId,
+ specinos[j].inodeNumber);
+ fdP = IH_OPEN(ih);
+ if (!fdP) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't find special inode %d for %d\n", j, volumeId);
+ code = -1;
+ goto done;
+ }
+
+ IH_INIT(ih2, partP->device, h.parent, specinos[j].ninodeNumber);
+ fdP2 = IH_OPEN(ih2);
+ if (!fdP2) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't find special inode %d for %d\n", j, h.parent);
+ code = -1;
+ goto done;
+ }
+
+ if (j == VI_VOLINFO)
+ convertVolumeInfo(fdP, fdP2, ih2->ih_vid);
+ else {
+ offset = 0;
+ while (1) {
+ len = FDH_PREAD(fdP, buffer, sizeof(buffer), offset);
+ if (len < 0)
+ return errno;
+ if (len == 0)
+ break;
+ nBytes = FDH_PWRITE(fdP2, buffer, len, offset);
+ if (nBytes != len) {
+ code = -1;
+ goto done;
+ }
+ offset += len;
+ }
+ }
+
+ FDH_CLOSE(fdP);
+ FDH_CLOSE(fdP2);
+
+ /* Unlink the old special inode; otherwise we will get duplicate
+ * special inodes if we recreate the RO again */
+ if (IH_DEC(ih, specinos[j].inodeNumber, volumeId) == -1) {
+ afs_ino_str_t stmp;
+ Log("IH_DEC failed: %x, %s, %u errno %d\n", ih,
+ PrintInode(stmp, specinos[j].inodeNumber), volumeId, errno);
+ }
+
+ IH_RELEASE(ih);
+ IH_RELEASE(ih2);
+ }
+ }
+
+ h.id = h.parent;
+#ifdef AFS_64BIT_IOPS_ENV
+ h.volumeInfo_lo = (afs_int32)specinos[VI_VOLINFO].ninodeNumber & 0xffffffff;
+ h.volumeInfo_hi = (afs_int32)(specinos[VI_VOLINFO].ninodeNumber >> 32) && 0xffffffff;
+ h.smallVnodeIndex_lo = (afs_int32)specinos[VI_SMALLINDEX].ninodeNumber & 0xffffffff;
+ h.smallVnodeIndex_hi = (afs_int32)(specinos[VI_SMALLINDEX].ninodeNumber >> 32) & 0xffffffff;
+ h.largeVnodeIndex_lo = (afs_int32)specinos[VI_LARGEINDEX].ninodeNumber & 0xffffffff;
+ h.largeVnodeIndex_hi = (afs_int32)(specinos[VI_LARGEINDEX].ninodeNumber >> 32) & 0xffffffff;
+ if (specinos[VI_LINKTABLE].ninodeNumber) {
+ h.linkTable_lo = (afs_int32)specinos[VI_LINKTABLE].ninodeNumber & 0xffffffff;
+ h.linkTable_hi = (afs_int32)specinos[VI_LINKTABLE].ninodeNumber & 0xffffffff;
+ }
+#else
+ h.volumeInfo_lo = specinos[VI_VOLINFO].ninodeNumber;
+ h.smallVnodeIndex_lo = specinos[VI_SMALLINDEX].ninodeNumber;
+ h.largeVnodeIndex_lo = specinos[VI_LARGEINDEX].ninodeNumber;
+ if (specinos[VI_LINKTABLE].ninodeNumber) {
+ h.linkTable_lo = specinos[VI_LINKTABLE].ninodeNumber;
+ }
+#endif
+
+ if (VCreateVolumeDiskHeader(&h, partP)) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't write header for RW-volume %lu\n",
+ afs_printable_uint32_lu(h.id));
+ code = EIO;
+ goto done;
+ }
+
+ if (VDestroyVolumeDiskHeader(partP, volumeId, h.parent)) {
+ Log("1 inode_ConvertROtoRWvolume: Couldn't unlink header for RO-volume %lu\n",
+ afs_printable_uint32_lu(volumeId));
+ }
+
+ FSYNC_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
+ FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
+
+ done:
+# ifdef AFS_DEMAND_ATTACH_FS
+ if (locktype) {
+ VUnlockVolumeById(volumeId, partP);
+ }
+# endif /* AFS_DEMAND_ATTACH_FS */
+ return code;
+}
+#endif /* FSSYNC_BUILD_CLIENT */
#endif /* AFS_NAMEI_ENV */