Changeset 77461 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Feb 25, 2019 3:44:39 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/utils.c
r77424 r77461 182 182 } 183 183 184 /** 185 * Update the inode with new object info from the host. 186 */ 187 void sf_update_inode(struct inode *pInode, PSHFLFSOBJINFO pObjInfo, struct sf_glob_info *sf_g) 188 { 189 /** @todo make lock/rcu safe. */ 190 sf_init_inode(sf_g, pInode, pObjInfo); 191 } 192 193 184 194 int sf_stat(const char *caller, struct sf_glob_info *sf_g, 185 195 SHFLSTRING *path, PSHFLFSOBJINFO result, int ok_to_fail) … … 223 233 } 224 234 225 /* this is called directly as iop on 2.4, indirectly as dop 226 [sf_dentry_revalidate] on 2.4/2.6, indirectly as iop through 227 [sf_getattr] on 2.6. the job is to find out whether dentry/inode is 228 still valid. the test is failed if [dentry] does not have an inode 229 or [sf_stat] is unsuccessful, otherwise we return success and 230 update inode attributes */ 235 /** 236 * Revalidate an inode. 237 * 238 * This is called directly as inode-op on 2.4, indirectly as dir-op 239 * sf_dentry_revalidate() on 2.4/2.6, indirectly as inode-op through 240 * sf_getattr() on 2.6. The job is to find out whether dentry/inode is still 241 * valid. The test fails if @a dentry does not have an inode or sf_stat() is 242 * unsuccessful, otherwise we return success and update inode attributes. 243 */ 231 244 int sf_inode_revalidate(struct dentry *dentry) 232 245 { 233 int err; 234 struct sf_glob_info *sf_g; 235 struct sf_inode_info *sf_i; 236 SHFLFSOBJINFO info; 237 238 TRACE(); 239 if (!dentry || !dentry->d_inode) { 240 LogFunc(("no dentry(%p) or inode(%p)\n", dentry, dentry ? dentry->d_inode : NULL)); 241 return -EINVAL; 242 } 243 244 sf_g = GET_GLOB_INFO(dentry->d_inode->i_sb); 245 sf_i = GET_INODE_INFO(dentry->d_inode); 246 247 #if 0 248 printk("%s called by %p:%p\n", 249 sf_i->path->String.utf8, 250 __builtin_return_address(0), __builtin_return_address(1)); 251 #endif 252 253 BUG_ON(!sf_g); 254 BUG_ON(!sf_i); 255 256 if (!sf_i->force_restat) { 257 if (jiffies - dentry->d_time < sf_g->ttl) 258 return 0; 259 } 260 261 err = sf_stat(__func__, sf_g, sf_i->path, &info, 1); 262 if (err) 263 return err; 264 265 dentry->d_time = jiffies; 266 /** @todo bird has severe inode locking / rcu concerns here: */ 267 sf_init_inode(sf_g, dentry->d_inode, &info); 268 return 0; 246 int rc; 247 struct inode *pInode = dentry ? dentry->d_inode : NULL; 248 if (pInode) { 249 struct sf_inode_info *sf_i = GET_INODE_INFO(pInode); 250 struct sf_glob_info *sf_g = GET_GLOB_INFO(pInode->i_sb); 251 AssertReturn(sf_i, -EINVAL); 252 AssertReturn(sf_g, -EINVAL); 253 254 /* 255 * Can we get away without any action here? 256 */ 257 if ( !sf_i->force_restat 258 && jiffies - dentry->d_time < sf_g->ttl) 259 rc = 0; 260 else { 261 /* 262 * No, we have to query the file info from the host. 263 * Try get a handle we can query, any kind of handle will do here. 264 */ 265 struct sf_handle *pHandle = sf_handle_find(sf_i, 0, 0); 266 if (pHandle) { 267 /* Query thru pHandle. */ 268 VBOXSFOBJINFOREQ *pReq = (VBOXSFOBJINFOREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq)); 269 if (pReq) { 270 RT_ZERO(*pReq); 271 rc = VbglR0SfHostReqQueryObjInfo(sf_g->map.root, pReq, pHandle->hHost); 272 if (RT_SUCCESS(rc)) { 273 /* 274 * Reset the TTL and copy the info over into the inode structure. 275 */ 276 dentry->d_time = jiffies; 277 sf_update_inode(pInode, &pReq->ObjInfo, sf_g); 278 } else if (rc == VERR_INVALID_HANDLE) { 279 rc = -ENOENT; /* Restore.*/ 280 } else { 281 LogFunc(("VbglR0SfHostReqQueryObjInfo failed on %#RX64: %Rrc\n", pHandle->hHost, rc)); 282 rc = -RTErrConvertToErrno(rc); 283 } 284 VbglR0PhysHeapFree(pReq); 285 } else 286 rc = -ENOMEM; 287 sf_handle_release(pHandle, sf_g, "sf_inode_revalidate"); 288 289 } else { 290 /* Query via path. */ 291 SHFLSTRING *pPath = sf_i->path; 292 VBOXSFCREATEREQ *pReq = (VBOXSFCREATEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq) + pPath->u16Size); 293 if (pReq) { 294 RT_ZERO(*pReq); 295 memcpy(&pReq->StrPath, pPath, SHFLSTRING_HEADER_SIZE + pPath->u16Size); 296 pReq->CreateParms.Handle = SHFL_HANDLE_NIL; 297 pReq->CreateParms.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW; 298 299 rc = VbglR0SfHostReqCreate(sf_g->map.root, pReq); 300 if (RT_SUCCESS(rc)) { 301 if (pReq->CreateParms.Result == SHFL_FILE_EXISTS) { 302 /* 303 * Reset the TTL and copy the info over into the inode structure. 304 */ 305 dentry->d_time = jiffies; 306 sf_update_inode(pInode, &pReq->CreateParms.Info, sf_g); 307 rc = 0; 308 } else { 309 rc = -ENOENT; 310 } 311 } else if (rc == VERR_INVALID_NAME) { 312 rc = -ENOENT; /* this can happen for names like 'foo*' on a Windows host */ 313 } else { 314 LogFunc(("VbglR0SfHostReqCreate failed on %s: %Rrc\n", pPath->String.ach, rc)); 315 rc = -EPROTO; 316 } 317 VbglR0PhysHeapFree(pReq); 318 } 319 else 320 rc = -ENOMEM; 321 } 322 } 323 } else { 324 LogFunc(("no dentry(%p) or inode(%p)\n", dentry, pInode)); 325 rc = -EINVAL; 326 } 327 return rc; 269 328 } 270 329 … … 306 365 */ 307 366 dentry->d_time = jiffies; 308 /** @todo bird has severe inode locking / rcu concerns here: */ 309 sf_init_inode(sf_g, pInode, &pReq->ObjInfo); 367 sf_update_inode(pInode, &pReq->ObjInfo, sf_g); 310 368 } else { 311 369 LogFunc(("VbglR0SfHostReqQueryObjInfo failed on %#RX64: %Rrc\n", hHostFile, err)); … … 362 420 # endif 363 421 { 364 int err;422 int rc; 365 423 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) 366 424 struct dentry *dentry = path->dentry; 367 425 # endif 368 426 369 TRACE(); 370 err = sf_inode_revalidate(dentry); 371 if (err) 372 return err; 373 374 generic_fillattr(dentry->d_inode, kstat); 375 376 /* 377 * FsPerf shows the following numbers for sequential file access against 378 * a tmpfs folder on an AMD 1950X host running debian buster/sid: 379 * 380 * block size = r128600 ----- r128755 ----- 381 * reads reads writes 382 * 4096 KB = 2254 MB/s 4953 MB/s 3668 MB/s 383 * 2048 KB = 2368 MB/s 4908 MB/s 3541 MB/s 384 * 1024 KB = 2208 MB/s 4011 MB/s 3291 MB/s 385 * 512 KB = 1908 MB/s 3399 MB/s 2721 MB/s 386 * 256 KB = 1625 MB/s 2679 MB/s 2251 MB/s 387 * 128 KB = 1413 MB/s 1967 MB/s 1684 MB/s 388 * 64 KB = 1152 MB/s 1409 MB/s 1265 MB/s 389 * 32 KB = 726 MB/s 815 MB/s 783 MB/s 390 * 16 KB = 683 MB/s 475 MB/s 391 * 8 KB = 294 MB/s 286 MB/s 392 * 4 KB = 145 MB/s 156 MB/s 149 MB/s 393 * 394 */ 395 if (S_ISREG(kstat->mode)) 396 kstat->blksize = _1M; 397 else if (S_ISDIR(kstat->mode)) 398 /** @todo this may need more tuning after we rewrite the directory handling. */ 399 kstat->blksize = _16K; 400 return 0; 427 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) 428 SFLOGFLOW(("sf_getattr: dentry=%p request_mask=%#x flags=%#x\n", dentry, request_mask, flags)); 429 # else 430 SFLOGFLOW(("sf_getattr: dentry=%p\n", dentry)); 431 # endif 432 433 rc = sf_inode_revalidate(dentry); 434 if (rc == 0) { 435 generic_fillattr(dentry->d_inode, kstat); 436 437 /* 438 * FsPerf shows the following numbers for sequential file access against 439 * a tmpfs folder on an AMD 1950X host running debian buster/sid: 440 * 441 * block size = r128600 ----- r128755 ----- 442 * reads reads writes 443 * 4096 KB = 2254 MB/s 4953 MB/s 3668 MB/s 444 * 2048 KB = 2368 MB/s 4908 MB/s 3541 MB/s 445 * 1024 KB = 2208 MB/s 4011 MB/s 3291 MB/s 446 * 512 KB = 1908 MB/s 3399 MB/s 2721 MB/s 447 * 256 KB = 1625 MB/s 2679 MB/s 2251 MB/s 448 * 128 KB = 1413 MB/s 1967 MB/s 1684 MB/s 449 * 64 KB = 1152 MB/s 1409 MB/s 1265 MB/s 450 * 32 KB = 726 MB/s 815 MB/s 783 MB/s 451 * 16 KB = 683 MB/s 475 MB/s 452 * 8 KB = 294 MB/s 286 MB/s 453 * 4 KB = 145 MB/s 156 MB/s 149 MB/s 454 * 455 */ 456 if (S_ISREG(kstat->mode)) 457 kstat->blksize = _1M; 458 else if (S_ISDIR(kstat->mode)) 459 /** @todo this may need more tuning after we rewrite the directory handling. */ 460 kstat->blksize = _16K; 461 } 462 return rc; 401 463 } 402 464
Note:
See TracChangeset
for help on using the changeset viewer.