- Timestamp:
- Mar 24, 2019 12:10:24 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129542
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxGuestLibSharedFoldersInline.h
r77854 r77858 42 42 #include <VBox/VMMDev.h> 43 43 #include <VBox/shflsvc.h> 44 #include <iprt/err core.h>44 #include <iprt/err.h> 45 45 46 46 … … 734 734 - sizeof(VBGLIOCIDCHGCMFASTCALL); 735 735 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST; 736 pReq->PgLst.offFirstPage = ( (uint16_t)PhysSrcStr)& (uint16_t)(PAGE_OFFSET_MASK);736 pReq->PgLst.offFirstPage = (uint16_t)PhysSrcStr & (uint16_t)(PAGE_OFFSET_MASK); 737 737 pReq->PgLst.aPages[0] = PhysSrcStr & ~(RTGCPHYS64)PAGE_OFFSET_MASK; 738 738 pReq->PgLst.cPages = 1; … … 1318 1318 } 1319 1319 1320 1321 /** Request structure for VbglR0SfHostReqReadLink. */ 1322 typedef struct VBOXSFREADLINKREQ 1323 { 1324 VBGLIOCIDCHGCMFASTCALL Hdr; 1325 VMMDevHGCMCall Call; 1326 VBoxSFParmReadLink Parms; 1327 HGCMPageListInfo PgLst; 1328 SHFLSTRING StrPath; 1329 } VBOXSFREADLINKREQ; 1330 1331 /** 1332 * SHFL_FN_READLINK request. 1333 * 1334 * @note Buffer contains UTF-8 characters on success, regardless of the 1335 * UTF-8/UTF-16 setting of the connection. 1336 */ 1337 DECLINLINE(int) VbglR0SfHostReqReadLinkContig(SHFLROOT idRoot, void *pvBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer, 1338 VBOXSFREADLINKREQ *pReq) 1339 { 1340 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS 1341 ? RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String) + pReq->StrPath.u16Size 1342 : cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK) 1343 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST) 1344 ? RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String) 1345 : RT_UOFFSETOF(VBOXSFREADLINKREQ, PgLst); 1346 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient, 1347 SHFL_FN_READLINK, SHFL_CPARMS_READLINK, cbReq); 1348 1349 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit; 1350 pReq->Parms.id32Root.u.value32 = idRoot; 1351 1352 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS) 1353 { 1354 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded; 1355 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size; 1356 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath) 1357 - sizeof(VBGLIOCIDCHGCMFASTCALL); 1358 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST; 1359 } 1360 else 1361 { 1362 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In; 1363 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size; 1364 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath; 1365 } 1366 1367 if ( cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK) 1368 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)) 1369 { 1370 pReq->Parms.pBuffer.type = cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK) 1371 ? VMMDevHGCMParmType_PageList 1372 : VMMDevHGCMParmType_ContiguousPageList; 1373 pReq->Parms.pBuffer.u.PageList.size = cbBuffer; 1374 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADLINKREQ, PgLst) 1375 - sizeof(VBGLIOCIDCHGCMFASTCALL); 1376 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST; 1377 pReq->PgLst.offFirstPage = (uint16_t)PhysBuffer & (uint16_t)(PAGE_OFFSET_MASK); 1378 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK; 1379 pReq->PgLst.cPages = 1; 1380 } 1381 else 1382 { 1383 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out; 1384 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer; 1385 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pvBuffer; 1386 } 1387 1388 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq); 1389 if (RT_SUCCESS(vrc)) 1390 vrc = pReq->Call.header.result; 1391 return vrc; 1392 } 1393 1394 /** 1395 * SHFL_FN_READLINK request, simplified version. 1396 * 1397 * 1398 * @note Buffer contains UTF-8 characters on success, regardless of the 1399 * UTF-8/UTF-16 setting of the connection. 1400 */ 1401 DECLINLINE(int) VbglR0SfHostReqReadLinkContigSimple(SHFLROOT idRoot, const char *pszPath, size_t cchPath, void *pvBuf, 1402 RTGCPHYS64 PhysBuffer, uint32_t cbBuffer) 1403 { 1404 if (cchPath < _64K - 1) 1405 { 1406 VBOXSFREADLINKREQ *pReq = (VBOXSFREADLINKREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String) 1407 + SHFLSTRING_HEADER_SIZE + cchPath); 1408 if (pReq) 1409 { 1410 pReq->StrPath.u16Length = (uint16_t)cchPath; 1411 pReq->StrPath.u16Size = (uint16_t)cchPath + 1; 1412 memcpy(pReq->StrPath.String.ach, pszPath, cchPath); 1413 pReq->StrPath.String.ach[cchPath] = '\0'; 1414 1415 { 1416 int vrc = VbglR0SfHostReqReadLinkContig(idRoot, pvBuf, PhysBuffer, cbBuffer, pReq); 1417 VbglR0PhysHeapFree(pReq); 1418 return vrc; 1419 } 1420 } 1421 return VERR_NO_MEMORY; 1422 } 1423 return VERR_FILENAME_TOO_LONG; 1424 } 1425 1426 1427 /** Request structure for VbglR0SfHostReqCreateSymlink. */ 1428 typedef struct VBOXSFCREATESYMLINKREQ 1429 { 1430 VBGLIOCIDCHGCMFASTCALL Hdr; 1431 VMMDevHGCMCall Call; 1432 VBoxSFParmCreateSymlink Parms; 1433 HGCMPageListInfo PgLstTarget; 1434 SHFLFSOBJINFO ObjInfo; 1435 SHFLSTRING StrSymlinkPath; 1436 } VBOXSFCREATESYMLINKREQ; 1437 1438 /** 1439 * SHFL_FN_SYMLINK request. 1440 * 1441 * Caller fills in the symlink string and supplies a physical contiguous 1442 * target string 1443 */ 1444 DECLINLINE(int) VbglR0SfHostReqCreateSymlinkContig(SHFLROOT idRoot, PCSHFLSTRING pStrTarget, RTGCPHYS64 PhysTarget, 1445 VBOXSFCREATESYMLINKREQ *pReq) 1446 { 1447 uint32_t const cbTarget = SHFLSTRING_HEADER_SIZE + pStrTarget->u16Size; 1448 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS 1449 ? RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath.String) + pReq->StrSymlinkPath.u16Size 1450 : RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, ObjInfo) /*simplified*/; 1451 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient, 1452 SHFL_FN_SYMLINK, SHFL_CPARMS_SYMLINK, cbReq); 1453 1454 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit; 1455 pReq->Parms.id32Root.u.value32 = idRoot; 1456 1457 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS) 1458 { 1459 pReq->Parms.pStrSymlink.type = VMMDevHGCMParmType_Embedded; 1460 pReq->Parms.pStrSymlink.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrSymlinkPath.u16Size; 1461 pReq->Parms.pStrSymlink.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath) 1462 - sizeof(VBGLIOCIDCHGCMFASTCALL); 1463 pReq->Parms.pStrSymlink.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST; 1464 } 1465 else 1466 { 1467 pReq->Parms.pStrSymlink.type = VMMDevHGCMParmType_LinAddr_In; 1468 pReq->Parms.pStrSymlink.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrSymlinkPath.u16Size; 1469 pReq->Parms.pStrSymlink.u.LinAddr.uAddr = (uintptr_t)&pReq->StrSymlinkPath; 1470 } 1471 1472 if ( cbTarget <= PAGE_SIZE - (PhysTarget & PAGE_OFFSET_MASK) 1473 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)) 1474 { 1475 pReq->Parms.pStrTarget.type = cbTarget <= PAGE_SIZE - (PhysTarget & PAGE_OFFSET_MASK) 1476 ? VMMDevHGCMParmType_PageList 1477 : VMMDevHGCMParmType_ContiguousPageList; 1478 pReq->Parms.pStrTarget.u.PageList.size = cbTarget; 1479 pReq->Parms.pStrTarget.u.PageList.offset = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, PgLstTarget) 1480 - sizeof(VBGLIOCIDCHGCMFASTCALL); 1481 pReq->PgLstTarget.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST; 1482 pReq->PgLstTarget.offFirstPage = (uint16_t)PhysTarget & (uint16_t)(PAGE_OFFSET_MASK); 1483 pReq->PgLstTarget.aPages[0] = PhysTarget & ~(RTGCPHYS64)PAGE_OFFSET_MASK; 1484 pReq->PgLstTarget.cPages = 1; 1485 } 1486 else 1487 { 1488 pReq->Parms.pStrTarget.type = VMMDevHGCMParmType_LinAddr_In; 1489 pReq->Parms.pStrTarget.u.LinAddr.cb = cbTarget; 1490 pReq->Parms.pStrTarget.u.LinAddr.uAddr = (uintptr_t)pStrTarget; 1491 } 1492 1493 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS) 1494 { 1495 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded; 1496 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo); 1497 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, ObjInfo) 1498 - sizeof(VBGLIOCIDCHGCMFASTCALL); 1499 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST; 1500 } 1501 else 1502 { 1503 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out; 1504 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo); 1505 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo; 1506 } 1507 1508 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq); 1509 if (RT_SUCCESS(vrc)) 1510 vrc = pReq->Call.header.result; 1511 return vrc; 1512 } 1513 1320 1514 /** @} */ 1321 1515 -
trunk/include/VBox/shflsvc.h
r77854 r77858 119 119 /** Read symlink destination. 120 120 * @since VBox 4.0 */ 121 #define SHFL_FN_READLINK (18) 121 #define SHFL_FN_READLINK (18) /**< @todo rename to SHFL_FN_READ_LINK (see struct capitalization) */ 122 122 /** Create symlink. 123 123 * @since VBox 4.0 */ … … 1613 1613 */ 1614 1614 1615 /** SHFL_FN_READLINK parameters. */ 1616 typedef struct VBoxSFParmReadLink 1617 { 1618 /** value32, in: SHFLROOT of the mapping which the symlink is read. */ 1619 HGCMFunctionParameter id32Root; 1620 /** pointer, in: SHFLSTRING full path to the symlink. */ 1621 HGCMFunctionParameter pStrPath; 1622 /** pointer, out: Buffer to place the symlink target into. 1623 * @note Buffer contains UTF-8 characters on success, regardless of the 1624 * UTF-8/UTF-16 setting of the connection. Will be zero terminated. 1625 * 1626 * @todo r=bird: This should've been a string! 1627 * @todo r=bird: There should've been a byte count returned! */ 1628 HGCMFunctionParameter pBuffer; 1629 } VBoxSFParmReadLink; 1630 1615 1631 /** Parameters structure. */ 1616 1632 typedef struct _VBoxSFReadLink … … 1630 1646 /** pointer, out: 1631 1647 * Buffer to place data to. 1648 * @note Buffer contains UTF-8 characters on success, regardless of the 1649 * UTF-8/UTF-16 setting of the connection. Will be zero terminated. 1632 1650 */ 1633 1651 HGCMFunctionParameter buffer; … … 1817 1835 * @{ 1818 1836 */ 1837 1838 /** Parameters structure. */ 1839 typedef struct VBoxSFParmCreateSymlink 1840 { 1841 /** value32, in: SHFLROOT of the mapping the symlink should be created on. */ 1842 HGCMFunctionParameter id32Root; 1843 /** pointer, in: SHFLSTRING giving the path to the symlink. */ 1844 HGCMFunctionParameter pStrSymlink; 1845 /** pointer, in: SHFLSTRING giving the target. */ 1846 HGCMFunctionParameter pStrTarget; 1847 /** pointer, out: SHFLFSOBJINFO buffer to be filled with info about the created symlink. */ 1848 HGCMFunctionParameter pInfo; 1849 } VBoxSFParmCreateSymlink; 1819 1850 1820 1851 /** Parameters structure. */ -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibSharedFolders.c
r77854 r77858 610 610 } 611 611 612 613 612 DECLVBGL(int) VbglR0SfLock(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, 614 613 uint64_t offset, uint64_t cbSize, uint32_t fLock) … … 637 636 } 638 637 639 #endif /* !RT_OS_LINUX */640 641 638 DECLVBGL(int) VbglR0SfReadLink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, uint32_t cbBuffer, uint8_t *pBuffer) 642 639 { … … 662 659 } 663 660 661 #endif /* !RT_OS_LINUX */ 662 664 663 DECLVBGL(int) VbglR0SfSymlink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath, 665 664 PSHFLFSOBJINFO pBuffer) -
trunk/src/VBox/Additions/linux/sharedfolders/dirops.c
r77741 r77858 274 274 } 275 275 276 276 277 /** 277 278 * Helper function for when we need to convert the name, avoids wasting stack in … … 548 549 } 549 550 551 550 552 /** 551 553 * Directory file operations. 552 554 */ 553 555 struct file_operations vbsf_dir_fops = { 554 .open = vbsf_dir_open,556 .open = vbsf_dir_open, 555 557 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) 556 558 .iterate_shared = vbsf_dir_iterate, 557 559 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) 558 .iterate = vbsf_dir_iterate,560 .iterate = vbsf_dir_iterate, 559 561 #else 560 .readdir = vbsf_dir_read,561 #endif 562 .release = vbsf_dir_release,563 .read = generic_read_dir562 .readdir = vbsf_dir_read, 563 #endif 564 .release = vbsf_dir_release, 565 .read = generic_read_dir, 564 566 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) 565 , .llseek= generic_file_llseek567 .llseek = generic_file_llseek 566 568 #endif 567 569 }; … … 676 678 * Build the path. We'll associate the path with dret's inode on success. 677 679 */ 678 rc = vbsf_path_from_dentry( __func__, sf_g, sf_i, dentry, &path);680 rc = vbsf_path_from_dentry(sf_g, sf_i, dentry, &path, __func__); 679 681 if (rc == 0) { 680 682 /* … … 800 802 * Build a path. We'll donate this to the inode on success. 801 803 */ 802 rc = vbsf_path_from_dentry( __func__, sf_g, sf_parent_i, dentry, &path);804 rc = vbsf_path_from_dentry(sf_g, sf_parent_i, dentry, &path, __func__); 803 805 if (rc == 0) { 804 806 /* … … 1059 1061 } 1060 1062 1063 1061 1064 /** 1062 1065 * Create a new directory. … … 1083 1086 } 1084 1087 1088 1085 1089 /** 1086 1090 * Remove a regular file / directory. … … 1101 1105 BUG_ON(!sf_g); 1102 1106 1103 err = vbsf_path_from_dentry( __func__, sf_g, sf_parent_i, dentry, &path);1107 err = vbsf_path_from_dentry(sf_g, sf_parent_i, dentry, &path, __func__); 1104 1108 if (!err) { 1105 1109 VBOXSFREMOVEREQ *pReq = (VBOXSFREMOVEREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) … … 1137 1141 } 1138 1142 1143 1139 1144 /** 1140 1145 * Remove a regular file. … … 1150 1155 } 1151 1156 1157 1152 1158 /** 1153 1159 * Remove a directory. … … 1162 1168 return vbsf_unlink_worker(parent, dentry, true /*fDirectory*/); 1163 1169 } 1170 1164 1171 1165 1172 /** … … 1194 1201 if (sf_g != VBSF_GET_SUPER_INFO(new_parent->i_sb)) { 1195 1202 LogFunc(("rename with different roots\n")); 1196 err = -E INVAL;1203 err = -EXDEV; 1197 1204 } else { 1198 1205 struct vbsf_inode_info *sf_old_i = VBSF_GET_INODE_INFO(old_parent); … … 1209 1216 1210 1217 old_path = sf_file_i->path; 1211 err = vbsf_path_from_dentry( __func__, sf_g, sf_new_i, new_dentry, &new_path);1218 err = vbsf_path_from_dentry(sf_g, sf_new_i, new_dentry, &new_path, __func__); 1212 1219 if (err) 1213 1220 LogFunc(("failed to create new path\n")); … … 1243 1250 } 1244 1251 1245 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 1246 static int vbsf_ino_symlink(struct inode *parent, struct dentry *dentry, const char *symname) 1247 { 1248 int err; 1249 int rc; 1250 struct vbsf_inode_info *sf_i; 1251 struct vbsf_super_info *sf_g; 1252 SHFLSTRING *path, *ssymname; 1253 SHFLFSOBJINFO info; 1254 int symname_len = strlen(symname) + 1; 1255 1256 TRACE(); 1257 sf_g = VBSF_GET_SUPER_INFO(parent->i_sb); 1258 sf_i = VBSF_GET_INODE_INFO(parent); 1259 1260 BUG_ON(!sf_g); 1261 BUG_ON(!sf_i); 1262 1263 err = vbsf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path); 1264 if (err) 1265 goto fail0; 1266 1267 ssymname = kmalloc(offsetof(SHFLSTRING, String.utf8) + symname_len, GFP_KERNEL); 1268 if (!ssymname) { 1269 LogRelFunc(("kmalloc failed, caller=sf_symlink\n")); 1270 err = -ENOMEM; 1271 goto fail1; 1272 } 1273 1274 ssymname->u16Length = symname_len - 1; 1275 ssymname->u16Size = symname_len; 1276 memcpy(ssymname->String.utf8, symname, symname_len); 1277 1278 rc = VbglR0SfSymlink(&g_SfClient, &sf_g->map, path, ssymname, &info); 1279 kfree(ssymname); 1280 1281 if (RT_FAILURE(rc)) { 1282 err = RTErrConvertFromErrno(rc); 1283 LogFunc(("VbglR0SfSymlink(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); 1284 goto fail1; 1285 } 1286 1287 err = vbsf_inode_instantiate(parent, dentry, path, &info, SHFL_HANDLE_NIL); 1288 if (err) { 1289 LogFunc(("could not instantiate dentry for %s err=%d\n", sf_i->path->String.utf8, err)); 1290 goto fail1; 1291 } 1292 1293 sf_i->force_restat = 1; 1294 return 0; 1295 1296 fail1: 1297 kfree(path); 1298 fail0: 1299 return err; 1300 } 1301 #endif /* LINUX_VERSION_CODE >= 2.6.0 */ 1302 1252 1253 /** 1254 * Create a symbolic link. 1255 */ 1256 static int vbsf_inode_symlink(struct inode *parent, struct dentry *dentry, const char *target) 1257 { 1258 /* 1259 * Turn the target into a string (contiguous physcial memory). 1260 */ 1261 /** @todo we can save a kmalloc here if we switch to embedding the target rather 1262 * than the symlink path into the request. Will require more NLS helpers. */ 1263 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(parent->i_sb); 1264 PSHFLSTRING pTarget = NULL; 1265 int rc = vbsf_nls_to_shflstring(sf_g, target, &pTarget); 1266 if (rc == 0) { 1267 /* 1268 * Create a full path for the symlink name. 1269 */ 1270 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(parent); 1271 PSHFLSTRING pPath = NULL; 1272 rc = vbsf_path_from_dentry(sf_g, sf_i, dentry, &pPath, __func__); 1273 if (rc == 0) { 1274 /* 1275 * Create the request and issue it. 1276 */ 1277 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath.String) + pPath->u16Size; 1278 VBOXSFCREATESYMLINKREQ *pReq = (VBOXSFCREATESYMLINKREQ *)VbglR0PhysHeapAlloc(cbReq); 1279 if (pReq) { 1280 RT_ZERO(*pReq); 1281 memcpy(&pReq->StrSymlinkPath, pPath, SHFLSTRING_HEADER_SIZE + pPath->u16Size); 1282 1283 rc = VbglR0SfHostReqCreateSymlinkContig(sf_g->map.root, pTarget, virt_to_phys(pTarget), pReq); 1284 if (RT_SUCCESS(rc)) { 1285 sf_i->force_restat = 1; 1286 1287 /* 1288 * Instantiate a new inode for the symlink. 1289 */ 1290 rc = vbsf_inode_instantiate(parent, dentry, pPath, &pReq->ObjInfo, SHFL_HANDLE_NIL); 1291 if (rc == 0) { 1292 SFLOGFLOW(("vbsf_inode_symlink: Successfully created '%s' -> '%s'\n", pPath->String.ach, pTarget->String.ach)); 1293 pPath = NULL; /* consumed by inode */ 1294 } else { 1295 SFLOGFLOW(("vbsf_inode_symlink: Failed to create inode for '%s': %d\n", pPath->String.ach, rc)); 1296 } 1297 } else { 1298 int const vrc = rc; 1299 rc = -RTErrConvertToErrno(rc); 1300 SFLOGFLOW(("vbsf_inode_symlink: VbglR0SfHostReqCreateSymlinkContig failed for '%s' -> '%s': %Rrc (-> %d)\n", 1301 pPath->String.ach, pTarget->String.ach, vrc, rc)); 1302 } 1303 VbglR0PhysHeapFree(pReq); 1304 } else { 1305 SFLOGFLOW(("vbsf_inode_symlink: failed to allocate %u phys heap for the request!\n", cbReq)); 1306 rc = -ENOMEM; 1307 } 1308 if (pPath) 1309 kfree(pPath); 1310 } 1311 kfree(pTarget); 1312 } 1313 return rc; 1314 } 1315 1316 1317 /** 1318 * Directory inode operations. 1319 */ 1303 1320 struct inode_operations vbsf_dir_iops = { 1304 .lookup = vbsf_inode_lookup,1321 .lookup = vbsf_inode_lookup, 1305 1322 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) 1306 .atomic_open = vbsf_inode_atomic_open, 1307 #endif 1308 .create = vbsf_inode_create, 1309 .mkdir = vbsf_inode_mkdir, 1310 .rmdir = vbsf_inode_rmdir, 1311 .unlink = vbsf_inode_unlink, 1312 .rename = vbsf_inode_rename, 1323 .atomic_open = vbsf_inode_atomic_open, 1324 #endif 1325 .create = vbsf_inode_create, 1326 .symlink = vbsf_inode_symlink, 1327 .mkdir = vbsf_inode_mkdir, 1328 .rmdir = vbsf_inode_rmdir, 1329 .unlink = vbsf_inode_unlink, 1330 .rename = vbsf_inode_rename, 1313 1331 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18) 1314 .getattr = vbsf_inode_getattr,1332 .getattr = vbsf_inode_getattr, 1315 1333 #else 1316 .revalidate = vbsf_inode_revalidate, 1317 #endif 1318 .setattr = vbsf_inode_setattr, 1319 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 1320 .symlink = vbsf_ino_symlink, 1321 #endif 1334 .revalidate = vbsf_inode_revalidate, 1335 #endif 1336 .setattr = vbsf_inode_setattr, 1322 1337 }; 1323 1338 -
trunk/src/VBox/Additions/linux/sharedfolders/lnkops.c
r77530 r77858 29 29 */ 30 30 31 32 /********************************************************************************************************************************* 33 * Header Files * 34 *********************************************************************************************************************************/ 31 35 #include "vfsmod.h" 32 36 33 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) /* no generic_readlink() before 2.6.8 */ 34 35 # if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) 36 37 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) 37 38 /** 39 * Converts error codes as best we can. 40 */ 41 DECLINLINE(int) vbsf_convert_symlink_error(int vrc) 42 { 43 if ( vrc == VERR_IS_A_DIRECTORY 44 || vrc == VERR_IS_A_FIFO 45 || vrc == VERR_IS_A_FILE 46 || vrc == VERR_IS_A_BLOCK_DEVICE 47 || vrc == VERR_IS_A_CHAR_DEVICE 48 || vrc == VERR_IS_A_SOCKET 49 || vrc == VERR_NOT_SYMLINK) 50 return -EINVAL; 51 if (vrc == VERR_PATH_NOT_FOUND) 52 return -ENOTDIR; 53 if (vrc == VERR_FILE_NOT_FOUND) 54 return -ENOENT; 55 return -EPROTO; 56 } 57 58 59 /** 60 * Does the NLS conversion of the symlink target. 61 */ 62 static int vbsf_symlink_nls_convert_slow(struct vbsf_super_info *pSuperInfo, char *pszTarget, size_t cbTargetBuf) 63 { 64 int rc; 65 size_t const cchUtf8 = RTStrNLen(pszTarget, cbTargetBuf); 66 if (cchUtf8 < cbTargetBuf) { 67 /* 68 * If the target is short and there is a lot of space left in the target 69 * buffer (typically PAGE_SIZE in size), we move the input to the end 70 * instead of allocating a temporary buffer for it. This works because 71 * there shouldn't be anything that is more than 8x worse than UTF-8 72 * when it comes to efficiency. 73 */ 74 char *pszFree = NULL; 75 char *pszUtf8; 76 if (cchUtf8 - 1 <= cbTargetBuf / 8) { 77 pszUtf8 = &pszTarget[cbTargetBuf - cchUtf8 - 1]; 78 cbTargetBuf -= cchUtf8 - 1; 79 } else { 80 pszFree = pszUtf8 = kmalloc(cchUtf8 + 1, GFP_KERNEL); 81 if (RT_UNLIKELY(!pszUtf8)) { 82 LogRelMax(50, ("vbsf_symlink_nls_convert_slow: failed to allocate %u bytes\n", cchUtf8 + 1)); 83 return -ENOMEM; 84 } 85 } 86 memcpy(pszUtf8, pszTarget, cchUtf8); 87 pszUtf8[cchUtf8] = '\0'; 88 89 rc = vbsf_nlscpy(pSuperInfo, pszTarget, cbTargetBuf, pszUtf8, cchUtf8); 90 if (pszFree) 91 kfree(pszFree); 92 } else { 93 SFLOGFLOW(("vbsf_symlink_nls_convert_slow: Impossible! Unterminated target!\n")); 94 rc = -ENAMETOOLONG; 95 } 96 return rc; 97 } 98 99 100 /** 101 * Does NLS conversion if needed. 102 */ 103 DECLINLINE(int) vbsf_symlink_nls_convert(struct vbsf_super_info *pSuperInfo, char *pszTarget, size_t cbTargetBuf) 104 { 105 if (pSuperInfo->fNlsIsUtf8) 106 return 0; 107 return vbsf_symlink_nls_convert_slow(pSuperInfo, pszTarget, cbTargetBuf); 108 } 109 110 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) 111 112 /** 113 * Get symbolic link. 114 */ 115 static const char *vbsf_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) 116 { 117 char *pszTarget; 118 if (dentry) { 119 pszTarget = (char *)kzalloc(PAGE_SIZE, GFP_KERNEL); 120 if (pszTarget) { 121 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 122 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 123 int rc = VbglR0SfHostReqReadLinkContigSimple(sf_g->map.root, sf_i->path->String.ach, sf_i->path->u16Length, 124 pszTarget, virt_to_phys(pszTarget), RT_MIN(PATH_MAX, PAGE_SIZE - 1)); 125 if (RT_SUCCESS(rc)) { 126 pszTarget[PAGE_SIZE - 1] = '\0'; 127 SFLOGFLOW(("vbsf_get_link: %s -> %s\n", sf_i->path->String.ach, pszTarget)); 128 rc = vbsf_symlink_nls_convert(sf_g, pszTarget, PAGE_SIZE); 129 if (rc == 0) { 130 set_delayed_call(done, kfree_link, pszTarget); 131 return pszTarget; 132 } 133 } else { 134 SFLOGFLOW(("vbsf_get_link: VbglR0SfHostReqReadLinkContigSimple failed on '%s': %Rrc\n", 135 sf_i->path->String.ach, rc)); 136 } 137 kfree(pszTarget); 138 pszTarget = ERR_PTR(vbsf_convert_symlink_error(rc)); 139 } else 140 pszTarget = ERR_PTR(-ENOMEM); 141 } else 142 pszTarget = ERR_PTR(-ECHILD); 143 return pszTarget; 144 } 145 146 #else /* < 4.5 */ 147 148 # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) 149 /** 150 * Reads the link into the given buffer. 151 */ 152 static int vbsf_readlink(struct dentry *dentry, char *buffer, int len) 153 { 154 int rc; 155 char *pszTarget = (char *)get_zeroed_page(GFP_KERNEL); 156 if (pszTarget) { 157 struct inode *inode = dentry->d_inode; 158 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 159 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 160 rc = VbglR0SfHostReqReadLinkContigSimple(sf_g->map.root, sf_i->path->String.ach, sf_i->path->u16Length, 161 pszTarget, virt_to_phys(pszTarget), RT_MIN(PATH_MAX, PAGE_SIZE - 1)); 162 if (RT_SUCCESS(rc)) { 163 pszTarget[PAGE_SIZE - 1] = '\0'; 164 SFLOGFLOW(("vbsf_readlink: %s -> %*s\n", sf_i->path->String.ach, pszTarget)); 165 rc = vbsf_symlink_nls_convert(sf_g, pszTarget, PAGE_SIZE); 166 if (rc == 0) 167 rc = vfs_readlink(dentry, buffer, len, pszTarget); 168 } else { 169 SFLOGFLOW(("vbsf_readlink: VbglR0SfHostReqReadLinkContigSimple failed on '%s': %Rrc\n", sf_i->path->String.ach, rc)); 170 rc = vbsf_convert_symlink_error(rc); 171 } 172 free_page((unsigned long)pszTarget); 173 } else 174 rc = -ENOMEM; 175 return rc; 176 } 177 # endif /* < 2.6.8 */ 178 179 /** 180 * Follow link in dentry. 181 */ 182 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) 38 183 static const char *vbsf_follow_link(struct dentry *dentry, void **cookie) 39 # 184 # elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) 40 185 static void *vbsf_follow_link(struct dentry *dentry, struct nameidata *nd) 186 # else 187 static int vbsf_follow_link(struct dentry *dentry, struct nameidata *nd) 188 # endif 189 { 190 int rc; 191 char *pszTarget = (char *)get_zeroed_page(GFP_KERNEL); 192 if (pszTarget) { 193 struct inode *inode = dentry->d_inode; 194 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 195 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 196 197 rc = VbglR0SfHostReqReadLinkContigSimple(sf_g->map.root, sf_i->path->String.ach, sf_i->path->u16Length, 198 pszTarget, virt_to_phys(pszTarget), RT_MIN(PATH_MAX, PAGE_SIZE - 1)); 199 if (RT_SUCCESS(rc)) { 200 pszTarget[PAGE_SIZE - 1] = '\0'; 201 SFLOGFLOW(("vbsf_follow_link: %s -> %s\n", sf_i->path->String.ach, pszTarget)); 202 rc = vbsf_symlink_nls_convert(sf_g, pszTarget, PAGE_SIZE); 203 if (rc == 0) { 204 /* 205 * Succeeded. For 2.6.8 and later the page gets associated 206 * with the caller-cookie or nameidata structure and freed 207 * later by vbsf_put_link(). On earlier kernels we have to 208 * call vfs_follow_link() which will try continue the walking 209 * using the buffer we pass it here. 210 */ 211 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) 212 *cookie = pszTarget; 213 return pszTarget; 214 # elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) 215 nd_set_link(nd, pszTarget); 216 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) 217 return NULL; 41 218 # else 42 static int vbsf_follow_link(struct dentry *dentry, struct nameidata *nd) 219 return 0; 43 220 # endif 44 { 45 struct inode *inode = dentry->d_inode; 46 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 47 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 48 int error = -ENOMEM; 49 char *path = (char *)get_zeroed_page(GFP_KERNEL); 50 int rc; 51 52 if (path) { 53 error = 0; 54 rc = VbglR0SfReadLink(&g_SfClient, &sf_g->map, sf_i->path, PATH_MAX, path); 55 if (RT_FAILURE(rc)) { 221 # else /* < 2.6.8 */ 222 rc = vfs_follow_link(nd, pszTarget); 223 free_page((unsigned long)pszTarget); 224 return rc; 225 # endif 226 } 227 228 /* 229 * Failed. 230 */ 231 } else { 56 232 LogFunc(("VbglR0SfReadLink failed, caller=%s, rc=%Rrc\n", __func__, rc)); 57 free_page((unsigned long)path); 58 error = -EPROTO; 233 rc = vbsf_convert_symlink_error(rc); 59 234 } 235 free_page((unsigned long)pszTarget); 236 } else { 237 rc = -ENOMEM; 60 238 } 61 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) 62 return error ? ERR_PTR(error) : (*cookie = path); 239 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) 240 *cookie = ERR_PTR(rc); 241 return (const char *)ERR_PTR(rc); 242 # elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) 243 nd_set_link(nd, (char *)ERR_PTR(rc)); 244 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) 245 return NULL; 63 246 # else 64 nd_set_link(nd, error ? ERR_PTR(error) : path);65 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)66 return NULL;67 # else68 247 return 0; 69 # endif70 248 # endif 71 } 72 73 # if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) 74 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) 249 # else /* < 2.6.8 */ 250 return rc; 251 # endif /* < 2.6.8 */ 252 } 253 254 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) 255 /** 256 * For freeing target link buffer allocated by vbsf_follow_link. 257 * 258 * For kernel before 2.6.8 memory isn't being kept around. 259 */ 260 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) 75 261 static void vbsf_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) 76 # 262 # else 77 263 static void vbsf_put_link(struct dentry *dentry, struct nameidata *nd) 78 # endif 79 { 264 # endif 265 { 266 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) 267 char *page = cookie; 268 # else 80 269 char *page = nd_get_link(nd); 270 # endif 271 SFLOGFLOW(("vbsf_put_link: page=%p\n", page)); 81 272 if (!IS_ERR(page)) 82 273 free_page((unsigned long)page); 83 274 } 84 # endif /* < 4.2.0 */ 85 86 # else /* >= 4.5.0 */ 87 88 static const char *vbsf_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) 89 { 90 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 91 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 92 char *path; 93 int rc; 94 95 if (!dentry) 96 return ERR_PTR(-ECHILD); 97 path = kzalloc(PAGE_SIZE, GFP_KERNEL); 98 if (!path) 99 return ERR_PTR(-ENOMEM); 100 rc = VbglR0SfReadLink(&g_SfClient, &sf_g->map, sf_i->path, PATH_MAX, path); 101 if (RT_FAILURE(rc)) { 102 LogFunc(("VbglR0SfReadLink failed, rc=%Rrc\n", rc)); 103 kfree(path); 104 return ERR_PTR(-EPROTO); 105 } 106 set_delayed_call(done, kfree_link, path); 107 return path; 108 } 109 110 # endif /* >= 4.5.0 */ 111 275 # endif /* >= 2.6.8 */ 276 277 #endif /* < 4.5.0 */ 278 279 /** 280 * Symlink inode operations. 281 */ 112 282 struct inode_operations vbsf_lnk_iops = { 113 # if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) 114 .readlink = generic_readlink, 283 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) 284 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) 285 .readlink = generic_readlink, 286 # else 287 .readlink = vbsf_readlink, 115 288 # endif 116 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) 117 .get_link = vbsf_get_link 118 # elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) 289 #endif 290 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) 291 .get_link = vbsf_get_link 292 #else 119 293 .follow_link = vbsf_follow_link, 120 .put_link = free_page_put_link, 121 # else 122 .follow_link = vbsf_follow_link, 123 .put_link = vbsf_put_link 294 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) 295 .put_link = vbsf_put_link, 124 296 # endif 297 #endif 125 298 }; 126 299 127 #endif /* LINUX_VERSION_CODE >= 2.6.8 */ 300 -
trunk/src/VBox/Additions/linux/sharedfolders/utils.c
r77741 r77858 39 39 int vbsf_nlscpy(struct vbsf_super_info *sf_g, char *name, size_t name_bound_len, const unsigned char *utf8_name, size_t utf8_len) 40 40 { 41 Assert(name_bound_len > 1); 41 42 Assert(RTStrNLen(utf8_name, utf8_len) == utf8_len); 42 43 … … 45 46 size_t in_bound_len = utf8_len; 46 47 char *out = name; 47 size_t out_bound_len = name_bound_len ;48 size_t out_bound_len = name_bound_len - 1; 48 49 size_t out_len = 0; 49 50 … … 90 91 91 92 /** 93 * Converts the given NLS string to a host one, kmalloc'ing 94 * the output buffer (use kfree on result). 95 */ 96 int vbsf_nls_to_shflstring(struct vbsf_super_info *sf_g, const char *pszNls, PSHFLSTRING *ppString) 97 { 98 int rc; 99 size_t const cchNls = strlen(pszNls); 100 PSHFLSTRING pString = NULL; 101 if (sf_g->nls) { 102 /* 103 * NLS -> UTF-8 w/ SHLF string header. 104 */ 105 /* Calc length first: */ 106 size_t cchUtf8 = 0; 107 size_t offNls = 0; 108 while (offNls < cchNls) { 109 linux_wchar_t uc; /* Note! We renamed the type due to clashes. */ 110 int const cbNlsCodepoint = sf_g->nls->char2uni(&pszNls[offNls], cchNls - offNls, &uc); 111 if (cbNlsCodepoint >= 0) { 112 char achTmp[16]; 113 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) 114 int cbUtf8Codepoint = utf32_to_utf8(uc, achTmp, sizeof(achTmp)); 115 #else 116 int cbUtf8Codepoint = utf8_wctomb(achTmp, uc, sizeof(achTmp)); 117 #endif 118 if (cbUtf8Codepoint > 0) { 119 cchUtf8 += cbUtf8Codepoint; 120 offNls += cbNlsCodepoint; 121 } else { 122 Log(("vbsf_nls_to_shflstring: nls->uni2char(%#x) failed: %d\n", uc, cbUtf8Codepoint)); 123 return -EINVAL; 124 } 125 } else { 126 Log(("vbsf_nls_to_shflstring: nls->char2uni(%.*Rhxs) failed: %d\n", 127 RT_MIN(8, cchNls - offNls), &pszNls[offNls], cbNlsCodepoint)); 128 return -EINVAL; 129 } 130 } 131 if (cchUtf8 + 1 < _64K) { 132 /* Allocate: */ 133 pString = (PSHFLSTRING)kmalloc(SHFLSTRING_HEADER_SIZE + cchUtf8 + 1, GFP_KERNEL); 134 if (pString) { 135 char *pchDst = pString->String.ach; 136 pString->u16Length = (uint16_t)cchUtf8; 137 pString->u16Size = (uint16_t)(cchUtf8 + 1); 138 139 /* Do the conversion (cchUtf8 is counted down): */ 140 rc = 0; 141 offNls = 0; 142 while (offNls < cchNls) { 143 linux_wchar_t uc; /* Note! We renamed the type due to clashes. */ 144 int const cbNlsCodepoint = sf_g->nls->char2uni(&pszNls[offNls], cchNls - offNls, &uc); 145 if (cbNlsCodepoint >= 0) { 146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) 147 int cbUtf8Codepoint = utf32_to_utf8(uc, pchDst, cchUtf8); 148 #else 149 int cbUtf8Codepoint = utf8_wctomb(pchDst, uc, cchUtf8); 150 #endif 151 if (cbUtf8Codepoint > 0) { 152 AssertBreakStmt(cbUtf8Codepoint <= cchUtf8, rc = -EINVAL); 153 cchUtf8 -= cbUtf8Codepoint; 154 pchDst += cbUtf8Codepoint; 155 offNls += cbNlsCodepoint; 156 } else { 157 Log(("vbsf_nls_to_shflstring: nls->uni2char(%#x) failed! %d, cchUtf8=%zu\n", 158 uc, cbUtf8Codepoint, cchUtf8)); 159 rc = -EINVAL; 160 break; 161 } 162 } else { 163 Log(("vbsf_nls_to_shflstring: nls->char2uni(%.*Rhxs) failed! %d\n", 164 RT_MIN(8, cchNls - offNls), &pszNls[offNls], cbNlsCodepoint)); 165 rc = -EINVAL; 166 break; 167 } 168 } 169 if (rc == 0) { 170 /* 171 * Succeeded. Just terminate the string and we're good. 172 */ 173 Assert(pchDst - pString->String.ach == pString->u16Length); 174 *pchDst = '\0'; 175 } else { 176 kfree(pString); 177 pString = NULL; 178 } 179 } else { 180 Log(("vbsf_nls_to_shflstring: failed to allocate %u bytes\n", SHFLSTRING_HEADER_SIZE + cchUtf8 + 1)); 181 rc = -ENOMEM; 182 } 183 } else { 184 Log(("vbsf_nls_to_shflstring: too long: %zu bytes (%zu nls bytes)\n", cchUtf8, cchNls)); 185 rc = -ENAMETOOLONG; 186 } 187 } else { 188 /* 189 * UTF-8 -> UTF-8 w/ SHLF string header. 190 */ 191 if (cchNls + 1 < _64K) { 192 pString = (PSHFLSTRING)kmalloc(SHFLSTRING_HEADER_SIZE + cchNls + 1, GFP_KERNEL); 193 if (pString) { 194 pString->u16Length = (uint16_t)cchNls; 195 pString->u16Size = (uint16_t)(cchNls + 1); 196 memcpy(pString->String.ach, pszNls, cchNls); 197 pString->String.ach[cchNls] = '\0'; 198 rc = 0; 199 } else { 200 Log(("vbsf_nls_to_shflstring: failed to allocate %u bytes\n", SHFLSTRING_HEADER_SIZE + cchNls + 1)); 201 rc = -ENOMEM; 202 } 203 } else { 204 Log(("vbsf_nls_to_shflstring: too long: %zu bytes\n", cchNls)); 205 rc = -ENAMETOOLONG; 206 } 207 } 208 *ppString = pString; 209 return rc; 210 } 211 212 213 /** 92 214 * Convert from VBox to linux time. 93 215 */ … … 197 319 set_nlink(inode, 1); 198 320 } 199 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)200 321 else if (RTFS_IS_SYMLINK(pAttr->fMode)) { 201 322 /** @todo r=bird: Aren't System V symlinks w/o any mode mask? IIRC there is … … 204 325 inode->i_op = &vbsf_lnk_iops; 205 326 set_nlink(inode, 1); 206 } 207 #endif 208 else { 327 } else { 209 328 inode->i_mode = sf_file_mode_to_linux(pAttr->fMode, sf_g->fmode, sf_g->fmask, S_IFREG); 210 329 inode->i_op = &vbsf_reg_iops; … … 261 380 if (RTFS_IS_DIRECTORY(pAttr->fMode)) 262 381 fMode = sf_file_mode_to_linux(pAttr->fMode, sf_g->dmode, sf_g->dmask, S_IFDIR); 263 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)264 382 else if (RTFS_IS_SYMLINK(pAttr->fMode)) 265 383 /** @todo r=bird: Aren't System V symlinks w/o any mode mask? IIRC there is 266 384 * no lchmod on Linux. */ 267 385 fMode = sf_file_mode_to_linux(pAttr->fMode, sf_g->fmode, sf_g->fmask, S_IFLNK); 268 #endif269 386 else 270 387 fMode = sf_file_mode_to_linux(pAttr->fMode, sf_g->fmode, sf_g->fmask, S_IFREG); … … 828 945 * [vbsf_make_path] which will allocate SHFLSTRING and fill it in 829 946 */ 830 int vbsf_path_from_dentry( const char *caller, struct vbsf_super_info *sf_g, struct vbsf_inode_info *sf_i,831 struct dentry *dentry, SHFLSTRING **result)947 int vbsf_path_from_dentry(struct vbsf_super_info *sf_g, struct vbsf_inode_info *sf_i, struct dentry *dentry, SHFLSTRING **result, 948 const char *caller) 832 949 { 833 950 int err; -
trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c
r77854 r77858 70 70 spinlock_t g_SfHandleLock; 71 71 72 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 52) 72 /** The 'follow_symlinks' module parameter. 73 * @todo Figure out how do this for 2.4.x! */ 73 74 static int g_fFollowSymlinks = 0; 74 #endif75 75 76 76 /* forward declaration */ … … 871 871 rc = VbglR0SfHostReqSetUtf8Simple(); 872 872 if (RT_SUCCESS(rc)) { 873 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)874 873 if (!g_fFollowSymlinks) { 875 874 rc = VbglR0SfHostReqSetSymlinksSimple(); 876 875 if (RT_FAILURE(rc)) 877 printk(KERN_WARNING "vboxsf: Host unable to showsymlinks, rc=%d\n", rc);876 printk(KERN_WARNING "vboxsf: Host unable to enable showing symlinks, rc=%d\n", rc); 878 877 } 879 #endif880 878 /* 881 879 * Now that we're ready for action, try register the … … 929 927 module_param_named(follow_symlinks, g_fFollowSymlinks, int, 0); 930 928 MODULE_PARM_DESC(follow_symlinks, 931 "Let host resolve symlinks rather than showing them");929 "Let host resolve symlinks rather than showing them"); 932 930 #endif 933 931 -
trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h
r77853 r77858 394 394 395 395 extern int vbsf_stat(const char *caller, struct vbsf_super_info *sf_g, SHFLSTRING * path, PSHFLFSOBJINFO result, int ok_to_fail); 396 extern int vbsf_path_from_dentry( const char *caller, struct vbsf_super_info *sf_g, struct vbsf_inode_info *sf_i,397 struct dentry *dentry, SHFLSTRING ** result);396 extern int vbsf_path_from_dentry(struct vbsf_super_info *sf_g, struct vbsf_inode_info *sf_i, struct dentry *dentry, 397 SHFLSTRING ** result, const char *caller); 398 398 extern int vbsf_nlscpy(struct vbsf_super_info *sf_g, char *name, size_t name_bound_len, 399 399 const unsigned char *utf8_name, size_t utf8_len); 400 extern int vbsf_nls_to_shflstring(struct vbsf_super_info *sf_g, const char *pszNls, PSHFLSTRING *ppString); 400 401 401 402
Note:
See TracChangeset
for help on using the changeset viewer.