VirtualBox

Changeset 77959 in vbox for trunk


Ignore:
Timestamp:
Mar 29, 2019 9:12:05 PM (6 years ago)
Author:
vboxsync
Message:

linux/vboxsf: Invalidate the page cache pages for an inode if we think the host might have modified the file. bugref:9172

Location:
trunk/src/VBox/Additions/linux/sharedfolders
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/sharedfolders/regops.c

    r77953 r77959  
    929929                    /* Check that we don't have signals pending before we issue the write, as
    930930                       we'll only end up having to cancel the HGCM request 99% of the time: */
    931                     if (!signal_pending(current))
     931                    if (!signal_pending(current)) {
    932932                        vrc = VbglR0SfHostReqWritePgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile,
    933933                                                        cbToWrite, cPagesToWrite);
    934                     else
     934                        sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
     935                    } else
    935936                        vrc = VERR_INTERRUPTED;
    936937                    if (RT_SUCCESS(vrc)) {
     
    18131814             */
    18141815            rc = VbglR0SfHostReqWritePgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile, cbChunk, cPages);
     1816            sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
    18151817            if (RT_SUCCESS(rc)) {
    18161818                /*
     
    19391941                int vrc = VbglR0SfHostReqWriteEmbedded(pSuperInfo->map.root, pReq, sf_r->Handle.hHost,
    19401942                                                       pos, (uint32_t)size);
     1943                sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
    19411944                if (RT_SUCCESS(vrc)) {
    19421945                    cbRet = pReq->Parms.cb32Write.u.value32;
     
    19731976                    ssize_t cbRet;
    19741977                    int vrc = VbglR0SfHostReqWriteContig(pSuperInfo->map.root, pReq, sf_r->handle, pos,
    1975                                          (uint32_t)size, pvBounce, virt_to_phys(pvBounce));
     1978                                                         (uint32_t)size, pvBounce, virt_to_phys(pvBounce));
     1979                    sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
    19761980                    if (RT_SUCCESS(vrc)) {
    19771981                        cbRet = pReq->Parms.cb32Write.u.value32;
     
    26362640             */
    26372641            rc = VbglR0SfHostReqWritePgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile, cbChunk, cPages);
     2642            sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
    26382643            SFLOGFLOW(("vbsf_reg_write_iter_locking: VbglR0SfHostReqWritePgLst -> %d (cbActual=%#x cbChunk=%#zx of %#zx cPages=%#zx offPage0=%#x\n",
    26392644                       rc, pReq->Parms.cb32Write.u.value32, cbChunk, cbToWrite, cPages, offPage0));
     
    27942799                    int vrc = VbglR0SfHostReqWriteEmbedded(pSuperInfo->map.root, pReq, sf_r->Handle.hHost,
    27952800                                                           offFile, (uint32_t)cbToWrite);
     2801                    sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
    27962802                    if (RT_SUCCESS(vrc)) {
    27972803                        cbRet = pReq->Parms.cb32Write.u.value32;
     
    35493555                                            cbToWrite,
    35503556                                            1 /*cPages*/);
     3557            sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
    35513558            AssertMsgStmt(pReq->Parms.cb32Write.u.value32 == cbToWrite || RT_FAILURE(vrc), /* lazy bird */
    35523559                          ("%#x vs %#x\n", pReq->Parms.cb32Write, cbToWrite),
  • trunk/src/VBox/Additions/linux/sharedfolders/utils.c

    r77953 r77959  
    357357    vbsf_time_to_linux(&inode->i_mtime, &pObjInfo->ModificationTime);
    358358    sf_i->BirthTime = pObjInfo->BirthTime;
     359    sf_i->ModificationTime = pObjInfo->ModificationTime;
     360    RTTimeSpecSetSeconds(&sf_i->ModificationTimeAtOurLastWrite, 0);
    359361}
    360362
     
    369371{
    370372    PCSHFLFSOBJATTR pAttr = &pObjInfo->Attr;
    371     int fMode;
     373    int             fMode;
    372374
    373375    TRACE();
     
    426428    /*
    427429     * Mark it as up to date.
     430     * Best to do this before we start with any expensive map invalidation.
    428431     */
    429432    pInodeInfo->ts_up_to_date = jiffies;
    430433    pInodeInfo->force_restat  = 0;
    431434
     435    /*
     436     * If the modification time changed, we may have to invalidate the page
     437     * cache pages associated with this inode if we suspect the change was
     438     * made by the host.  How supicious we are depends on the cache mode.
     439     *
     440     * Note! The invalidate_inode_pages() call is pretty weak.  It will _not_
     441     *       touch pages that are already mapped into an address space, but it
     442     *       will help if the file isn't currently mmap'ed or if we're in read
     443     *       or read/write caching mode.
     444     */
     445    if (!RTTimeSpecIsEqual(&pInodeInfo->ModificationTime, &pObjInfo->ModificationTime)) {
     446        if (RTFS_IS_FILE(pAttr->fMode)) {
     447            bool fInvalidate;
     448            if (pSuperInfo->enmCacheMode == kVbsfCacheMode_None) {
     449                fInvalidate = true;      /* No-caching: always invalidate. */
     450            } else {
     451                /** @todo Seeing nano-seconds being chopped off by someone before we get
     452                 *        here. weird weird weird.  Must be host side.   */
     453                if (RTTimeSpecIsEqual(&pInodeInfo->ModificationTimeAtOurLastWrite, &pInodeInfo->ModificationTime)) {
     454                    fInvalidate = false; /* Could be our write, so don't invalidate anything */
     455                    RTTimeSpecSetSeconds(&pInodeInfo->ModificationTimeAtOurLastWrite, 0);
     456                } else {
     457                    /* RTLogBackdoorPrintf("vbsf_update_inode: Invalidating the mapping %s - %RU64 vs %RU64 vs %RU64\n",
     458                       pInodeInfo->path->String.ach, RTTimeSpecGetNano(&pInodeInfo->ModificationTimeAtOurLastWrite),
     459                       RTTimeSpecGetNano(&pInodeInfo->ModificationTime), RTTimeSpecGetNano(&pObjInfo->ModificationTime) ); */
     460                    fInvalidate = true;  /* We haven't modified the file recently, so probably a host update. */
     461                }
     462            }
     463            pInodeInfo->ModificationTime = pObjInfo->ModificationTime;
     464
     465            if (fInvalidate) {
     466                struct address_space *mapping = pInode->i_mapping;
     467                if (mapping && mapping->nrpages > 0) {
     468                    SFLOGFLOW(("vbsf_update_inode: Invalidating the mapping (%s)\n", pInodeInfo->path->String.ach));
     469#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
     470                    invalidate_mapping_pages(mapping, 0, ~(pgoff_t)0);
     471#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
     472                    invalidate_inode_pages(mapping);
     473#else
     474                    invalidate_inode_pages(pInode);
     475#endif
     476                }
     477            }
     478        } else
     479            pInodeInfo->ModificationTime = pObjInfo->ModificationTime;
     480    }
     481
     482    /*
     483     * Done.
     484     */
    432485#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
    433486    if (!fInodeLocked)
     
    462515                if (!ok_to_fail)
    463516                    LogFunc(("VbglR0SfHostReqCreate on %s: file does not exist: %d (caller=%s)\n",
    464                          path->String.utf8, pReq->CreateParms.Result, caller));
     517                             path->String.utf8, pReq->CreateParms.Result, caller));
    465518                rc = -ENOENT;
    466519            }
     
    10811134             *       and ignore the dentry timestamp for positive entries.
    10821135             */
    1083             //struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(pInode);
    10841136            unsigned long const     cJiffiesAge = jiffies - vbsf_dentry_get_update_jiffies(dentry);
    10851137            struct vbsf_super_info *pSuperInfo  = VBSF_GET_SUPER_INFO(dentry->d_sb);
     
    10881140                rc = 1;
    10891141            } else if (!vbsf_inode_revalidate_worker(dentry, true /*fForced*/, false /*fInodeLocked*/)) {
    1090                 vbsf_dentry_set_update_jiffies(dentry, jiffies); /** @todo get jiffies from inode. */
     1142                vbsf_dentry_set_update_jiffies(dentry, jiffies);
    10911143                SFLOGFLOW(("vbsf_dentry_revalidate: age: %lu vs. TTL %lu -> reval -> 1\n", cJiffiesAge, pSuperInfo->cJiffiesDirCacheTTL));
    10921144                rc = 1;
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c

    r77953 r77959  
    352352{
    353353    int rc = 0;
    354 /** @todo this needs sorting out between 3.19 and 4.11   */
    355354#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
    356355    /* Each new shared folder map gets a new uint64_t identifier,
    357356     * allocated in sequence.  We ASSUME the sequence will not wrap. */
    358 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
     357# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
    359358    static uint64_t s_u64Sequence = 0;
    360     uint64_t u64CurrentSequence = ASMAtomicIncU64(&s_u64Sequence);
    361 #endif
     359    uint64_t idSeqMine = ASMAtomicIncU64(&s_u64Sequence);
     360# endif
    362361    struct backing_dev_info *bdi;
    363362
    364363#  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
    365     rc = super_setup_bdi_name(sb, "vboxsf-%llu", (unsigned long long)u64CurrentSequence);
     364    rc = super_setup_bdi_name(sb, "vboxsf-%llu", (unsigned long long)idSeqMine);
    366365    if (!rc)
    367366        bdi = sb->s_bdi;
     
    411410#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
    412411    if (!rc)
    413         rc = bdi_register(&pSuperInfo->bdi, NULL, "vboxsf-%llu", (unsigned long long)u64CurrentSequence);
     412        rc = bdi_register(&pSuperInfo->bdi, NULL, "vboxsf-%llu", (unsigned long long)idSeqMine);
    414413#  endif /* >= 2.6.26 */
    415414# endif  /* 4.11.0 > version >= 2.6.24 */
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h

    r77953 r77959  
    221221    RTTIMESPEC              BirthTime;
    222222
     223    /** @name Host modification detection stats.
     224     *  @{  */
     225    /** The raw modification time, for mapping invalidation purposes. */
     226    RTTIMESPEC              ModificationTime;
     227    /** Copy of ModificationTime from the last time we wrote to the the file. */
     228    RTTIMESPEC              ModificationTimeAtOurLastWrite;
     229    /** @} */
     230
    223231    /** handle valid if a file was created with vbsf_create_worker until it will
    224232     * be opened with vbsf_reg_open()
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