Don't cast the return from realloc()
[openafs.git] / src / vol / listinodes.c
index cf5578c..22425c0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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>
 
-#include <string.h>
+#include <roken.h>
 
+#include <ctype.h>
 
 #ifndef AFS_NAMEI_ENV
-#if defined(AFS_LINUX20_ENV) || defined(AFS_SUN4_ENV)
+#if defined(AFS_LINUX20_ENV)
 /* ListViceInodes
  *
  * Return codes:
@@ -33,7 +34,7 @@
  * -2 - Unable to completely write temp file. Produces warning message in log.
  */
 int
-ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
               afs_uint32 (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
               char *wpath, void *rock)
 {
@@ -41,10 +42,7 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     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 */
@@ -69,7 +67,6 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 #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
@@ -89,24 +86,15 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 #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 "lock.h"
 #include "ihandle.h"
 #include "vnode.h"
@@ -114,35 +102,14 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 #include "volinodes.h"
 #include "partition.h"
 #include "fssync.h"
-
-/*@+fcnmacros +macrofcndecl@*/
-#ifdef O_LARGEFILE
-#ifdef S_SPLINT_S
-extern off64_t afs_lseek(int FD, off64_t O, int F);
-#endif /*S_SPLINT_S */
-#define afs_lseek(FD, O, F)   lseek64(FD, (off64_t) (O), F)
-#define afs_stat      stat64
-#define afs_fstat     fstat64
-#define afs_open      open64
-#define afs_fopen     fopen64
-#else /* !O_LARGEFILE */
-#ifdef S_SPLINT_S
-extern off_t afs_lseek(int FD, off_t O, int F);
-#endif /*S_SPLINT_S */
-#define afs_lseek(FD, O, F)   lseek(FD, (off_t) (O), F)
-#define afs_stat      stat
-#define afs_fstat     fstat
-#define afs_open      open
-#define afs_fopen     fopen
-#endif /* !O_LARGEFILE */
-/*@=fcnmacros =macrofcndecl@*/
+#include "volume_inline.h"
 
 /* Notice:  parts of this module have been cribbed from vfsck.c */
 
 #define        ROOTINODE       2
 static char *partition;
 int Testing=0;
-int pfd;
+FD_t pfd;
 
 #ifdef AFS_AIX32_ENV
 #include <jfs/filsys.h>
@@ -190,7 +157,7 @@ struct dinode *ginode();
 
 
 int
-ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
               int (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
               char *wpath, void *rock)
 {
@@ -201,7 +168,7 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     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    */
@@ -275,8 +242,8 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 
     fmax = fs.s_fsize / (FSBSIZE / 512);       /* first invalid blk num */
 
-    pfd = afs_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;
     }
@@ -298,7 +265,7 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
      *      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) {
@@ -322,8 +289,8 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
            continue;
 
-       if (inodeFile) {
-           if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+       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;
            }
@@ -331,13 +298,8 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        ++ninodes;
     }
 
-    if (inodeFile) {
-       if (fflush(inodeFile) == EOF) {
-           Log("Unable to successfully flush inode file for %s\n", partition);
-           err = -2;
-           goto out1;
-       }
-       if (fsync(fileno(inodeFile)) == -1) {
+    if (inodeFile != INVALID_FD) {
+       if (OS_SYNC(inodeFile) == -1) {
            Log("Unable to successfully fsync inode file for %s\n", partition);
            err = -2;
            goto out1;
@@ -346,12 +308,7 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        /*
         * Paranoia:  check that the file is really the right size
         */
-       if (fstat(fileno(inodeFile), &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)) {
+       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);
@@ -359,14 +316,14 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
            goto out1;
        }
     }
-    close(pfd);
+    OS_CLOSE(pfd);
     return 0;
 
   out:
     err = -1;
   out1:
-    if (pfd >= 0)
-       close(pfd);
+    if (pfd != INVALID_FD)
+       OS_CLOSE(pfd);
 
     return err;
 }
@@ -375,10 +332,10 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 int
 ReadSuper(struct superblock *fs, char *devName)
 {
-    int pfd;
+    FD_t pfd;
 
-    pfd = afs_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;
     }
@@ -387,7 +344,7 @@ ReadSuper(struct superblock *fs, char *devName)
        Log("Unable to read superblock on %s.\n", devName);
        return -1;
     }
-    close(pfd);
+    OS_CLOSE(pfd);
     return (0);
 }
 
@@ -452,14 +409,13 @@ ginode(inum)
 #define        __ASSERT_H__
 
 #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
@@ -473,7 +429,7 @@ ginode(inum)
  */
 
 /* 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.
@@ -491,6 +447,7 @@ xfs_VerifyInode(char *dir, uint64_t pino, char *name, i_list_inode_t * info,
     char tmpName[32];
     b64_string_t stmp;
     int tag;
+    afs_ino_str_t stmp;
 
     *rename = 0;
     (void)sprintf(path, "%s/%s", dir, name);
@@ -498,7 +455,7 @@ xfs_VerifyInode(char *dir, uint64_t pino, char *name, i_list_inode_t * info,
     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;
@@ -508,7 +465,7 @@ xfs_VerifyInode(char *dir, uint64_t pino, char *name, i_list_inode_t * info,
     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;
@@ -541,7 +498,7 @@ xfs_VerifyInode(char *dir, uint64_t pino, char *name, i_list_inode_t * info,
     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;
@@ -557,7 +514,7 @@ xfs_VerifyInode(char *dir, uint64_t pino, char *name, i_list_inode_t * info,
            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;
@@ -565,7 +522,7 @@ xfs_VerifyInode(char *dir, uint64_t pino, char *name, i_list_inode_t * info,
                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;
@@ -641,7 +598,7 @@ xfs_RenameFiles(char *dir, xfs_Rename_t * renames, int n_renames)
 
 
 int
-xfs_ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
+xfs_ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
                   int (*judgeInode) (), afs_uint32 judgeParam, int *forcep,
                   int forceR, char *wpath, void *rock)
 {
@@ -666,7 +623,6 @@ xfs_ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     int n_renames = 0;
     int n_avail = 0;
     uint64_t pino;
-    struct stat status;
     int errors = 0;
 
     *forcep = 0;
@@ -762,9 +718,8 @@ xfs_ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
                        renames = (xfs_Rename_t *)
                            malloc(n_avail * sizeof(xfs_Rename_t));
                    else
-                       renames = (xfs_Rename_t *)
-                           realloc((char *)renames,
-                                   n_avail * sizeof(xfs_Rename_t));
+                       renames = realloc(renames,
+                                         n_avail * sizeof(xfs_Rename_t));
                    if (!renames) {
                        Log("Can't %salloc %lu bytes for rename list.\n",
                            (n_avail == N_RENAME_STEP) ? "m" : "re",
@@ -777,10 +732,10 @@ xfs_ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
                n_renames++;
            }
 
-           if (inodeFile) {
-               if (fwrite
-                   (&info.ili_info, sizeof(vice_inode_info_t), 1, inodeFile)
-                   != 1) {
+           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;
                }
@@ -801,26 +756,18 @@ xfs_ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 
     closedir(top_dirp);
     if (renames)
-       free((char *)renames);
-    if (inodeFile) {
-       if (fflush(inodeFile) == EOF) {
-           ("Unable to successfully flush inode file for %s\n", mountedOn);
-           return errors ? -1 : -2;
-       }
-       if (fsync(fileno(inodeFile)) == -1) {
+       free(renames);
+    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 (fstat(fileno(inodeFile), &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)) {
+       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),
+               OS_SIZE(inodeFile), ninodes * sizeof(struct ViceInodeInfo),
                partition);
            return errors ? -1 : -2;
        }
@@ -839,14 +786,14 @@ xfs_ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     if (top_dirp)
        closedir(top_dirp);
     if (renames)
-       free((char *)renames);
+       free(renames);
     return -1;
 }
 
 #endif
 
 int
-ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
               int (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
               char *wpath, void *rock)
 {
@@ -911,7 +858,7 @@ BUFAREA sblk;
 
 extern char *afs_rawname();
 int
-ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
+ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
               int (*judgeInode) (), afs_uint32 judgeParam, int *forcep, int forceR,
               char *wpath, void *rock)
 {
@@ -927,7 +874,6 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     int i, c, e, bufsize, code, err = 0;
     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;
@@ -946,8 +892,8 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     sleep(10);
 #endif
 
-    pfd = afs_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;
@@ -1007,8 +953,8 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        info.u.param[3] = auxp->aux_param4;
        if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
            continue;
-       if (inodeFile) {
-           if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+       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;
            }
@@ -1084,10 +1030,10 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        i = c * sblock.fs_ipg;
        e = i + sblock.fs_ipg;
 #if    defined(AFS_HPUX102_ENV)
-       if (afs_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 (afs_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
@@ -1105,14 +1051,14 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        e = i + super.fs.fs_ipg;
 #ifdef AFS_OSF_ENV
        dblk1 = fsbtodb(&super.fs, itod(&super.fs, i));
-       if (afs_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 (afs_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 */
@@ -1123,19 +1069,19 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
        }
        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 (afs_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;
@@ -1169,10 +1115,10 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
                    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;
@@ -1218,8 +1164,8 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
                    info.linkCount = p->di_nlink;
                    if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0)
                        continue;
-                   if (inodeFile) {
-                       if (fwrite(&info, sizeof info, 1, inodeFile) != 1) {
+                   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;
@@ -1233,41 +1179,31 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
     if (inodes)
        free(inodes);
 #endif
-    if (inodeFile) {
-       if (fflush(inodeFile) == EOF) {
-           Log("Unable to successfully flush inode file for %s\n", partition);
-           err = -2;
-           goto out1;
-       }
-       if (fsync(fileno(inodeFile)) == -1) {
+    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 (fstat(fileno(inodeFile), &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)) {
+       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),
+               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);
+    OS_CLOSE(pfd);
     if (inodes)
        free(inodes);
     return err;
@@ -1281,26 +1217,26 @@ ListViceInodes(char *devname, char *mountedOn, FILE *inodeFile,
 #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 (afs_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 (afs_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;
     }
@@ -1309,12 +1245,12 @@ bread(int fd, char *buf, daddr_t blk, afs_int32 size)
 
 #endif /* AFS_LINUX20_ENV */
 static afs_int32
-convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
+convertVolumeInfo(FdHandle_t *fdhr, FdHandle_t *fdhw, afs_uint32 vid)
 {
     struct VolumeDiskData vd;
     char *p;
 
-    if (read(fdr, &vd, sizeof(struct VolumeDiskData)) !=
+    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);
@@ -1326,15 +1262,28 @@ convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
     vd.type = RWVOL;
     vd.dontSalvage = 0;
     vd.inUse = 0;
-    vd.uniquifier += 5000;      /* just in case there are still file copies 
+    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 (write(fdw, &vd, sizeof(struct VolumeDiskData)) !=
+    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);
@@ -1351,13 +1300,13 @@ struct specino {
 
 
 int
-UpdateThisVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber, 
+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 = 
+       specinos[inodeinfo->u.special.type].inodeNumber =
            inodeinfo->inodeNumber;
     }
     return 0; /* We aren't using a result file, we're caching */
@@ -1368,13 +1317,13 @@ getDevName(char *pbuffer, char *wpath)
 {
     char pbuf[128], *ptr;
     strcpy(pbuf, pbuffer);
-    ptr = (char *)strrchr(pbuf, '/');
+    ptr = (char *)strrchr(pbuf, OS_DIRSEPC);
     if (ptr) {
         *ptr = '\0';
         strcpy(wpath, pbuf);
     } else
         return NULL;
-    ptr = (char *)strrchr(pbuffer, '/');
+    ptr = (char *)strrchr(pbuffer, OS_DIRSEPC);
     if (ptr) {
         strcpy(pbuffer, ptr + 1);
         return pbuffer;
@@ -1398,33 +1347,38 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     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));
 
-#ifdef AFS_DEMAND_ATTACH_FS
-/* DAFS currently doesn't really work with inode, so don't bother putting the
- * locking code here right now. But in case someday someone makes DAFS work
- * with the inode backend, make sure they remember to add the volume locking
- * code here (make the build fail until that happens). If that is what you're
- * trying to do, take a look at VLockVolumeByIdNB, and
- * namei_ConvertROtoRWvolume.
- */
-# error must lock volumes before ConvertROtoRW is usable on DAFS inode
-#endif
-          
     /* 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);
-        return EIO;
+        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",
@@ -1437,14 +1391,15 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     strcpy(tmpDevName, partP->devName);
     name = getDevName(tmpDevName, wpath);
 
-    if ((err = ListViceInodes(name, VPartitionPath(partP), 
-                             NULL, UpdateThisVolume, volumeId, 
+    if ((err = ListViceInodes(name, VPartitionPath(partP),
+                             NULL, UpdateThisVolume, volumeId,
                              &forcep, 0, wpath, &specinos)) < 0)
     {
        Log("1 inode_ConvertROtoRWvolume: Couldn't get special inodes\n");
-       return EIO;
+       code = EIO;
+       goto done;
     }
-          
+
 #if defined(NEARINODE_HINT)
     nearInodeHash(volumeId, nearInode);
     nearInode %= partP->f_files;
@@ -1452,54 +1407,61 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
 
     for (j = VI_VOLINFO; j < VI_LINKTABLE+1; j++) {
        if (specinos[j].inodeNumber > 0) {
-           specinos[j].ninodeNumber = 
+           specinos[j].ninodeNumber =
                IH_CREATE(NULL, partP->device, VPartitionPath(partP),
                          nearInode, h.parent, INODESPECIAL, j, h.parent);
-           IH_INIT(ih, partP->device, volumeId, 
+           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); 
-               return -1;
+               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);  
-               return -1; 
-           } 
-           
+           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->fd_fd, fdP2->fd_fd, ih2->ih_vid);
+               convertVolumeInfo(fdP, fdP2, ih2->ih_vid);
            else {
+               offset = 0;
                while (1) {
-                   len = read(fdP->fd_fd, buffer, sizeof(buffer));
+                   len = FDH_PREAD(fdP, buffer, sizeof(buffer), offset);
                    if (len < 0)
                        return errno;
                    if (len == 0)
                        break;
-                   nBytes = write(fdP2->fd_fd, buffer, len);
-                   if (nBytes != len)
-                       return -1;
+                   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(NULL, specinos[j].inodeNumber), volumeId, errno);
+                   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;
@@ -1524,7 +1486,8 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     if (VCreateVolumeDiskHeader(&h, partP)) {
         Log("1 inode_ConvertROtoRWvolume: Couldn't write header for RW-volume %lu\n",
            afs_printable_uint32_lu(h.id));
-        return EIO;
+        code = EIO;
+       goto done;
     }
 
     if (VDestroyVolumeDiskHeader(partP, volumeId, h.parent)) {
@@ -1534,7 +1497,14 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
 
     FSYNC_VolOp(volumeId, pname, FSYNC_VOL_DONE, 0, NULL);
     FSYNC_VolOp(h.id, pname, FSYNC_VOL_ON, 0, NULL);
-    return 0;
+
+ 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 */