VirtualBox

Changeset 31455 in vbox for trunk/src


Ignore:
Timestamp:
Aug 8, 2010 1:34:51 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
64528
Message:

VBoxFUSE: Add write support and fix Linux build

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ImageMounter/VBoxFUSE/VBoxFUSE.cpp

    r28800 r31455  
    3434# ifdef EBADMACHO
    3535#  define EDOOFUS EBADMACHO
    36 # elif
     36# elif defined(EPROTO)
    3737#  define EDOOFUS EPROTO                /* What a boring lot. */
    3838//# elif defined(EXYZ)
     
    531531    if (RT_SUCCESS(rc))
    532532    {
    533         rc = VDOpen(pDisk, pszFormat, pszImage, VD_OPEN_FLAGS_READONLY, NULL /* pVDIfsImage */);
     533        rc = VDOpen(pDisk, pszFormat, pszImage, 0, NULL /* pVDIfsImage */);
    534534        if (RT_FAILURE(rc))
    535535        {
     
    12711271
    12721272
     1273/** @copydoc fuse_operations::write */
     1274static int vboxfuseOp_write(const char *pszPath, const char *pbBuf, size_t cbBuf,
     1275                           off_t offFile, struct fuse_file_info *pInfo)
     1276{
     1277    /* paranoia */
     1278    AssertReturn((int)cbBuf >= 0, -EINVAL);
     1279    AssertReturn((unsigned)cbBuf == cbBuf, -EINVAL);
     1280    AssertReturn(offFile >= 0, -EINVAL);
     1281    AssertReturn((off_t)(offFile + cbBuf) >= offFile, -EINVAL);
     1282
     1283    PVBOXFUSENODE pNode = (PVBOXFUSENODE)(uintptr_t)pInfo->fh;
     1284    AssertPtr(pNode);
     1285    switch (pNode->enmType)
     1286    {
     1287        case VBOXFUSETYPE_DIRECTORY:
     1288            return -ENOTSUP;
     1289
     1290        case VBOXFUSETYPE_FLAT_IMAGE:
     1291        {
     1292            PVBOXFUSEFLATIMAGE pFlatImage = (PVBOXFUSEFLATIMAGE)(uintptr_t)pInfo->fh;
     1293            LogFlow(("vboxfuseOp_write: offFile=%#llx cbBuf=%#zx pszPath=\"%s\"\n", (uint64_t)offFile, cbBuf, pszPath));
     1294            vboxfuseNodeLock(&pFlatImage->Node);
     1295
     1296            int rc;
     1297            if ((off_t)(offFile + cbBuf) < offFile)
     1298                rc = -EINVAL;
     1299            else if (offFile >= pFlatImage->Node.cbPrimary)
     1300                rc = 0;
     1301            else if (!cbBuf)
     1302                rc = 0;
     1303            else
     1304            {
     1305                /* Adjust for EOF. */
     1306                if ((off_t)(offFile + cbBuf) >= pFlatImage->Node.cbPrimary)
     1307                    cbBuf = pFlatImage->Node.cbPrimary - offFile;
     1308
     1309                /*
     1310                 * Aligned write?
     1311                 */
     1312                int rc2;
     1313                if (    !(offFile & VBOXFUSE_MIN_SIZE_MASK_OFF)
     1314                    &&  !(cbBuf   & VBOXFUSE_MIN_SIZE_MASK_OFF))
     1315                    rc2 = VDWrite(pFlatImage->pDisk, offFile, pbBuf, cbBuf);
     1316                else
     1317                {
     1318                    /*
     1319                     * Unaligned write - lots of extra work.
     1320                     */
     1321                    uint8_t abBlock[VBOXFUSE_MIN_SIZE];
     1322                    if (((offFile + cbBuf) & VBOXFUSE_MIN_SIZE_MASK_BLK) == (offFile & VBOXFUSE_MIN_SIZE_MASK_BLK))
     1323                    {
     1324                        /* a single partial block. */
     1325                        rc2 = VDRead(pFlatImage->pDisk, offFile & VBOXFUSE_MIN_SIZE_MASK_BLK, abBlock, VBOXFUSE_MIN_SIZE);
     1326                        if (RT_SUCCESS(rc2))
     1327                        {
     1328                            memcpy(&abBlock[offFile & VBOXFUSE_MIN_SIZE_MASK_OFF], pbBuf, cbBuf);
     1329                            /* Update the block */
     1330                            rc2 = VDWrite(pFlatImage->pDisk, offFile & VBOXFUSE_MIN_SIZE_MASK_BLK, abBlock, VBOXFUSE_MIN_SIZE);
     1331                        }
     1332                    }
     1333                    else
     1334                    {
     1335                        /* read unaligned head. */
     1336                        rc2 = VINF_SUCCESS;
     1337                        if (offFile & VBOXFUSE_MIN_SIZE_MASK_OFF)
     1338                        {
     1339                            rc2 = VDRead(pFlatImage->pDisk, offFile & VBOXFUSE_MIN_SIZE_MASK_BLK, abBlock, VBOXFUSE_MIN_SIZE);
     1340                            if (RT_SUCCESS(rc2))
     1341                            {
     1342                                size_t cbCopy = VBOXFUSE_MIN_SIZE - (offFile & VBOXFUSE_MIN_SIZE_MASK_OFF);
     1343                                memcpy(&abBlock[offFile & VBOXFUSE_MIN_SIZE_MASK_OFF], pbBuf, cbCopy);
     1344                                pbBuf   += cbCopy;
     1345                                offFile += cbCopy;
     1346                                cbBuf   -= cbCopy;
     1347                                rc2 = VDWrite(pFlatImage->pDisk, offFile & VBOXFUSE_MIN_SIZE_MASK_BLK, abBlock, VBOXFUSE_MIN_SIZE);
     1348                            }
     1349                        }
     1350
     1351                        /* write the middle. */
     1352                        Assert(!(offFile & VBOXFUSE_MIN_SIZE_MASK_OFF));
     1353                        if (cbBuf >= VBOXFUSE_MIN_SIZE && RT_SUCCESS(rc2))
     1354                        {
     1355                            size_t cbWrite = cbBuf & VBOXFUSE_MIN_SIZE_MASK_BLK;
     1356                            rc2 = VDWrite(pFlatImage->pDisk, offFile, pbBuf, cbWrite);
     1357                            if (RT_SUCCESS(rc2))
     1358                            {
     1359                                pbBuf   += cbWrite;
     1360                                offFile += cbWrite;
     1361                                cbBuf   -= cbWrite;
     1362                            }
     1363                        }
     1364
     1365                        /* unaligned tail write. */
     1366                        Assert(cbBuf < VBOXFUSE_MIN_SIZE);
     1367                        Assert(!(offFile & VBOXFUSE_MIN_SIZE_MASK_OFF));
     1368                        if (cbBuf && RT_SUCCESS(rc2))
     1369                        {
     1370                            rc2 = VDRead(pFlatImage->pDisk, offFile, abBlock, VBOXFUSE_MIN_SIZE);
     1371                            if (RT_SUCCESS(rc2))
     1372                            {
     1373                                memcpy(&abBlock[0], pbBuf, cbBuf);
     1374                                rc2 = VDWrite(pFlatImage->pDisk, offFile, abBlock, VBOXFUSE_MIN_SIZE);
     1375                            }
     1376                        }
     1377                    }
     1378                }
     1379
     1380                /* convert the return code */
     1381                if (RT_SUCCESS(rc2))
     1382                    rc = cbBuf;
     1383                else
     1384                    rc = -RTErrConvertToErrno(rc2);
     1385            }
     1386
     1387            vboxfuseNodeUnlock(&pFlatImage->Node);
     1388            return rc;
     1389        }
     1390
     1391        case VBOXFUSETYPE_CONTROL_PIPE:
     1392            return -ENOTSUP;
     1393
     1394        default:
     1395            AssertMsgFailed(("%s\n", pszPath));
     1396            return -EDOOFUS;
     1397    }
     1398}
     1399
     1400
    12731401/**
    12741402 * The FUSE operations.
     
    13231451    g_vboxfuseOps.open       = vboxfuseOp_open;
    13241452    g_vboxfuseOps.read       = vboxfuseOp_read;
     1453    g_vboxfuseOps.write      = vboxfuseOp_write;
    13251454    g_vboxfuseOps.release    = vboxfuseOp_release;
    13261455
Note: See TracChangeset for help on using the changeset viewer.

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