VirtualBox

Ignore:
Timestamp:
Mar 24, 2019 2:42:15 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129547
Message:

linux/vboxsf: Added support for the RENAME_NOREPLACE flags (since 3.15) and cleaned up the code a little bit. bugref:9172

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

Legend:

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

    r77859 r77863  
    224224        /* Likely, except for the first time. */
    225225    } else {
    226         /** @todo make the buffer size configurable. */
    227         sf_d->pBuf = (PSHFLDIRINFO)kmalloc(_64K, GFP_KERNEL);
     226        sf_d->pBuf = (PSHFLDIRINFO)kmalloc(sf_g->cbDirBuf, GFP_KERNEL);
    228227        if (sf_d->pBuf)
    229             sf_d->cbBuf = _64K;
     228            sf_d->cbBuf = sf_g->cbDirBuf;
    230229        else {
    231230            sf_d->pBuf = (PSHFLDIRINFO)kmalloc(_4K, GFP_KERNEL);
     
    944943            sf_r->Handle.cRefs  = 1;
    945944            sf_r->Handle.fFlags = !(fOpen & O_DIRECTORY)
    946                                  ? VBSF_HANDLE_F_FILE | VBSF_HANDLE_F_MAGIC
    947                                  : VBSF_HANDLE_F_DIR  | VBSF_HANDLE_F_MAGIC;
     945                                ? VBSF_HANDLE_F_FILE | VBSF_HANDLE_F_MAGIC
     946                                : VBSF_HANDLE_F_DIR  | VBSF_HANDLE_F_MAGIC;
    948947            sf_r->Handle.hHost  = SHFL_HANDLE_NIL;
    949948
     
    11081107    if (!err) {
    11091108        VBOXSFREMOVEREQ *pReq = (VBOXSFREMOVEREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String)
    1110                                            + path->u16Size);
     1109                                                                       + path->u16Size);
    11111110        if (pReq) {
    11121111            memcpy(&pReq->StrPath, path, SHFLSTRING_HEADER_SIZE + path->u16Size);
     
    11811180 */
    11821181static int vbsf_inode_rename(struct inode *old_parent, struct dentry *old_dentry,
    1183                              struct inode *new_parent, struct dentry *new_dentry
     1182                             struct inode *new_parent, struct dentry *new_dentry, unsigned flags)
     1183{
     1184    /*
     1185     * Deal with flags.
     1186     */
     1187    int      rc;
     1188    uint32_t fRename = (old_dentry->d_inode->i_mode & S_IFDIR ? SHFL_RENAME_DIR : SHFL_RENAME_FILE)
     1189                     | SHFL_RENAME_REPLACE_IF_EXISTS;
     1190#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
     1191    if (!(flags & ~RENAME_NOREPLACE)) {
     1192        if (flags & RENAME_NOREPLACE)
     1193            fRename &= ~SHFL_RENAME_REPLACE_IF_EXISTS;
     1194#endif
     1195        /*
     1196         * Check that they are on the same mount.
     1197         */
     1198        struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(old_parent->i_sb);
     1199        if (sf_g == VBSF_GET_SUPER_INFO(new_parent->i_sb)) {
     1200            /*
     1201             * Build the new path.
     1202             */
     1203            struct vbsf_inode_info *sf_new_parent_i = VBSF_GET_INODE_INFO(new_parent);
     1204            PSHFLSTRING             pNewPath;
     1205            rc = vbsf_path_from_dentry(sf_g, sf_new_parent_i, new_dentry, &pNewPath, __func__);
     1206            if (rc == 0) {
     1207                /*
     1208                 * Create and issue the rename request.
     1209                 */
     1210                VBOXSFRENAMEWITHSRCBUFREQ *pReq;
     1211                pReq = (VBOXSFRENAMEWITHSRCBUFREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
     1212                                                                        + pNewPath->u16Size);
     1213                if (pReq) {
     1214                    struct vbsf_inode_info *sf_file_i = VBSF_GET_INODE_INFO(old_dentry->d_inode);
     1215                    PSHFLSTRING             pOldPath = sf_file_i->path;
     1216
     1217                    memcpy(&pReq->StrDstPath, pNewPath, SHFLSTRING_HEADER_SIZE + pNewPath->u16Size);
     1218                    rc = VbglR0SfHostReqRenameWithSrcContig(sf_g->map.root, pReq, pOldPath, virt_to_phys(pOldPath), fRename);
     1219                    VbglR0PhysHeapFree(pReq);
     1220                    if (RT_SUCCESS(rc)) {
     1221                        /*
     1222                         * On success we replace the path in the inode and trigger
     1223                         * restatting of both parent directories.
     1224                         */
     1225                        struct vbsf_inode_info *sf_old_parent_i = VBSF_GET_INODE_INFO(old_parent);
     1226                        SFLOGFLOW(("vbsf_inode_rename: %s -> %s (%#x)\n", pOldPath->String.ach, pNewPath->String.ach, fRename));
     1227
     1228                        sf_file_i->path = pNewPath;
     1229                        kfree(pOldPath);
     1230                        pNewPath = NULL;
     1231
     1232                        sf_new_parent_i->force_restat = 1;
     1233                        sf_old_parent_i->force_restat = 1;
     1234
     1235                        vbsf_dentry_chain_increase_parent_ttl(old_dentry);
     1236                        vbsf_dentry_chain_increase_parent_ttl(new_dentry);
     1237
     1238                        rc = 0;
     1239                    } else {
     1240                        SFLOGFLOW(("vbsf_inode_rename: VbglR0SfHostReqRenameWithSrcContig(%s,%s,%#x) failed -> %d\n",
     1241                                   pOldPath->String.ach, pNewPath->String.ach, fRename, rc));
     1242                        if (rc == VERR_IS_A_DIRECTORY || rc == VERR_IS_A_FILE)
     1243                            vbsf_dentry_set_update_jiffies(old_dentry, jiffies + INT_MAX / 2);
     1244                        rc = -RTErrConvertToErrno(rc);
     1245                    }
     1246                } else {
     1247                    SFLOGFLOW(("vbsf_inode_rename: failed to allocate request (%#x bytes)\n",
     1248                               RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pNewPath->u16Size));
     1249                    rc = -ENOMEM;
     1250                }
     1251                if (pNewPath)
     1252                    kfree(pNewPath);
     1253            } else
     1254                SFLOGFLOW(("vbsf_inode_rename: vbsf_path_from_dentry failed: %d\n", rc));
     1255        } else {
     1256            SFLOGFLOW(("vbsf_inode_rename: rename with different roots (%#x vs %#x)\n",
     1257                       sf_g->map.root, VBSF_GET_SUPER_INFO(new_parent->i_sb)->map.root));
     1258            rc = -EXDEV;
     1259        }
    11841260#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
    1185                              , unsigned flags
    1186 #endif
    1187                              )
    1188 {
    1189     int err = 0, rc = VINF_SUCCESS;
    1190     struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(old_parent->i_sb);
    1191 
    1192     TRACE();
    1193 
    1194 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
    1195     if (flags) {
    1196         LogFunc(("rename with flags=%x\n", flags));
    1197         return -EINVAL;
    1198     }
    1199 #endif
    1200 
    1201     if (sf_g != VBSF_GET_SUPER_INFO(new_parent->i_sb)) {
    1202         LogFunc(("rename with different roots\n"));
    1203         err = -EXDEV;
    12041261    } else {
    1205         struct vbsf_inode_info *sf_old_i = VBSF_GET_INODE_INFO(old_parent);
    1206         struct vbsf_inode_info *sf_new_i = VBSF_GET_INODE_INFO(new_parent);
    1207         /* As we save the relative path inside the inode structure, we need to change
    1208            this if the rename is successful. */
    1209         struct vbsf_inode_info *sf_file_i = VBSF_GET_INODE_INFO(old_dentry->d_inode);
    1210         SHFLSTRING *old_path;
    1211         SHFLSTRING *new_path;
    1212 
    1213         BUG_ON(!sf_old_i);
    1214         BUG_ON(!sf_new_i);
    1215         BUG_ON(!sf_file_i);
    1216 
    1217         old_path = sf_file_i->path;
    1218         err = vbsf_path_from_dentry(sf_g, sf_new_i, new_dentry, &new_path, __func__);
    1219         if (err)
    1220             LogFunc(("failed to create new path\n"));
    1221         else {
    1222             VBOXSFRENAMEWITHSRCBUFREQ *pReq;
    1223             pReq = (VBOXSFRENAMEWITHSRCBUFREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
    1224                                                                     + new_path->u16Size);
    1225             if (pReq) {
    1226                 memcpy(&pReq->StrDstPath, new_path, SHFLSTRING_HEADER_SIZE + new_path->u16Size);
    1227                 rc = VbglR0SfHostReqRenameWithSrcContig(sf_g->map.root, pReq,
    1228                                                         old_path, virt_to_phys(old_path),
    1229                                                         old_dentry->d_inode->i_mode & S_IFDIR ? SHFL_RENAME_DIR
    1230                                                         : SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS);
    1231                 VbglR0PhysHeapFree(pReq);
    1232             } else
    1233                 rc = VERR_NO_MEMORY;
    1234             if (RT_SUCCESS(rc)) {
    1235                 kfree(old_path);
    1236                 sf_new_i->force_restat = 1;
    1237                 sf_old_i->force_restat = 1; /* XXX: needed? */
    1238 
    1239                 /* Set the new relative path in the inode. */
    1240                 sf_file_i->path = new_path;
    1241             } else {
    1242                 LogFunc(("VbglR0SfRename failed rc=%Rrc\n",
    1243                      rc));
    1244                 err = -RTErrConvertToErrno(rc);
    1245                 kfree(new_path);
    1246             }
    1247         }
    1248     }
    1249     return err;
    1250 }
     1262        SFLOGFLOW(("vbsf_inode_rename: Unsupported flags: %#x\n", flags));
     1263        rc = -EINVAL;
     1264    }
     1265#else
     1266    RT_NOREF(flags);
     1267#endif
     1268    return rc;
     1269}
     1270
     1271
     1272#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
     1273/**
     1274 * The traditional rename interface without any flags.
     1275 */
     1276static int vbsf_inode_rename_no_flags(struct inode *old_parent, struct dentry *old_dentry,
     1277                                      struct inode *new_parent, struct dentry *new_dentry)
     1278{
     1279    return vbsf_inode_rename(old_parent, old_dentry, new_parent, new_dentry, 0);
     1280}
     1281#endif
    12511282
    12521283
     
    13321363    .rmdir          = vbsf_inode_rmdir,
    13331364    .unlink         = vbsf_inode_unlink,
     1365#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
    13341366    .rename         = vbsf_inode_rename,
     1367#else
     1368    .rename         = vbsf_inode_rename_no_flags,
     1369# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
     1370    .rename2        = vbsf_inode_rename,
     1371# endif
     1372#endif
    13351373#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18)
    13361374    .getattr        = vbsf_inode_getattr,
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c

    r77859 r77863  
    134134                   info->cMaxIoPages, sf_g->cMaxIoPages);
    135135    }
     136
     137    sf_g->cbDirBuf = _64K; /** @todo make configurable. */
    136138}
    137139
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h

    r77858 r77863  
    144144     * This applies to read and write operations.  */
    145145    uint32_t cMaxIoPages;
     146    /** The default directory buffer size. */
     147    uint32_t cbDirBuf;
    146148    /** Mount tag for VBoxService automounter.  @since 6.0 */
    147149    char tag[32];
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