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