After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 766294 - Different GFiles for same FUSE path with g_file_new_for_commandline_arg
Different GFiles for same FUSE path with g_file_new_for_commandline_arg
Status: RESOLVED FIXED
Product: gvfs
Classification: Core
Component: client module
unspecified
Other All
: Normal normal
: ---
Assigned To: gvfs-maint
gvfs-maint
Depends on:
Blocks: 740436
 
 
Reported: 2016-05-11 21:14 UTC by Jens Georg
Modified: 2016-05-20 18:13 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
wip (1.85 KB, patch)
2016-05-11 21:14 UTC, Jens Georg
none Details | Review
Add mount prefix in cached fuse paths (2.75 KB, patch)
2016-05-11 21:15 UTC, Jens Georg
none Details | Review
Always add mount prefix in cached fuse paths (3.39 KB, patch)
2016-05-12 17:29 UTC, Jens Georg
none Details | Review
Always add mount prefix in cached fuse paths (4.02 KB, patch)
2016-05-19 18:14 UTC, Jens Georg
committed Details | Review

Description Jens Georg 2016-05-11 21:14:01 UTC
result in two identical GFiles for WebDAV shares if the share is mounted:

Simple test code:



int main(int argc, char *argv[])
{
    char path[] = "/run/user/1000/gvfs/dav:host=shotwell-project.org,ssl=false,prefix=%2Fdav/Capture.PNG";
    GFile *f = g_file_new_for_commandline_arg (path);
    GFile *g = g_file_new_for_commandline_arg (path);

    g_print ("f: %s (local: %s) %s\ng: %s (local: %s) %s \n\n",
            g_file_get_path (f), G_OBJECT_TYPE_NAME (f), g_file_get_uri (f),
            g_file_get_path (g), G_OBJECT_TYPE_NAME (g), g_file_get_uri (g));

    g_assert(g_file_equal (f, g));

    return 0;
}

Output:

/run/user/1000/gvfs/dav:host=shotwell-project.org,ssl=false,prefix=%2Fdav/Capture.PNG
(local: GDaemonFile) dav://shotwell-project.org/dav/Capture.PNG
(null) (local: GDaemonFile) dav://shotwell-project.org/Capture.PNG 

**
ERROR:foo.c:13:main: assertion failed: (g_file_equal (f, g))
Aborted (core dumped)
Comment 1 Jens Georg 2016-05-11 21:14:05 UTC
Created attachment 327667 [details] [review]
wip

Signed-off-by: Jens Georg <mail@jensge.org>
Comment 2 Jens Georg 2016-05-11 21:14:55 UTC
Comment on attachment 327667 [details] [review]
wip

Sorry, sent from wrong git repository
Comment 3 Jens Georg 2016-05-11 21:15:38 UTC
Created attachment 327668 [details] [review]
Add mount prefix in cached fuse paths

If a fuse path is encountered the first time, the fuse path is re-created
taking the mount prefix into account. When the file is created for the path
the second time from the cached mount info, the mount prefix is silently
ignored, causing the new file not to be equal to the old one (it is even
invalid):

This change uses the mount prefix if available to construct the path just as
the code does on first use.
Comment 4 Ondrej Holy 2016-05-12 06:48:34 UTC
Review of attachment 327668 [details] [review]:

Thanks for the patch! It looks basically good, however similar code to convert GMountInfo to mount_path is already in _g_daemon_vfs_get_mount_info_by_fuse_sync. So it would be good to add new function with this functionality and use it on the both places, or just return info from lookup_mount_info_by_fuse_path_in_cache (not mount_path) and continue processing in _g_daemon_vfs_get_mount_info_by_fuse_sync.
Comment 5 Jens Georg 2016-05-12 07:04:49 UTC
Ah, right, good point.
Comment 6 Jens Georg 2016-05-12 17:29:43 UTC
Created attachment 327731 [details] [review]
Always add mount prefix in cached fuse paths

If a fuse path is encountered the first time, the fuse path is re-created
taking the mount prefix into account. When the file is created for the path
the second time from the cached mount info, the mount prefix is silently
ignored, causing the new file not to be equal to the old one (it is even
invalid):

This change just looks up the mount info in the cache and then continues
constructing the path as it would without having the info cached.
Comment 7 Jens Georg 2016-05-12 17:30:24 UTC
I did the "remove code" option. It seemed cleaner to me.
Comment 8 Ondrej Holy 2016-05-13 07:16:51 UTC
Review of attachment 327731 [details] [review]:

Thanks for the updated patch!

::: client/gdaemonvfs.c
@@ +717,3 @@
       if (mount_info->fuse_mountpoint != NULL &&
 	  g_str_has_prefix (fuse_path, mount_info->fuse_mountpoint))
+            break;

This doesn't work, it always returns NULL, because info variable is not set. Also you have to check fuse_path[len] to be sure it is same mount...

There should be something like:
{
  int len = strlen (mount_info->fuse_mountpoint);
  if (fuse_path[len] == 0 || fuse_path[len] == '/')
    {
      info = g_mount_info_ref (mount_info);
      break;
    }
}

@@ +967,3 @@
   GVariant *iter_mount;
 
+  info = lookup_mount_info_by_fuse_path_in_cache (fuse_path);

Be careful g_object_unref (proxy) at the end of _g_daemon_vfs_get_mount_info_by_fuse_sync may be called with uninitialized proxy if the info is returned from cache. You should unref the proxy in this following statement, or unref it later conditionally...
Comment 9 Jens Georg 2016-05-14 18:57:02 UTC
Review of attachment 327731 [details] [review]:

::: client/gdaemonvfs.c
@@ +717,3 @@
       if (mount_info->fuse_mountpoint != NULL &&
 	  g_str_has_prefix (fuse_path, mount_info->fuse_mountpoint))
+            break;

Dread, didn't see this. This would be similar code to path_has_prefix in common/gmountspec.c - would it make sense to make this somewhat reusable?

@@ +967,3 @@
   GVariant *iter_mount;
 
+  info = lookup_mount_info_by_fuse_path_in_cache (fuse_path);

Ah, good point
Comment 10 Ondrej Holy 2016-05-19 06:52:20 UTC
(In reply to Jens Georg from comment #9)
> Review of attachment 327731 [details] [review] [review]:
> 
> ::: client/gdaemonvfs.c
> @@ +717,3 @@
>        if (mount_info->fuse_mountpoint != NULL &&
>  	  g_str_has_prefix (fuse_path, mount_info->fuse_mountpoint))
> +            break;
> 
> Dread, didn't see this. This would be similar code to path_has_prefix in
> common/gmountspec.c - would it make sense to make this somewhat reusable?

Indeed, it would be nice to use one common function, it could help to avoid such bugs, however not sure how do you want to reuse it there... It is ok for me if you just fix the patch as per my previous review :-)
Comment 11 Jens Georg 2016-05-19 08:22:37 UTC
> > Dread, didn't see this. This would be similar code to path_has_prefix in
> > common/gmountspec.c - would it make sense to make this somewhat reusable?
> 
> Indeed, it would be nice to use one common function, it could help to avoid
> such bugs, however not sure how do you want to reuse it there... It is ok
> for me if you just fix the patch as per my previous review :-)

Just noticed that wile trying to find out what the difference between the two cache lookup functions was. Sorry, I was busy during the the week, I'll try to update the patch tonight
Comment 12 Jens Georg 2016-05-19 18:14:07 UTC
Created attachment 328218 [details] [review]
Always add mount prefix in cached fuse paths

If a fuse path is encountered the first time, the fuse path is re-created
taking the mount prefix into account. When the file is created for the path
the second time from the cached mount info, the mount prefix is silently
ignored, causing the new file not to be equal to the old one (it is even
invalid):

This change just looks up the mount info in the cache and then continues
constructing the path as it would without having the info cached.
Comment 13 Ondrej Holy 2016-05-20 07:15:26 UTC
Review of attachment 328218 [details] [review]:

Thanks, looks good to me! Please push to master and stable.

Usually, I complain about unnecessary whitespace changes, however it is also true that I want to get rid of the tabs...
Comment 14 Jens Georg 2016-05-20 18:13:47 UTC
Attachment 328218 [details] pushed as 7196c5c - Always add mount prefix in cached fuse paths