]> source.dussan.org Git - nextcloud-server.git/commitdiff
only fetch the data for mounts inside a folder when needed 36610/head
authorRobin Appelman <robin@icewind.nl>
Wed, 8 Feb 2023 13:34:40 +0000 (14:34 +0100)
committerRobin Appelman <robin@icewind.nl>
Thu, 9 Feb 2023 10:39:00 +0000 (11:39 +0100)
for most operations we don't actually care about any mounts inside a folder, only for metadata that needs to propagate across storage boundaries (size, etag, mtime) do we need all the submount info.

By only loading this data when needed we can save a bunch of storage setup in a number of cases

Signed-off-by: Robin Appelman <robin@icewind.nl>
lib/private/Files/Node/File.php
lib/private/Files/Node/Folder.php
lib/private/Files/Node/Node.php
lib/private/Files/Node/Root.php
lib/private/Files/View.php

index d8a6741dc6ee2a4fa2a48ed8894c10c9bc4b8411..475930b361a48a312b2016d381e6a0e5c4d92b75 100644 (file)
@@ -37,7 +37,7 @@ class File extends Node implements \OCP\Files\File {
         * Creates a Folder that represents a non-existing path
         *
         * @param string $path path
-        * @return string non-existing node class
+        * @return NonExistingFile non-existing node
         */
        protected function createNonExistingNode($path) {
                return new NonExistingFile($this->root, $this->view, $path);
index bf9ae3c148d5c6092709f6b9c98d46d61784cd92..90aed642a2d1972e83da173f4b61b135bc7d2d93 100644 (file)
@@ -54,7 +54,7 @@ class Folder extends Node implements \OCP\Files\Folder {
         * Creates a Folder that represents a non-existing path
         *
         * @param string $path path
-        * @return string non-existing node class
+        * @return NonExistingFolder non-existing node
         */
        protected function createNonExistingNode($path) {
                return new NonExistingFolder($this->root, $this->view, $path);
@@ -98,7 +98,7 @@ class Folder extends Node implements \OCP\Files\Folder {
         * @throws \OCP\Files\NotFoundException
         */
        public function getDirectoryListing() {
-               $folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo());
+               $folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo(false));
 
                return array_map(function (FileInfo $info) {
                        if ($info->getMimetype() === FileInfo::MIMETYPE_FOLDER) {
@@ -114,7 +114,7 @@ class Folder extends Node implements \OCP\Files\Folder {
         * @param FileInfo $info
         * @return File|Folder
         */
-       protected function createNode($path, FileInfo $info = null) {
+       protected function createNode($path, FileInfo $info = null, bool $infoHasSubMountsIncluded = true) {
                if (is_null($info)) {
                        $isDir = $this->view->is_dir($path);
                } else {
@@ -122,7 +122,7 @@ class Folder extends Node implements \OCP\Files\Folder {
                }
                $parent = dirname($path) === $this->getPath() ? $this : null;
                if ($isDir) {
-                       return new Folder($this->root, $this->view, $path, $info, $parent);
+                       return new Folder($this->root, $this->view, $path, $info, $parent, $infoHasSubMountsIncluded);
                } else {
                        return new File($this->root, $this->view, $path, $info, $parent);
                }
index 6c4e0b0f9085f1f2d2a6e2e4ac03167974b47482..2f88cc3a15acd3faa85aad8222000fa1f7aa14c3 100644 (file)
@@ -56,35 +56,35 @@ class Node implements \OCP\Files\Node {
         */
        protected $path;
 
-       /**
-        * @var \OCP\Files\FileInfo
-        */
-       protected $fileInfo;
+       protected ?FileInfo $fileInfo;
 
        /**
         * @var Node|null
         */
        protected $parent;
 
+       private bool $infoHasSubMountsIncluded;
+
        /**
         * @param \OC\Files\View $view
         * @param \OCP\Files\IRootFolder $root
         * @param string $path
         * @param FileInfo $fileInfo
         */
-       public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null) {
+       public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null, bool $infoHasSubMountsIncluded = true) {
                $this->view = $view;
                $this->root = $root;
                $this->path = $path;
                $this->fileInfo = $fileInfo;
                $this->parent = $parent;
+               $this->infoHasSubMountsIncluded = $infoHasSubMountsIncluded;
        }
 
        /**
         * Creates a Node of the same type that represents a non-existing path
         *
         * @param string $path path
-        * @return string non-existing node class
+        * @return Node non-existing node
         * @throws \Exception
         */
        protected function createNonExistingNode($path) {
@@ -98,17 +98,23 @@ class Node implements \OCP\Files\Node {
         * @throws InvalidPathException
         * @throws NotFoundException
         */
-       public function getFileInfo() {
+       public function getFileInfo(bool $includeMountPoint = true) {
                if (!$this->fileInfo) {
                        if (!Filesystem::isValidPath($this->path)) {
                                throw new InvalidPathException();
                        }
-                       $fileInfo = $this->view->getFileInfo($this->path);
+                       $fileInfo = $this->view->getFileInfo($this->path, $includeMountPoint);
+                       $this->infoHasSubMountsIncluded = $includeMountPoint;
                        if ($fileInfo instanceof FileInfo) {
                                $this->fileInfo = $fileInfo;
                        } else {
                                throw new NotFoundException();
                        }
+               } elseif ($includeMountPoint && !$this->infoHasSubMountsIncluded && $this instanceof Folder) {
+                       if ($this->fileInfo instanceof \OC\Files\FileInfo) {
+                               $this->view->addSubMounts($this->fileInfo);
+                       }
+                       $this->infoHasSubMountsIncluded = true;
                }
                return $this->fileInfo;
        }
@@ -179,7 +185,7 @@ class Node implements \OCP\Files\Node {
         * @return string
         */
        public function getInternalPath() {
-               return $this->getFileInfo()->getInternalPath();
+               return $this->getFileInfo(false)->getInternalPath();
        }
 
        /**
@@ -188,7 +194,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function getId() {
-               return $this->getFileInfo()->getId();
+               return $this->getFileInfo(false)->getId() ?? -1;
        }
 
        /**
@@ -232,7 +238,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function getPermissions() {
-               return $this->getFileInfo()->getPermissions();
+               return $this->getFileInfo(false)->getPermissions();
        }
 
        /**
@@ -241,7 +247,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function isReadable() {
-               return $this->getFileInfo()->isReadable();
+               return $this->getFileInfo(false)->isReadable();
        }
 
        /**
@@ -250,7 +256,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function isUpdateable() {
-               return $this->getFileInfo()->isUpdateable();
+               return $this->getFileInfo(false)->isUpdateable();
        }
 
        /**
@@ -259,7 +265,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function isDeletable() {
-               return $this->getFileInfo()->isDeletable();
+               return $this->getFileInfo(false)->isDeletable();
        }
 
        /**
@@ -268,7 +274,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function isShareable() {
-               return $this->getFileInfo()->isShareable();
+               return $this->getFileInfo(false)->isShareable();
        }
 
        /**
@@ -277,7 +283,7 @@ class Node implements \OCP\Files\Node {
         * @throws NotFoundException
         */
        public function isCreatable() {
-               return $this->getFileInfo()->isCreatable();
+               return $this->getFileInfo(false)->isCreatable();
        }
 
        /**
@@ -328,42 +334,42 @@ class Node implements \OCP\Files\Node {
        }
 
        public function isMounted() {
-               return $this->getFileInfo()->isMounted();
+               return $this->getFileInfo(false)->isMounted();
        }
 
        public function isShared() {
-               return $this->getFileInfo()->isShared();
+               return $this->getFileInfo(false)->isShared();
        }
 
        public function getMimeType() {
-               return $this->getFileInfo()->getMimetype();
+               return $this->getFileInfo(false)->getMimetype();
        }
 
        public function getMimePart() {
-               return $this->getFileInfo()->getMimePart();
+               return $this->getFileInfo(false)->getMimePart();
        }
 
        public function getType() {
-               return $this->getFileInfo()->getType();
+               return $this->getFileInfo(false)->getType();
        }
 
        public function isEncrypted() {
-               return $this->getFileInfo()->isEncrypted();
+               return $this->getFileInfo(false)->isEncrypted();
        }
 
        public function getMountPoint() {
-               return $this->getFileInfo()->getMountPoint();
+               return $this->getFileInfo(false)->getMountPoint();
        }
 
        public function getOwner() {
-               return $this->getFileInfo()->getOwner();
+               return $this->getFileInfo(false)->getOwner();
        }
 
        public function getChecksum() {
        }
 
        public function getExtension(): string {
-               return $this->getFileInfo()->getExtension();
+               return $this->getFileInfo(false)->getExtension();
        }
 
        /**
index 8d0a65d2a68fcb6502fb918237cccf8b2a4a2135..29cdbb987c350810b738c48f3284f410474f1f63 100644 (file)
@@ -202,9 +202,9 @@ class Root extends Folder implements IRootFolder {
                $path = $this->normalizePath($path);
                if ($this->isValidPath($path)) {
                        $fullPath = $this->getFullPath($path);
-                       $fileInfo = $this->view->getFileInfo($fullPath);
+                       $fileInfo = $this->view->getFileInfo($fullPath, false);
                        if ($fileInfo) {
-                               return $this->createNode($fullPath, $fileInfo);
+                               return $this->createNode($fullPath, $fileInfo, false);
                        } else {
                                throw new NotFoundException($path);
                        }
index f79a992c77372a019a880f3e0d111326409f1da4..456f804ee561772abdbd9dec4b517130ddc7cf92 100644 (file)
@@ -1412,11 +1412,7 @@ class View {
                                if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') {
                                        //add the sizes of other mount points to the folder
                                        $extOnly = ($includeMountPoints === 'ext');
-                                       $mounts = Filesystem::getMountManager()->findIn($path);
-                                       $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
-                                               $subStorage = $mount->getStorage();
-                                               return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
-                                       }));
+                                       $this->addSubMounts($info, $extOnly);
                                }
                        }
 
@@ -1428,6 +1424,17 @@ class View {
                return false;
        }
 
+       /**
+        * Extend a FileInfo that was previously requested with `$includeMountPoints = false` to include the sub mounts
+        */
+       public function addSubMounts(FileInfo $info, $extOnly = false): void {
+               $mounts = Filesystem::getMountManager()->findIn($info->getPath());
+               $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
+                       $subStorage = $mount->getStorage();
+                       return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
+               }));
+       }
+
        /**
         * get the content of a directory
         *