vol: Introduce and use FDH_BLOCKSIZE 62/14662/4
authorAndrew Deason <adeason@sinenomine.net>
Wed, 3 Jun 2020 20:53:48 +0000 (15:53 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Thu, 22 Jul 2021 02:40:21 +0000 (22:40 -0400)
A couple of places in src/volser currently have some logic to get the
size and blocksize of a file. The existing logic is nontrivial due to
platform-specific quirks, and ignores afs_fstat errors.

To fix these issue and consolidate the code into one place, introduce
a new function, FDH_BLOCKSIZE, which gets the file size and blksize.
Update the places in src/volser to use the new function.

Change-Id: I4daeec84c8fdb5756a8d6a7f477d0045a19a8fe9
Reviewed-on: https://gerrit.openafs.org/14662
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/vol/ihandle.c
src/vol/ihandle.h
src/volser/dumpstuff.c
src/volser/vol-dump.c

index 3c01e3a..6d55ec8 100644 (file)
 #include <sys/resource.h>
 #endif
 
+#ifdef AFS_AIX_ENV
+# include <sys/statfs.h>
+#endif
+
 #include <afs/opr.h>
 #ifdef AFS_PTHREAD_ENV
 # include <opr/lock.h>
@@ -1154,3 +1158,80 @@ ih_fdsync(FdHandle_t *fdP)
        opr_Assert(0);
     }
 }
+
+#ifdef AFS_NT40_ENV
+
+static int
+os_blocksize(FD_t fd, afs_sfsize_t *a_size, afs_sfsize_t *a_blksize)
+{
+    LARGE_INTEGER fileSize;
+
+    if (!GetFileSizeEx(fd, &fileSize)) {
+       return GetLastError();
+    }
+
+    *a_size = fileSize.QuadPart;
+    *a_blksize = 4096;
+
+    return 0;
+}
+
+#else /* AFS_NT40_ENV */
+
+# ifdef AFS_AIX_ENV
+static int
+get_blksize_aix(FD_t fd, afs_sfsize_t *a_blksize)
+{
+    int code;
+#  ifdef AFS_AIX52_ENV
+    struct statfs64 tstatfs;
+    code = fstatfs64(fd, &tstatfs);
+#  else
+    struct statfs tstatfs;
+    code = fstatfs(fd, &tstatfs);
+#  endif
+    if (code != 0) {
+       return errno;
+    }
+    *a_blksize = tstatfs.f_bsize;
+    return 0;
+}
+# endif /* AFS_AIX_ENV */
+
+static int
+os_blocksize(FD_t fd, afs_sfsize_t *a_size, afs_sfsize_t *a_blksize)
+{
+    int code;
+    struct afs_stat status;
+    code = afs_fstat(fd, &status);
+    if (code < 0) {
+       return errno;
+    }
+
+    *a_size = status.st_size;
+
+# ifdef AFS_AIX_ENV
+    /* In AIX, st_blksize is not in struct stat; get it from fstatfs instead. */
+    return get_blksize_aix(fd, a_blksize);
+# else
+    *a_blksize = status.st_blksize;
+    return 0;
+# endif
+}
+
+#endif /* AFS_NT40_ENV */
+
+/**
+ * Get the size and blocksize for a file handle.
+ *
+ * @param[in] fdP   The file handle to query
+ * @param[out] a_size      The size of the underlying file
+ * @param[out] a_blksize    The block size of the underlying file
+ *
+ * @return errno error codes
+ */
+int
+fd_blocksize(FdHandle_t *fdP, afs_sfsize_t *a_size, afs_sfsize_t *a_blksize)
+{
+    return os_blocksize(fdP->fd_fd, a_size, a_blksize);
+}
index ac71ffd..e79b4d1 100644 (file)
@@ -69,6 +69,7 @@
  *
  * status information:
  * FDH_SIZE - returns the size of the file.
+ * FDH_BLOCKSIZE - returns the size and blocksize of the file.
  * FDH_NLINK - returns the link count of the file.
  * FDH_ISUNLINKED - returns if the file has been unlinked out from under us
  *
@@ -348,6 +349,9 @@ extern int ih_release(IHandle_t * ihP);
 extern int ih_condsync(IHandle_t * ihP);
 extern FdHandle_t *ih_attachfd(IHandle_t * ihP, FD_t fd);
 
+extern int fd_blocksize(FdHandle_t *fdP, afs_sfsize_t *a_size,
+                       afs_sfsize_t *a_blksize);
+
 /* Macros common to user space and inode API's. */
 #define IH_INIT(H, D, V, I) ((H) = ih_init((D), (V), (I)))
 
@@ -582,6 +586,7 @@ extern afs_sfsize_t ih_size(FD_t);
 #define FDH_SYNC(H) ih_fdsync(H)
 #define FDH_TRUNC(H, L) OS_TRUNC((H)->fd_fd, L)
 #define FDH_SIZE(H) OS_SIZE((H)->fd_fd)
+#define FDH_BLOCKSIZE(H, S, B) fd_blocksize(H, S, B)
 #define FDH_LOCKFILE(H, O) OS_LOCKFILE((H)->fd_fd, O)
 #define FDH_UNLOCKFILE(H, O) OS_UNLOCKFILE((H)->fd_fd, O)
 #define FDH_ISUNLINKED(H) OS_ISUNLINKED((H)->fd_fd)
index 8c044d6..bbc66f1 100644 (file)
@@ -704,59 +704,19 @@ static int
 DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
 {
     int code = 0, error = 0;
-    afs_sfsize_t nbytes, howBig;
+    afs_sfsize_t nbytes, howBig, howMany;
     ssize_t n = 0;
-    size_t howMany;
     afs_foff_t howFar = 0;
     byte *p;
     afs_uint32 hi, lo;
     afs_ino_str_t stmp;
-#ifndef AFS_NT40_ENV
-    struct afs_stat status;
-#else
-    LARGE_INTEGER fileSize;
-#endif
-#ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
-#if defined(AFS_AIX52_ENV)
-    struct statfs64 tstatfs;
-#else /* !AFS_AIX52_ENV */
-    struct statfs tstatfs;
-#endif /* !AFS_AIX52_ENV */
-    int statfs_code;
-#endif
 
-#ifdef AFS_NT40_ENV
-    if (!GetFileSizeEx(handleP->fd_fd, &fileSize)) {
-        Log("DumpFile: GetFileSizeEx returned error code %d on descriptor %d\n", GetLastError(), handleP->fd_fd);
-           return VOLSERDUMPERROR;
-    }
-    howBig = fileSize.QuadPart;
-    howMany = 4096;
-
-#else
-    afs_fstat(handleP->fd_fd, &status);
-    howBig = status.st_size;
-
-#ifdef AFS_AIX_ENV
-    /* Unfortunately in AIX valuable fields such as st_blksize are
-     * gone from the stat structure.
-     */
-#if defined(AFS_AIX52_ENV)
-    statfs_code = fstatfs64(handleP->fd_fd, &tstatfs);
-#else /* !AFS_AIX52_ENV */
-    statfs_code = fstatfs(handleP->fd_fd, &tstatfs);
-#endif /* !AFS_AIX52_ENV */
-    if (statfs_code != 0) {
-        Log("DumpFile: fstatfs returned error code %d on descriptor %d\n", errno, handleP->fd_fd);
+    code = FDH_BLOCKSIZE(handleP, &howBig, &howMany);
+    if (code != 0) {
+       Log("DumpFile: FDH_BLOCKSIZE returned error code %d on descriptor %d\n",
+           code, handleP->fd_fd);
        return VOLSERDUMPERROR;
     }
-    howMany = tstatfs.f_bsize;
-#else
-    howMany = status.st_blksize;
-#endif /* AFS_AIX_ENV */
-#endif /* AFS_NT40_ENV */
-
 
     SplitInt64(howBig, hi, lo);
     if (hi == 0L) {
index 0fdf0e3..de1a28c 100644 (file)
@@ -536,57 +536,26 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
     int code = 0;
     afs_int32 pad = 0;
     afs_foff_t offset = 0;
-    afs_sfsize_t nbytes, howBig;
+    afs_sfsize_t nbytes, size, howMany;
     ssize_t n = 0;
-    size_t howMany;
     afs_foff_t howFar = 0;
     byte *p;
     afs_uint32 hi, lo;
     afs_ino_str_t stmp;
-#ifndef AFS_NT40_ENV
-    struct afs_stat status;
-#else
-    LARGE_INTEGER fileSize;
-#endif
-    afs_sfsize_t size;
-#ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
-    struct statfs tstatfs;
-#endif
 
     if (verbose)
        fprintf(stderr, "dumping file for vnode %d\n", vnode);
 
-#ifdef AFS_NT40_ENV
-    if (!GetFileSizeEx(handleP->fd_fd, &fileSize)) {
-        Log("DumpFile: GetFileSizeEx returned error code %d on descriptor %d\n", GetLastError(), handleP->fd_fd);
-           return VOLSERDUMPERROR;
+    code = FDH_BLOCKSIZE(handleP, &size, &howMany);
+    if (code != 0) {
+       fprintf(stderr, "FDH_BLOCKSIZE returned error code %d on descriptor %d\n",
+               code, handleP->fd_fd);
+       return VOLSERDUMPERROR;
     }
-    howBig = fileSize.QuadPart;
-    howMany = 4096;
-
-#else
-    afs_fstat(handleP->fd_fd, &status);
-    howBig = status.st_size;
-
-#ifdef AFS_AIX_ENV
-    /* Unfortunately in AIX valuable fields such as st_blksize are
-     * gone from the stat structure.
-     */
-    fstatfs(handleP->fd_fd, &tstatfs);
-    howMany = tstatfs.f_bsize;
-#else
-    howMany = status.st_blksize;
-#endif /* AFS_AIX_ENV */
-#endif /* AFS_NT40_ENV */
-
-
-    size = FDH_SIZE(handleP);
 
     if (verbose)
-       fprintf(stderr, "  howBig = %u, howMany = %u, fdh size = %u\n",
-               (unsigned int) howBig, (unsigned int) howMany,
-               (unsigned int) size);
+       fprintf(stderr, "  howMany = %u, fdh size = %u\n",
+               (unsigned int) howMany, (unsigned int) size);
 
     SplitInt64(size, hi, lo);
     if (hi == 0L) {