VirtualBox

Changeset 76873 in vbox


Ignore:
Timestamp:
Jan 18, 2019 5:07:58 AM (6 years ago)
Author:
vboxsync
Message:

FsPerf: Updates. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp

    r76801 r76873  
    11/* $Id$ */
    22/** @file
    3  * NetPerf - File System Performance Benchmark.
     3 * FsPerf - File System (Shared Folders) Performance Benchmark.
    44 */
    55
     
    4848#include <iprt/time.h>
    4949#include <iprt/thread.h>
     50#include <iprt/zero.h>
    5051
    5152
     
    8990#define PROFILE_MANYTREE_FN(a_szPath, a_fnCall, a_cEstimationIterations, a_cNsTarget, a_szDesc) \
    9091    do { \
     92        if (!g_fManyFiles) \
     93            break; \
     94        \
    9195        /* Estimate how many iterations we need to fill up the given timeslot: */ \
    9296        uint64_t const nsStartEstimation = RTTimeNanoTS(); \
     
    158162
    159163
     164enum
     165{
     166    kCmdOpt_First = 128,
     167
     168    kCmdOpt_ManyFiles = kCmdOpt_First,
     169    kCmdOpt_NoManyFiles,
     170    kCmdOpt_Open,
     171    kCmdOpt_NoOpen,
     172    kCmdOpt_FStat,
     173    kCmdOpt_NoFStat,
     174    kCmdOpt_FChMod,
     175    kCmdOpt_NoFChMod,
     176    kCmdOpt_FUtimes,
     177    kCmdOpt_NoFUtimes,
     178    kCmdOpt_Stat,
     179    kCmdOpt_NoStat,
     180    kCmdOpt_ChMod,
     181    kCmdOpt_NoChMod,
     182    kCmdOpt_Utimes,
     183    kCmdOpt_NoUtimes,
     184    kCmdOpt_Rename,
     185    kCmdOpt_NoRename,
     186    kCmdOpt_DirEnum,
     187    kCmdOpt_NoDirEnum,
     188    kCmdOpt_MkRmDir,
     189    kCmdOpt_NoMkRmDir,
     190    kCmdOpt_StatVfs,
     191    kCmdOpt_NoStatVfs,
     192    kCmdOpt_Rm,
     193    kCmdOpt_NoRm,
     194    kCmdOpt_ChSize,
     195    kCmdOpt_NoChSize,
     196    kCmdOpt_Read,
     197    kCmdOpt_NoRead,
     198    kCmdOpt_Write,
     199    kCmdOpt_NoWrite,
     200    kCmdOpt_Seek,
     201    kCmdOpt_NoSeek,
     202
     203    kCmdOpt_End
     204};
     205
    160206/*********************************************************************************************************************************
    161207*   Global Variables                                                                                                             *
     
    166212    { "--dir",              'd', RTGETOPT_REQ_STRING  },
    167213    { "--seconds",          's', RTGETOPT_REQ_UINT32  },
     214    { "--milliseconds",     'm', RTGETOPT_REQ_UINT64  },
     215
     216    { "--enable-all",       'e', RTGETOPT_REQ_NOTHING },
     217    { "--disable-all",      'z', RTGETOPT_REQ_NOTHING },
     218
     219    { "--many-files",       kCmdOpt_ManyFiles,      RTGETOPT_REQ_NOTHING },
     220    { "--no-many-files",    kCmdOpt_NoManyFiles,    RTGETOPT_REQ_NOTHING },
     221
     222    { "--open",             kCmdOpt_Open,           RTGETOPT_REQ_NOTHING },
     223    { "--no-open",          kCmdOpt_NoOpen,         RTGETOPT_REQ_NOTHING },
     224    { "--fstat",            kCmdOpt_FStat,          RTGETOPT_REQ_NOTHING },
     225    { "--no-fstat",         kCmdOpt_NoFStat,        RTGETOPT_REQ_NOTHING },
     226    { "--fchmod",           kCmdOpt_FChMod,         RTGETOPT_REQ_NOTHING },
     227    { "--no-fchmod",        kCmdOpt_NoFChMod,       RTGETOPT_REQ_NOTHING },
     228    { "--futimes",          kCmdOpt_FUtimes,        RTGETOPT_REQ_NOTHING },
     229    { "--no-futimes",       kCmdOpt_NoFUtimes,      RTGETOPT_REQ_NOTHING },
     230    { "--stat",             kCmdOpt_Stat,           RTGETOPT_REQ_NOTHING },
     231    { "--no-stat",          kCmdOpt_NoStat,         RTGETOPT_REQ_NOTHING },
     232    { "--chmod",            kCmdOpt_ChMod,          RTGETOPT_REQ_NOTHING },
     233    { "--no-chmod",         kCmdOpt_NoChMod,        RTGETOPT_REQ_NOTHING },
     234    { "--utimes",           kCmdOpt_Utimes,         RTGETOPT_REQ_NOTHING },
     235    { "--no-utimes",        kCmdOpt_NoUtimes,       RTGETOPT_REQ_NOTHING },
     236    { "--rename",           kCmdOpt_Rename,         RTGETOPT_REQ_NOTHING },
     237    { "--no-rename",        kCmdOpt_NoRename,       RTGETOPT_REQ_NOTHING },
     238    { "--dir-enum",         kCmdOpt_DirEnum,        RTGETOPT_REQ_NOTHING },
     239    { "--no-dir-enum",      kCmdOpt_NoDirEnum,      RTGETOPT_REQ_NOTHING },
     240    { "--mk-rm-dir",        kCmdOpt_MkRmDir,        RTGETOPT_REQ_NOTHING },
     241    { "--no-mk-rm-dir",     kCmdOpt_NoMkRmDir,      RTGETOPT_REQ_NOTHING },
     242    { "--stat-vfs",         kCmdOpt_StatVfs,        RTGETOPT_REQ_NOTHING },
     243    { "--no-stat-vfs",      kCmdOpt_NoStatVfs,      RTGETOPT_REQ_NOTHING },
     244    { "--rm",               kCmdOpt_Rm,             RTGETOPT_REQ_NOTHING },
     245    { "--no-rm",            kCmdOpt_NoRm,           RTGETOPT_REQ_NOTHING },
     246    { "--chsize",           kCmdOpt_ChSize,         RTGETOPT_REQ_NOTHING },
     247    { "--no-chsize",        kCmdOpt_NoChSize,       RTGETOPT_REQ_NOTHING },
     248    { "--read",             kCmdOpt_Read,           RTGETOPT_REQ_NOTHING },
     249    { "--no-read",          kCmdOpt_NoRead,         RTGETOPT_REQ_NOTHING },
     250    { "--write",            kCmdOpt_Write,          RTGETOPT_REQ_NOTHING },
     251    { "--no-write",         kCmdOpt_NoWrite,        RTGETOPT_REQ_NOTHING },
     252    { "--seek",             kCmdOpt_Seek,           RTGETOPT_REQ_NOTHING },
     253    { "--no-seek",          kCmdOpt_NoSeek,         RTGETOPT_REQ_NOTHING },
     254
     255    { "--quiet",            'q', RTGETOPT_REQ_NOTHING },
    168256    { "--verbose",          'v', RTGETOPT_REQ_NOTHING },
    169257    { "--version",          'V', RTGETOPT_REQ_NOTHING },
     
    173261/** The test handle. */
    174262static RTTEST       g_hTest;
     263/** The number of nanoseconds a RTTimeNanoTS call takes.
     264 * This is used for adjusting loop count estimates.  */
     265static uint64_t     g_nsPerNanoTSCall = 1;
    175266/** Verbosity level. */
    176267static uint32_t     g_uVerbosity = 0;
     
    179270 * @{ */
    180271static bool         g_fManyFiles = true;
     272static bool         g_fOpen      = true;
     273static bool         g_fFStat     = true;
     274static bool         g_fFChMod    = true;
     275static bool         g_fFUtimes   = true;
     276static bool         g_fStat      = true;
     277static bool         g_fChMod     = true;
     278static bool         g_fUtimes    = true;
     279static bool         g_fRename    = true;
     280static bool         g_fDirEnum   = true;
     281static bool         g_fMkRmDir   = true;
     282static bool         g_fStatVfs   = true;
     283static bool         g_fRm        = true;
     284static bool         g_fChSize    = true;
     285static bool         g_fSeek      = true;
     286static bool         g_fRead      = true;
     287static bool         g_fWrite     = true;
    181288/** @} */
    182289
     
    188295
    189296/** Number of files in the 'manytree' directory tree.  */
    190 static uint32_t     g_cManyTreeFiles  = 640 + 16*640 /*10880*/;
     297static uint32_t     g_cManyTreeFiles         = 640 + 16*640 /*10880*/;
    191298/** Number of files per directory in the 'manytree' construct. */
    192 static uint32_t     g_cManyTreeFilesPerDir = 640;
     299static uint32_t     g_cManyTreeFilesPerDir   = 640;
    193300/* Number of subdirs per directory in the 'manytree' construct. */
    194301static uint32_t     g_cManyTreeSubdirsPerDir = 16;
    195302/** The depth of the 'manytree' directory tree.  */
    196 static uint32_t     g_cManyTreeDepth  = 1;
     303static uint32_t     g_cManyTreeDepth          = 1;
    197304/** List of directories in the many tree, creation order. */
    198305static RTLISTANCHOR g_ManyTreeHead;
     306
     307/** Number of configured I/O block sizes. */
     308static uint32_t     g_cIoBlocks       = 8;
     309/** Configured I/O block sizes. */
     310static uint32_t     g_acbIoBlocks[16] = { 1, 512, 4096, 16384, 65536, _1M, _32M, _128M };
     311/** The desired size of the test file we use for I/O. */
     312static uint64_t     g_cbIoFile        = _512M;
    199313
    200314/** The length of g_szDir. */
     
    220334    RTThreadYield();
    221335    RTThreadYield();
     336}
     337
     338
     339/**
     340 * Profiles the RTTimeNanoTS call, setting g_nsPerNanoTSCall.
     341 */
     342static void fsPerfNanoTS(void)
     343{
     344    fsPerfYield();
     345
     346    /* Make sure we start off on a changing timestamp on platforms will low time resoultion. */
     347    uint64_t nsStart = RTTimeNanoTS();
     348    uint64_t ns;
     349    do
     350        ns = RTTimeNanoTS();
     351    while (ns == nsStart);
     352    nsStart = ns;
     353
     354    /* Call it for 10 ms. */
     355    uint32_t i = 0;
     356    do
     357    {
     358        i++;
     359        ns = RTTimeNanoTS();
     360    }
     361    while (ns - nsStart < RT_NS_10MS);
     362
     363    g_nsPerNanoTSCall = (ns - nsStart) / i;
    222364}
    223365
     
    753895     * The directory with many files in it.
    754896     */
    755     fDots = 0;
    756     uint32_t const cBitmap  = RT_ALIGN_32(g_cManyFiles, 64);
    757     void          *pvBitmap = alloca(cBitmap / 8);
    758     RT_BZERO(pvBitmap, cBitmap / 8);
    759     for (uint32_t i = g_cManyFiles; i < cBitmap; i++)
    760         ASMBitSet(pvBitmap, i);
    761 
    762     uint32_t cFiles = 0;
    763     RTTESTI_CHECK_RC_RETV(RTDirOpen(&hDir, InDir(RT_STR_TUPLE("manyfiles"))), VINF_SUCCESS);
    764     for (;;)
    765     {
    766         int rc = RTDirRead(hDir, &Entry, NULL);
    767         if (rc == VINF_SUCCESS)
     897    if (g_fManyFiles)
     898    {
     899        fDots = 0;
     900        uint32_t const cBitmap  = RT_ALIGN_32(g_cManyFiles, 64);
     901        void          *pvBitmap = alloca(cBitmap / 8);
     902        RT_BZERO(pvBitmap, cBitmap / 8);
     903        for (uint32_t i = g_cManyFiles; i < cBitmap; i++)
     904            ASMBitSet(pvBitmap, i);
     905
     906        uint32_t cFiles = 0;
     907        RTTESTI_CHECK_RC_RETV(RTDirOpen(&hDir, InDir(RT_STR_TUPLE("manyfiles"))), VINF_SUCCESS);
     908        for (;;)
    768909        {
    769             if (Entry.szName[0] == '.')
     910            int rc = RTDirRead(hDir, &Entry, NULL);
     911            if (rc == VINF_SUCCESS)
    770912            {
    771                 if (Entry.szName[1] == '.')
     913                if (Entry.szName[0] == '.')
    772914                {
    773                     RTTESTI_CHECK(!(fDots & 2));
    774                     fDots |= 2;
     915                    if (Entry.szName[1] == '.')
     916                    {
     917                        RTTESTI_CHECK(!(fDots & 2));
     918                        fDots |= 2;
     919                    }
     920                    else
     921                    {
     922                        RTTESTI_CHECK(Entry.szName[1] == '\0');
     923                        RTTESTI_CHECK(!(fDots & 1));
     924                        fDots |= 1;
     925                    }
    775926                }
    776927                else
    777928                {
    778                     RTTESTI_CHECK(Entry.szName[1] == '\0');
    779                     RTTESTI_CHECK(!(fDots & 1));
    780                     fDots |= 1;
     929                    uint32_t iFile = UINT32_MAX;
     930                    RTTESTI_CHECK_RC(RTStrToUInt32Full(Entry.szName, 10, &iFile), VINF_SUCCESS);
     931                    if (   iFile < g_cManyFiles
     932                        && !ASMBitTest(pvBitmap, iFile))
     933                    {
     934                        ASMBitSet(pvBitmap, iFile);
     935                        cFiles++;
     936                    }
     937                    else
     938                        RTTestFailed(g_hTest, "line %u: iFile=%u g_cManyFiles=%u\n", __LINE__, iFile, g_cManyFiles);
    781939                }
    782940            }
     941            else if (rc == VERR_NO_MORE_FILES)
     942                break;
    783943            else
    784944            {
    785                 uint32_t iFile = UINT32_MAX;
    786                 RTTESTI_CHECK_RC(RTStrToUInt32Full(Entry.szName, 10, &iFile), VINF_SUCCESS);
    787                 if (   iFile < g_cManyFiles
    788                     && !ASMBitTest(pvBitmap, iFile))
    789                 {
    790                     ASMBitSet(pvBitmap, iFile);
    791                     cFiles++;
    792                 }
    793                 else
    794                     RTTestFailed(g_hTest, "line %u: iFile=%u g_cManyFiles=%u\n", __LINE__, iFile, g_cManyFiles);
     945                RTTestFailed(g_hTest, "RTDirRead failed enumerating manyfiles: %Rrc\n", rc);
     946                RTDirClose(hDir);
     947                return;
    795948            }
    796949        }
    797         else if (rc == VERR_NO_MORE_FILES)
    798             break;
    799         else
    800         {
    801             RTTestFailed(g_hTest, "RTDirRead failed enumerating manyfiles: %Rrc\n", rc);
    802             RTDirClose(hDir);
    803             return;
    804         }
    805     }
    806     RTTESTI_CHECK_RC(RTDirClose(hDir), VINF_SUCCESS);
    807     RTTESTI_CHECK(fDots == 3);
    808     RTTESTI_CHECK(cFiles == g_cManyFiles);
    809     RTTESTI_CHECK(ASMMemIsAllU8(pvBitmap, cBitmap / 8, 0xff));
     950        RTTESTI_CHECK_RC(RTDirClose(hDir), VINF_SUCCESS);
     951        RTTESTI_CHECK(fDots == 3);
     952        RTTESTI_CHECK(cFiles == g_cManyFiles);
     953        RTTESTI_CHECK(ASMMemIsAllU8(pvBitmap, cBitmap / 8, 0xff));
     954    }
    810955
    811956    /*
    812957     * Profile.
    813958     */
    814     PROFILE_FN(fsPerfEnumEmpty(),     g_nsTestRun, "RTDirOpen/Read/Close empty");
    815     PROFILE_FN(fsPerfEnumManyFiles(), g_nsTestRun, "RTDirOpen/Read/Close manyfiles");
    816 }
    817 
    818 
    819 void fsPerfMkDirRmDir(void)
     959    PROFILE_FN(fsPerfEnumEmpty(),g_nsTestRun, "RTDirOpen/Read/Close empty");
     960    if (g_fManyFiles)
     961        PROFILE_FN(fsPerfEnumManyFiles(), g_nsTestRun, "RTDirOpen/Read/Close manyfiles");
     962}
     963
     964
     965void fsPerfMkRmDir(void)
    820966{
    821967    RTTestISub("mkdir/rmdir");
     
    850996     * Profile alternately creating and removing a bunch of directories.
    851997     */
     998    RTTESTI_CHECK_RC_RETV(RTDirCreate(InDir(RT_STR_TUPLE("subdir-2")), 0755, 0), VINF_SUCCESS);
     999    size_t cchDir = strlen(g_szDir);
     1000    g_szDir[cchDir++] = RTPATH_SLASH;
     1001    g_szDir[cchDir++] = 's';
     1002
     1003    uint32_t cCreated = 0;
     1004    uint64_t nsCreate = 0;
     1005    uint64_t nsRemove = 0;
    8521006    for (;;)
    8531007    {
    8541008        /* Create a bunch: */
     1009        uint64_t nsStart = RTTimeNanoTS();
     1010        for (uint32_t i = 0; i < 998; i++)
     1011        {
     1012            RTStrFormatU32(&g_szDir[cchDir], sizeof(g_szDir) - cchDir, i, 10, 3, 3, RTSTR_F_ZEROPAD);
     1013            RTTESTI_CHECK_RC_RETV(RTDirCreate(g_szDir, 0755, 0), VINF_SUCCESS);
     1014        }
     1015        nsCreate += RTTimeNanoTS() - nsStart;
     1016        cCreated += 998;
    8551017
    8561018        /* Remove the bunch: */
     1019        nsStart = RTTimeNanoTS();
     1020        for (uint32_t i = 0; i < 998; i++)
     1021        {
     1022            RTStrFormatU32(&g_szDir[cchDir], sizeof(g_szDir) - cchDir, i, 10, 3, 3, RTSTR_F_ZEROPAD);
     1023            RTTESTI_CHECK_RC_RETV(RTDirRemove(g_szDir), VINF_SUCCESS);
     1024        }
     1025        nsRemove = RTTimeNanoTS() - nsStart;
    8571026
    8581027        /* Check if we got time for another round: */
    859         break;
    860     }
     1028        if (   (   nsRemove >= g_nsTestRun
     1029                && nsCreate >= g_nsTestRun)
     1030            || nsCreate + nsRemove >= g_nsTestRun * 3)
     1031            break;
     1032    }
     1033    RTTestIValue("RTDirCreate", nsCreate / cCreated, RTTESTUNIT_NS_PER_OCCURRENCE);
     1034    RTTestIValue("RTDirRemove", nsRemove / cCreated, RTTESTUNIT_NS_PER_OCCURRENCE);
     1035}
     1036
     1037
     1038void fsPerfStatVfs(void)
     1039{
     1040    RTTestISub("statvfs");
     1041
     1042    g_szEmptyDir[g_cchEmptyDir] = '\0';
     1043    RTFOFF   cbTotal;
     1044    RTFOFF   cbFree;
     1045    uint32_t cbBlock;
     1046    uint32_t cbSector;
     1047    RTTESTI_CHECK_RC(RTFsQuerySizes(g_szEmptyDir, &cbTotal, &cbFree, &cbBlock, &cbSector), VINF_SUCCESS);
     1048
     1049    uint32_t uSerial;
     1050    RTTESTI_CHECK_RC(RTFsQuerySerial(g_szEmptyDir, &uSerial), VINF_SUCCESS);
     1051
     1052    RTFSPROPERTIES Props;
     1053    RTTESTI_CHECK_RC(RTFsQueryProperties(g_szEmptyDir, &Props), VINF_SUCCESS);
     1054
     1055    RTFSTYPE enmType;
     1056    RTTESTI_CHECK_RC(RTFsQueryType(g_szEmptyDir, &enmType), VINF_SUCCESS);
     1057
    8611058}
    8621059
     
    9201117
    9211118
     1119void fsPerfChSize(void)
     1120{
     1121    RTTestISub("chsize");
     1122
     1123    /*
     1124     * We need some free space to perform this test.
     1125     */
     1126    RTFOFF cbFree = 0;
     1127    RTTESTI_CHECK_RC_RETV(RTFsQuerySizes(g_szDir, NULL, &cbFree, NULL, NULL), VINF_SUCCESS);
     1128    if (cbFree < _1M)
     1129    {
     1130        RTTestSkipped(g_hTest, "Insufficent free space: %'RU64 bytes, requires >= 1MB", cbFree);
     1131        return;
     1132    }
     1133
     1134    /*
     1135     * Create a file and play around with it's size.
     1136     * We let the current file position follow the end position as we make changes.
     1137     */
     1138    RTFILE hFile1;
     1139    RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile1, InDir(RT_STR_TUPLE("file20")),
     1140                                     RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE), VINF_SUCCESS);
     1141    uint64_t cbFile = UINT64_MAX;
     1142    RTTESTI_CHECK_RC(RTFileGetSize(hFile1, &cbFile), VINF_SUCCESS);
     1143    RTTESTI_CHECK(cbFile == 0);
     1144
     1145    uint8_t abBuf[4096];
     1146    static uint64_t const s_acbChanges[] =
     1147    {
     1148        1023, 1024, 1024, 1025, 8192, 11111, _1M, _8M, _8M,
     1149        _4M, _2M + 1, _1M - 1, 65537, 65536, 32768, 8000, 7999, 7998, 1024, 1, 0
     1150    };
     1151    uint64_t cbOld = 0;
     1152    for (unsigned i = 0; i < RT_ELEMENTS(s_acbChanges); i++)
     1153    {
     1154        uint64_t cbNew = s_acbChanges[i];
     1155        if (cbNew + _64K >= (uint64_t)cbFree)
     1156            continue;
     1157
     1158        RTTESTI_CHECK_RC(RTFileSetSize(hFile1, cbNew), VINF_SUCCESS);
     1159        RTTESTI_CHECK_RC(RTFileGetSize(hFile1, &cbFile), VINF_SUCCESS);
     1160        RTTESTI_CHECK_MSG(cbFile == cbNew, ("cbFile=%#RX64 cbNew=%#RX64\n", cbFile, cbNew));
     1161
     1162        if (cbNew > cbOld)
     1163        {
     1164            /* Check that the extension is all zeroed: */
     1165            uint64_t cbLeft = cbNew - cbOld;
     1166            while (cbLeft > 0)
     1167            {
     1168                memset(abBuf, 0xff, sizeof(abBuf));
     1169                size_t cbToRead = sizeof(abBuf);
     1170                if (cbToRead > cbLeft)
     1171                    cbToRead = (size_t)cbLeft;
     1172                RTTESTI_CHECK_RC(RTFileRead(hFile1, abBuf, cbToRead, NULL), VINF_SUCCESS);
     1173                RTTESTI_CHECK(ASMMemIsZero(abBuf, cbToRead));
     1174                cbLeft -= cbToRead;
     1175            }
     1176        }
     1177        else
     1178        {
     1179            /* Check that reading fails with EOF because current position is now beyond the end: */
     1180            RTTESTI_CHECK_RC(RTFileRead(hFile1, abBuf, 1, NULL), VERR_EOF);
     1181
     1182            /* Keep current position at the end of the file: */
     1183            RTTESTI_CHECK_RC(RTFileSeek(hFile1, cbNew, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
     1184        }
     1185        cbOld = cbNew;
     1186    }
     1187
     1188    /*
     1189     * Profile just the file setting operation itself, keeping the changes within
     1190     * an allocation unit to avoid needing to adjust the actual (host) FS allocation.
     1191     * ASSUMES allocation unit >= 512 and power of two.
     1192     */
     1193    RTTESTI_CHECK_RC(RTFileSetSize(hFile1, _64K), VINF_SUCCESS);
     1194    PROFILE_FN(RTFileSetSize(hFile1, _64K - (iIteration & 255) - 128), g_nsTestRun, "RTFileSetSize/noalloc");
     1195
     1196    RTTESTI_CHECK_RC(RTFileSetSize(hFile1, 0), VINF_SUCCESS);
     1197    RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
     1198    RTTESTI_CHECK_RC(RTFileDelete(g_szDir), VINF_SUCCESS);
     1199}
     1200
     1201
     1202int fsPerfIoPrepFile(RTFILE hFile1, uint64_t cbFile, uint8_t **ppbFree)
     1203{
     1204    /*
     1205     * Seek to the end - 4K and write the last 4K.
     1206     * This should have the effect of filling the whole file with zeros.
     1207     */
     1208    RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, cbFile - _4K, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck);
     1209    RTTESTI_CHECK_RC_RET(RTFileWrite(hFile1, g_abRTZero4K, _4K, NULL), VINF_SUCCESS, rcCheck);
     1210
     1211    /*
     1212     * Check that the space we searched across actually is zero filled.
     1213     */
     1214    RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck);
     1215    size_t   cbBuf = _1M;
     1216    uint8_t *pbBuf = *ppbFree = (uint8_t *)RTMemAlloc(cbBuf);
     1217    RTTESTI_CHECK_RET(pbBuf != NULL, VERR_NO_MEMORY);
     1218    uint64_t cbLeft = cbFile;
     1219    while (cbLeft > 0)
     1220    {
     1221        size_t cbToRead = cbBuf;
     1222        if (cbToRead > cbLeft)
     1223            cbToRead = (size_t)cbLeft;
     1224        pbBuf[cbToRead] = 0xff;
     1225
     1226        RTTESTI_CHECK_RC_RET(RTFileRead(hFile1, pbBuf, cbToRead, NULL), VINF_SUCCESS, rcCheck);
     1227        RTTESTI_CHECK_RET(ASMMemIsZero(pbBuf, cbToRead), VERR_MISMATCH);
     1228
     1229        cbLeft -= cbToRead;
     1230    }
     1231
     1232    /*
     1233     * Fill the file with 0xf6 and insert offset markers with 1KB intervals.
     1234     */
     1235    RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck);
     1236    memset(pbBuf, 0xf6, cbBuf);
     1237    cbLeft = cbFile;
     1238    uint64_t off = 0;
     1239    while (cbLeft > 0)
     1240    {
     1241        Assert(!(off   & (_1K - 1)));
     1242        Assert(!(cbBuf & (_1K - 1)));
     1243        for (size_t offBuf = 0; offBuf < cbBuf; offBuf += _1K, off += _1K)
     1244            *(uint64_t *)&pbBuf[offBuf] = off;
     1245
     1246        size_t cbToWrite = cbBuf;
     1247        if (cbToWrite > cbLeft)
     1248            cbToWrite = (size_t)cbLeft;
     1249
     1250        RTTESTI_CHECK_RC_RET(RTFileWrite(hFile1, pbBuf, cbToWrite, NULL), VINF_SUCCESS, rcCheck);
     1251
     1252        cbLeft -= cbToWrite;
     1253    }
     1254
     1255    return VINF_SUCCESS;
     1256}
     1257
     1258
     1259void fsPerfIoSeek(RTFILE hFile1, uint64_t cbFile)
     1260{
     1261    /*
     1262     * Do a bunch of search tests, most which are random.
     1263     */
     1264    struct
     1265    {
     1266        int         rc;
     1267        uint32_t    uMethod;
     1268        int64_t     offSeek;
     1269        uint64_t    offActual;
     1270
     1271    } aSeeks[9 + 64] =
     1272    {
     1273        { VINF_SUCCESS,         RTFILE_SEEK_BEGIN,    0,                        0 },
     1274        { VINF_SUCCESS,         RTFILE_SEEK_CURRENT,  0,                        0 },
     1275        { VINF_SUCCESS,         RTFILE_SEEK_END,      0,                        cbFile },
     1276        { VINF_SUCCESS,         RTFILE_SEEK_CURRENT,  -4096,                    cbFile - 4096 },
     1277        { VINF_SUCCESS,         RTFILE_SEEK_CURRENT,  4096 - (int64_t)cbFile,   0 },
     1278        { VINF_SUCCESS,         RTFILE_SEEK_END,      -(int64_t)cbFile/2,       cbFile / 2 + (cbFile & 1) },
     1279        { VINF_SUCCESS,         RTFILE_SEEK_CURRENT,  -(int64_t)cbFile/2,       0 },
     1280        { VERR_NEGATIVE_SEEK,   RTFILE_SEEK_CURRENT,  -1,                       0 },
     1281        { VINF_SUCCESS,         RTFILE_SEEK_CURRENT,  0,                        0 },
     1282    };
     1283
     1284    uint64_t offActual = 0;
     1285    for (unsigned i = 9; i < RT_ELEMENTS(aSeeks); i++)
     1286    {
     1287        switch (RTRandU32Ex(RTFILE_SEEK_BEGIN, RTFILE_SEEK_END))
     1288        {
     1289            default: AssertFailed();
     1290            case RTFILE_SEEK_BEGIN:
     1291                aSeeks[i].uMethod   = RTFILE_SEEK_BEGIN;
     1292                aSeeks[i].rc        = VINF_SUCCESS;
     1293                aSeeks[i].offSeek   = RTRandU64Ex(0, cbFile + cbFile / 8);
     1294                aSeeks[i].offActual = offActual = aSeeks[i].offSeek;
     1295                break;
     1296
     1297            case RTFILE_SEEK_CURRENT:
     1298                aSeeks[i].uMethod   = RTFILE_SEEK_CURRENT;
     1299                aSeeks[i].rc        = VINF_SUCCESS;
     1300                aSeeks[i].offSeek   = (int64_t)RTRandU64Ex(0, cbFile + cbFile / 8) - (int64_t)offActual;
     1301                aSeeks[i].offActual = offActual += aSeeks[i].offSeek;
     1302                break;
     1303
     1304            case RTFILE_SEEK_END:
     1305                aSeeks[i].uMethod   = RTFILE_SEEK_END;
     1306                aSeeks[i].rc        = VINF_SUCCESS;
     1307                aSeeks[i].offSeek   = -(int64_t)RTRandU64Ex(0, cbFile);
     1308                aSeeks[i].offActual = offActual = cbFile + aSeeks[i].offSeek;
     1309                break;
     1310        }
     1311    }
     1312
     1313    for (unsigned iDoReadCheck = 0; iDoReadCheck < 2; iDoReadCheck++)
     1314    {
     1315        for (uint32_t i = 0; i < RT_ELEMENTS(aSeeks); i++)
     1316        {
     1317            offActual = UINT64_MAX;
     1318            int rc = RTFileSeek(hFile1, aSeeks[i].offSeek, aSeeks[i].uMethod, &offActual);
     1319            if (rc != aSeeks[i].rc)
     1320                RTTestIFailed("Seek #%u: Expected %Rrc, got %Rrc", i, aSeeks[i].rc, rc);
     1321            if (RT_SUCCESS(rc) && offActual != aSeeks[i].offActual)
     1322                RTTestIFailed("Seek #%u: offActual %#RX64, expected %#RX64", i, offActual, aSeeks[i].offActual);
     1323            if (RT_SUCCESS(rc))
     1324            {
     1325                uint64_t offTell = RTFileTell(hFile1);
     1326                if (offTell != offActual)
     1327                    RTTestIFailed("Seek #%u: offActual %#RX64, RTFileTell %#RX64", i, offActual, offTell);
     1328            }
     1329
     1330            if (RT_SUCCESS(rc) && offActual + _2K <= cbFile && iDoReadCheck)
     1331            {
     1332                uint8_t abBuf[_2K];
     1333                RTTESTI_CHECK_RC(rc = RTFileRead(hFile1, abBuf, sizeof(abBuf), NULL), VINF_SUCCESS);
     1334                if (RT_SUCCESS(rc))
     1335                {
     1336                    size_t offMarker = (size_t)(RT_ALIGN_64(offActual, _1K) - offActual);
     1337                    uint64_t uMarker = *(uint64_t *)&abBuf[offMarker]; /** @todo potentially unaligned access */
     1338                    if (uMarker != offActual + offMarker)
     1339                        RTTestIFailed("Seek #%u: Invalid marker value (@ %#RX64): %#RX64, expected %#RX64",
     1340                                      i, offActual, uMarker, offActual + offMarker);
     1341
     1342                    RTTESTI_CHECK_RC(RTFileSeek(hFile1, -(int64_t)sizeof(abBuf), RTFILE_SEEK_CURRENT, NULL), VINF_SUCCESS);
     1343                }
     1344            }
     1345        }
     1346    }
     1347
     1348
     1349    /*
     1350     * Profile seeking relative to the beginning of the file and relative
     1351     * to the end.  The latter might be more expensive in a SF context.
     1352     */
     1353    PROFILE_FN(RTFileSeek(hFile1, iIteration < cbFile ? iIteration : iIteration % cbFile, RTFILE_SEEK_BEGIN, NULL),
     1354               g_nsTestRun, "RTFileSeek/BEGIN");
     1355    PROFILE_FN(RTFileSeek(hFile1, iIteration < cbFile ? -(int64_t)iIteration : -(int64_t)(iIteration % cbFile), RTFILE_SEEK_END, NULL),
     1356               g_nsTestRun, "RTFileSeek/END");
     1357
     1358}
     1359
     1360
     1361DECL_FORCE_INLINE(int) fsPerfIoReadWorker(RTFILE hFile1, uint64_t cbFile, uint32_t cbBlock, uint8_t *pbBlock,
     1362                                          uint64_t *poffActual, uint32_t *pcSeeks)
     1363{
     1364    /* Do we need to seek back to the start? */
     1365    if (*poffActual + cbBlock <= cbFile)
     1366    { /* likely */ }
     1367    else
     1368    {
     1369        RTTESTI_CHECK_RC_RET(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck);
     1370        *pcSeeks += 1;
     1371        *poffActual = 0;
     1372    }
     1373
     1374    size_t cbActuallyRead = 0;
     1375    RTTESTI_CHECK_RC_RET(RTFileRead(hFile1, pbBlock, cbBlock, &cbActuallyRead), VINF_SUCCESS, rcCheck);
     1376    if (cbActuallyRead == cbBlock)
     1377    {
     1378        *poffActual += cbActuallyRead;
     1379        return VINF_SUCCESS;
     1380    }
     1381    RTTestIFailed("RTFileRead at %#RX64 returned just %#x bytes, expected %#x", *poffActual, cbActuallyRead, cbBlock);
     1382    *poffActual += cbActuallyRead;
     1383    return VERR_READ_ERROR;
     1384}
     1385
     1386
     1387void fsPerfIoRead(RTFILE hFile1, uint64_t cbFile, uint32_t cbBlock, uint8_t **ppbFree)
     1388{
     1389    RTTestISubF("read %RU32", cbBlock);
     1390
     1391    uint8_t *pbBuf = *ppbFree = (uint8_t *)RTMemPageAlloc(cbBlock);
     1392    if (!pbBuf)
     1393    {
     1394        RTTestSkipped(g_hTest, "insufficient (virtual) memory available");
     1395        return;
     1396    }
     1397
     1398    char szDesc[64];
     1399    RTStrPrintf(szDesc, sizeof(szDesc), "RTFileRead/seq/%RU32", cbBlock);
     1400
     1401    RTTESTI_CHECK_RC_RETV(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
     1402    uint64_t offActual = 0;
     1403    uint32_t cSeeks    = 0;
     1404
     1405    /* Estimate how many iterations we need to fill up the given timeslot: */
     1406    fsPerfYield();
     1407    uint64_t nsStart = RTTimeNanoTS();
     1408    uint64_t ns;
     1409    do
     1410        ns = RTTimeNanoTS();
     1411    while (ns == nsStart);
     1412    nsStart = ns;
     1413
     1414    uint32_t iIteration = 0;
     1415    do
     1416    {
     1417        RTTESTI_CHECK_RC_RETV(fsPerfIoReadWorker(hFile1, cbFile, cbBlock, pbBuf, &offActual, &cSeeks), VINF_SUCCESS);
     1418        iIteration++;
     1419        ns = RTTimeNanoTS() - nsStart;
     1420    } while (ns < RT_NS_10MS);
     1421    ns /= iIteration;
     1422    if (ns > g_nsPerNanoTSCall)
     1423        ns -= g_nsPerNanoTSCall;
     1424    uint32_t const cIterations = g_nsTestRun / ns;
     1425
     1426    /* Do the actual profiling: */
     1427    cSeeks = 0;
     1428    fsPerfYield();
     1429    nsStart = RTTimeNanoTS();
     1430    for (iIteration = 0; iIteration < cIterations; iIteration++)
     1431    {
     1432        fsPerfIoReadWorker(hFile1, cbFile, cbBlock, pbBuf, &offActual, &cSeeks);
     1433    }
     1434    ns = RTTimeNanoTS() - nsStart;
     1435    RTTestIValueF(ns / iIteration,
     1436                  RTTESTUNIT_NS_PER_OCCURRENCE, "RTFileRead/seq/%RU32 latency", cbBlock);
     1437    RTTestIValueF((uint64_t)iIteration * cbBlock / ((double)ns / RT_NS_1SEC),
     1438                  RTTESTUNIT_BYTES_PER_SEC,     "RTFileRead/seq/%RU32 throughput", cbBlock);
     1439    RTTestIValueF(iIteration,
     1440                  RTTESTUNIT_CALLS,             "RTFileRead/seq/%RU32 calls", cbBlock);
     1441    RTTestIValueF((uint64_t)iIteration * cbBlock,
     1442                  RTTESTUNIT_BYTES,             "RTFileRead/seq/%RU32 bytes", cbBlock);
     1443    RTTestIValueF(cSeeks,
     1444                  RTTESTUNIT_OCCURRENCES,       "RTFileRead/seq/%RU32 seeks", cbBlock);
     1445}
     1446
     1447
     1448void fsPerfIoWrite(RTFILE hFile1, uint64_t cbFile, uint32_t cbBlock, uint8_t **ppbFree)
     1449{
     1450    RT_NOREF(hFile1, cbFile, cbBlock, ppbFree);
     1451}
     1452
     1453
     1454/**
     1455 * This does the read, write and seek tests.
     1456 */
     1457void fsPerfIo(void)
     1458{
     1459    RTTestISub("I/O");
     1460
     1461    /*
     1462     * Determin the size of the test file.
     1463     */
     1464    g_szDir[g_cchDir] = '\0';
     1465    RTFOFF cbFree = 0;
     1466    RTTESTI_CHECK_RC_RETV(RTFsQuerySizes(g_szDir, NULL, &cbFree, NULL, NULL), VINF_SUCCESS);
     1467    uint64_t cbFile = g_cbIoFile;
     1468    if (cbFile + _16M < (uint64_t)cbFree)
     1469        cbFile = RT_ALIGN_64(cbFile, _64K);
     1470    else
     1471    {
     1472        if (cbFree < _32M)
     1473        {
     1474            RTTestSkipped(g_hTest, "Insufficent free space: %'RU64 bytes, requires >= 32MB", cbFree);
     1475            return;
     1476        }
     1477        cbFile = cbFree - (cbFree > _128M ? _64M : _16M);
     1478        cbFile = RT_ALIGN_64(cbFile, _64K);
     1479        RTTestIPrintf(RTTESTLVL_ALWAYS,  "Adjusted file size to %'RU64 bytes, due to %'RU64 bytes free.\n", cbFile, cbFree);
     1480    }
     1481    if (cbFile < _64K)
     1482    {
     1483        RTTestSkipped(g_hTest, "Specified test file size too small: %'RU64 bytes, requires >= 64KB", cbFile);
     1484        return;
     1485    }
     1486
     1487    /*
     1488     * Create a cbFile sized test file.
     1489     */
     1490    RTFILE hFile1;
     1491    RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile1, InDir(RT_STR_TUPLE("file21")),
     1492                                     RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE), VINF_SUCCESS);
     1493    uint8_t *pbFree = NULL;
     1494    int rc = fsPerfIoPrepFile(hFile1, cbFile, &pbFree);
     1495    RTMemFree(pbFree);
     1496    if (RT_SUCCESS(rc))
     1497    {
     1498        /*
     1499         * Do the testing & profiling.
     1500         */
     1501        if (g_fSeek)
     1502            fsPerfIoSeek(hFile1, cbFile);
     1503        if (g_fRead)
     1504            for (unsigned i = 0; i < g_cIoBlocks; i++)
     1505            {
     1506                pbFree = NULL;
     1507                fsPerfIoRead(hFile1, cbFile, g_acbIoBlocks[i], &pbFree);
     1508                RTMemPageFree(pbFree, g_acbIoBlocks[i]);
     1509            }
     1510        if (g_fWrite)
     1511            for (unsigned i = 0; i < g_cIoBlocks; i++)
     1512            {
     1513                pbFree = NULL;
     1514                fsPerfIoWrite(hFile1, cbFile, g_acbIoBlocks[i], &pbFree);
     1515                RTMemPageFree(pbFree, g_acbIoBlocks[i]);
     1516            }
     1517    }
     1518
     1519    RTTESTI_CHECK_RC(RTFileSetSize(hFile1, 0), VINF_SUCCESS);
     1520    RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
     1521    RTTESTI_CHECK_RC(RTFileDelete(g_szDir), VINF_SUCCESS);
     1522}
     1523
     1524
    9221525static void Usage(PRTSTREAM pStrm)
    9231526{
     
    9281531    RTStrmPrintf(pStrm, "options: \n");
    9291532
    930 
    9311533    for (unsigned i = 0; i < RT_ELEMENTS(g_aCmdOptions); i++)
    9321534    {
     1535        char szHelp[80];
    9331536        const char *pszHelp;
    9341537        switch (g_aCmdOptions[i].iShort)
    9351538        {
    9361539            case 'd':   pszHelp = "The directory to use for testing.  Default: CWD/fstestdir"; break;
    937             case 's':   pszHelp = "Benchmark duration.  Default: 10 sec"; break;
     1540            case 'e':   pszHelp = "Enables all tests.   Default: -e"; break;
     1541            case 'z':   pszHelp = "Disables all tests.  Default: -e"; break;
     1542            case 's':   pszHelp = "Set benchmark duration in seconds.  Default: 10 sec"; break;
     1543            case 'm':   pszHelp = "Set benchmark duration in milliseconds.  Default: 10000 ms"; break;
    9381544            case 'v':   pszHelp = "More verbose execution."; break;
    9391545            case 'q':   pszHelp = "Quiet execution."; break;
     
    9411547            case 'V':   pszHelp = "Displays the program revision"; break;
    9421548            default:
    943                 pszHelp = "Option undocumented";
     1549                if (g_aCmdOptions[i].iShort >= kCmdOpt_First)
     1550                {
     1551                    if (RTStrStartsWith(g_aCmdOptions[i].pszLong, "--no-"))
     1552                        RTStrPrintf(szHelp, sizeof(szHelp), "Disables the '%s' test.", g_aCmdOptions[i].pszLong + 5);
     1553                    else
     1554                        RTStrPrintf(szHelp, sizeof(szHelp), "Enables  the '%s' test.", g_aCmdOptions[i].pszLong + 2);
     1555                    pszHelp = szHelp;
     1556                }
     1557                else
     1558                    pszHelp = "Option undocumented";
    9441559                break;
    9451560        }
    946         char szOpt[256];
    947         RTStrPrintf(szOpt, sizeof(szOpt), "%s, -%c", g_aCmdOptions[i].pszLong, g_aCmdOptions[i].iShort);
    948         RTStrmPrintf(pStrm, "  %-20s%s\n", szOpt, pszHelp);
     1561        if ((unsigned)g_aCmdOptions[i].iShort < 127U)
     1562        {
     1563            char szOpt[64];
     1564            RTStrPrintf(szOpt, sizeof(szOpt), "%s, -%c", g_aCmdOptions[i].pszLong, g_aCmdOptions[i].iShort);
     1565            RTStrmPrintf(pStrm, "  %-20s%s\n", szOpt, pszHelp);
     1566        }
     1567        else
     1568            RTStrmPrintf(pStrm, "  %-20s%s\n", g_aCmdOptions[i].pszLong, pszHelp);
    9491569    }
    9501570}
     
    9981618                    g_nsTestRun = ValueUnion.u32 * RT_NS_1SEC_64;
    9991619                break;
     1620
     1621            case 'm':
     1622                if (ValueUnion.u64 == 0)
     1623                    g_nsTestRun = RT_NS_1SEC_64 * 10;
     1624                else
     1625                    g_nsTestRun = ValueUnion.u64 * RT_NS_1MS;
     1626                break;
     1627
     1628            case 'e':
     1629                g_fManyFiles = true;
     1630                g_fOpen      = true;
     1631                g_fFStat     = true;
     1632                g_fFChMod    = true;
     1633                g_fFUtimes   = true;
     1634                g_fStat      = true;
     1635                g_fChMod     = true;
     1636                g_fUtimes    = true;
     1637                g_fRename    = true;
     1638                g_fDirEnum   = true;
     1639                g_fMkRmDir   = true;
     1640                g_fStatVfs   = true;
     1641                g_fRm        = true;
     1642                g_fChSize    = true;
     1643                g_fRead      = true;
     1644                g_fWrite     = true;
     1645                g_fSeek      = true;
     1646                break;
     1647
     1648            case 'z':
     1649                g_fManyFiles = false;
     1650                g_fOpen      = false;
     1651                g_fFStat     = false;
     1652                g_fFChMod    = false;
     1653                g_fFUtimes   = false;
     1654                g_fStat      = false;
     1655                g_fChMod     = false;
     1656                g_fUtimes    = false;
     1657                g_fRename    = false;
     1658                g_fDirEnum   = false;
     1659                g_fMkRmDir   = false;
     1660                g_fStatVfs   = false;
     1661                g_fRm        = false;
     1662                g_fChSize    = false;
     1663                g_fRead      = false;
     1664                g_fWrite     = false;
     1665                g_fSeek      = false;
     1666                break;
     1667
     1668#define CASE_OPT(a_Stem) \
     1669            case RT_CONCAT(kCmdOpt_,a_Stem):   RT_CONCAT(g_f,a_Stem) = true; break; \
     1670            case RT_CONCAT(kCmdOpt_No,a_Stem): RT_CONCAT(g_f,a_Stem) = false; break
     1671            CASE_OPT(ManyFiles);
     1672            CASE_OPT(Open);
     1673            CASE_OPT(FStat);
     1674            CASE_OPT(FChMod);
     1675            CASE_OPT(FUtimes);
     1676            CASE_OPT(Stat);
     1677            CASE_OPT(ChMod);
     1678            CASE_OPT(Utimes);
     1679            CASE_OPT(Rename);
     1680            CASE_OPT(DirEnum);
     1681            CASE_OPT(MkRmDir);
     1682            CASE_OPT(StatVfs);
     1683            CASE_OPT(Rm);
     1684            CASE_OPT(ChSize);
     1685            CASE_OPT(Seek);
     1686            CASE_OPT(Read);
     1687            CASE_OPT(Write);
     1688#undef CASE_OPT
    10001689
    10011690            case 'q':
     
    10611750                if (RT_SUCCESS(rc))
    10621751                {
    1063                     //g_fManyFiles = false;
     1752                    /* Profile RTTimeNanoTS(). */
     1753                    fsPerfNanoTS();
    10641754
    10651755                    /* Do tests: */
    10661756                    if (g_fManyFiles)
    10671757                        fsPerfManyFiles();
    1068 #if 1
    1069                     fsPerfOpen();
    1070                     fsPerfFStat();
    1071                     fsPerfFChMod();
    1072                     fsPerfFUtimes();
    1073                     fsPerfStat();
    1074                     fsPerfChmod();
    1075                     fsPerfUtimes();
    1076                     fsPerfRename();
    1077                     vsPerfDirEnum();
    1078 #endif
    1079                     fsPerfMkDirRmDir();
    1080                     /// @todo fsPerfRead
    1081                     /// @todo fsPerfWrite
    1082                     /// @todo fsPerfSeek
    1083                     /// @todo fsPerfChSize
    1084                     fsPerfRm(); /* must come last as it deletes manyfiles and manytree */
     1758                    if (g_fOpen)
     1759                        fsPerfOpen();
     1760                    if (g_fFStat)
     1761                        fsPerfFStat();
     1762                    if (g_fFChMod)
     1763                        fsPerfFChMod();
     1764                    if (g_fFUtimes)
     1765                        fsPerfFUtimes();
     1766                    if (g_fStat)
     1767                        fsPerfStat();
     1768                    if (g_fChMod)
     1769                        fsPerfChmod();
     1770                    if (g_fUtimes)
     1771                        fsPerfUtimes();
     1772                    if (g_fRename)
     1773                        fsPerfRename();
     1774                    if (g_fDirEnum)
     1775                        vsPerfDirEnum();
     1776                    if (g_fMkRmDir)
     1777                        fsPerfMkRmDir();
     1778                    if (g_fStatVfs)
     1779                        fsPerfStatVfs();
     1780                    if (g_fRm || g_fManyFiles)
     1781                        fsPerfRm(); /* deletes manyfiles and manytree */
     1782                    if (g_fChSize)
     1783                        fsPerfChSize();
     1784                    if (g_fRead || g_fWrite || g_fSeek)
     1785                        fsPerfIo();
    10851786                }
    10861787            }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette