-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix file cache updater #5513
Fix file cache updater #5513
Conversation
…oesn't work for Shared files correctFolder() correct folder for the owner of the file. The Shared folder for the other users gets updated by the files_sharing app
Please use constants instead of magic numbers ( |
There is no constant. That's how it is done in other places of the filecache implementation, too. |
Oh, this is stable5. Can we at least make that a constant in master? |
I don't want to make larger changes to the file cache without discussing it with @icewind1991. |
Test failed. |
Any idea why this tests are failing... I don't see how this is connected to my changes. For example this error is obvious: https://ci.owncloud.org/job/pull-request-analyser/1766/testReport/junit/%28root%29/Test_Files_Cache_Scanner/testFile/ Here https://github.com/owncloud/core/blob/stable5/lib/files/cache/cache.php#L111 we cast some of the results to int but not 'parent' so I'm not surprised that the test which compares the result against an integer fails. But why does it only fails for my pull request. Did I missed something? |
If I cast the parent to integer on my local system the test still fails, than with the message:
Strange. 😨 |
Test failed. |
failed test might be related to #3568 |
👎 the changes to |
$id = $cache->getId($internalPath); | ||
if ($id !== -1) { | ||
$cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); | ||
self::correctFolder($parent, $time); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to keep this line - this is responsible for recursive etag change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The recursive call was replaced with a while loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok - thanks - I totally overlooked this.
Once more: sorry for the noise 😉
…ethod, this method always expect a path relativ to the current user
@icewind1991 the last commits should address your concerns. The test will probably still fail because operations like getOwner() and getFileInfo() doesn't work correctly in the test environment. To make it work we would probably have to change the tests in a way that it uses a real user and operates on a real file view. But this would be quite large changes to the tests. But I don't see a better solution. Opinions? |
Test failed. |
//$id = $cache->getParentId($internalPath); | ||
$internalPath = dirname($internalPath); | ||
// check storage for parent in case we change the storage in this step | ||
list($storage, $internalPath) = $view->resolvePath($internalPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will go wrong, you need to call dirname on $path
and use that in the resolvePath call.
Internal path is relative to the storage and thus will never go outside the storage with dirname
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. We need to update the whole tree from the original path (internalPath). Imagine following situation:
user1 has /folder1/folder2/folder3
and shares folder3
with user2. For user2 this will look like /Shared/folder3
and that's also the path we will receive here, for example if user2 uploads a file to the shared folder. dirname() from $path
would return Shared
but we want to iterate over /folder1/folder2/folder3
to update the original path. That's why we need to iterate over the internalPath which is the correct /folder1/folder2/folder3
I also tried it both with nested Shares and with nested folder from the same user. It works fine in real world. The only problem are the tests.
Internal path is relative to the storage and thus will never go outside the storage with dirname
I think I see your point... But how do we solve it correctly? As shown with the example above we need to iterate over the "real path" to update the owners path correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the crucial point is that I need to get somehow the complete path from the owner of a file/folder independent for any storage which might be mounted in between. Does our file system provides any method to get such a path? I couldn't find one until now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
user1 has /folder1/folder2/folder3 and shares folder3 with user2. For user2 this will look like /Shared/folder3 and that's also the path we will receive here, for example if user2 uploads a file to the shared folder. dirname() from $path would return Shared but we want to iterate over /folder1/folder2/folder3 to update the original path. That's why we need to iterate over the internalPath which is the correct /folder1/folder2/folder3
Internal path won't be /folder1/folder2/folder3
though for a shared file, it would be folder3
because it's relative to the shared storage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During my tests this PR's resolvePath() returned /folder1/folder2/folder3
, keep in mind that I also did some small changes to resolvePath() which you can see above.
…to be updated check the storage for every iteration to make sure that we update the correct cache entry
OK, now I think I took all possible situations into account.
|
Test failed. |
…sn't use a completely initialized oc filesystem
Test passed. |
Yea, finally tests are passing as well. 😄 @icewind1991 Can you please have a final look? Thanks! |
👍 looks good now |
Great! Can I have a second reviewer? Maybe @DeepDiver1975 or @PVince81 ? Thanks! |
looks good 👍 |
* @return array with the oweners uid and the owners path | ||
*/ | ||
public static function getUidAndFilename($filename) { | ||
$uid = \OC\Files\Filesystem::getOwner($filename); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to move this to the FileSystem or View class instead of the Updater ? This way it can be used in other places where the user might be needed ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. Here we need the path relative to data/user
in most other cases you would probably need the path relative to data/user/files
Fix file cache updater (backport to master of #5513)
This fixes bug #5098
For a detailed explanation how to reproduce it look at: owncloud/client#1056 (comment)
@icewind1991 please have a look. correctFolder() always assumed that we are operating on a folder owned by the current user which of course is wrong in case of a shared file. That's why I changed resolvePath() to resolve the path to the owners path and updated the correctFolder() method to loop though the correct folder tree.
Also affects master, will port it once the fix is merged for stable5.