@@ -488,28 +488,48 @@ public function clear(): void {
488488 }
489489
490490 public function getMountForPath (IUser $ user , string $ path ): ICachedMountInfo {
491- $ mounts = [];
492- foreach ($ this ->getMountsForUser ($ user ) as $ mount ) {
493- $ mounts [$ mount ->getMountPoint ()] = $ mount ;
494- }
495-
491+ $ searchPaths = [];
496492 $ current = rtrim ($ path , '/ ' );
497- // walk up the directory tree until we find a path that has a mountpoint set
498- // the loop will return if a mountpoint is found or break if none are found
499- while (true ) {
493+ // get all paths that we are interested in, $path and all it's parents
494+ while ($ current !== '' ) {
500495 $ mountPoint = $ current . '/ ' ;
501- if (isset ($ mounts [$ mountPoint ])) {
502- return $ mounts [$ mountPoint ];
503- } elseif ($ current === '' ) {
504- break ;
505- }
496+
497+ $ searchPaths [] = $ mountPoint ;
506498
507499 $ current = dirname ($ current );
508500 if ($ current === '. ' || $ current === '/ ' ) {
509501 $ current = '' ;
510502 }
511503 }
512504
505+ $ mounts = [];
506+ if (isset ($ this ->mountsForUsers [$ user ->getUID ()])) {
507+ foreach ($ this ->mountsForUsers [$ user ->getUID ()] as $ mount ) {
508+ $ mounts [$ mount ->getMountPoint ()] = $ mount ;
509+ }
510+ } else {
511+ $ searchPathHashes = array_map (static fn (string $ path ) => hash ('xxh128 ' , $ path ), $ searchPaths );
512+
513+ $ builder = $ this ->connection ->getQueryBuilder ();
514+ $ query = $ builder ->select ('storage_id ' , 'root_id ' , 'user_id ' , 'mount_point ' , 'mount_id ' , 'f.path ' , 'mount_provider_class ' )
515+ ->from ('mounts ' , 'm ' )
516+ ->innerJoin ('m ' , 'filecache ' , 'f ' , $ builder ->expr ()->eq ('m.root_id ' , 'f.fileid ' ))
517+ ->where ($ builder ->expr ()->eq ('user_id ' , $ builder ->createNamedParameter ($ user ->getUID ())))
518+ ->andWhere ($ builder ->expr ()->in ('mount_point_hash ' , $ builder ->createNamedParameter ($ searchPathHashes , IQueryBuilder::PARAM_STR_ARRAY )));
519+
520+ foreach ($ query ->executeQuery ()->fetchAll () as $ row ) {
521+ $ mount = $ this ->dbRowToMountInfo ($ row );
522+ $ mounts [$ mount ->getMountPoint ()] = $ mount ;
523+ }
524+ }
525+
526+ // note that $searchPaths is sorted deepest path first
527+ foreach ($ searchPaths as $ searchPath ) {
528+ if (isset ($ mounts [$ searchPath ])) {
529+ return $ mounts [$ searchPath ];
530+ }
531+ }
532+
513533 throw new NotFoundException ('No cached mount for path ' . $ path );
514534 }
515535
0 commit comments