From 387709338c9f9d6eb49ce9052f1937da886c6218 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Wed, 24 Apr 2019 09:44:36 +0200 Subject: [PATCH 1/6] glocalfile: Handle smb2 filesystem type `G_FILE_ATTRIBUTE_FILESYSTEM_TYPE` is not set for CIFS mounts with `vers=2.0` option, or newer. Add `smb2` to the list of known filesystems. It is also reported by `stat -f`: https://github.com/coreutils/coreutils/blob/master/src/stat.c --- gio/glocalfile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 72ef947d4..9caa35b1c 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -690,6 +690,8 @@ get_fs_type (long f_type) return "smackfs"; case 0x517B: return "smb"; + case 0xfe534d42: + return "smb2"; case 0x534F434B: return "sockfs"; case 0x73717368: From d067b5390a343cc04feaf60fc8b16f375308d228 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Thu, 11 Jun 2020 17:31:39 +0200 Subject: [PATCH 2/6] glocalfile: Remove redundant private header There are glocalfile.h and glocalfileprivate.h header files currently. None of those header files is public, so it doesn't make sense to have two private headers for glocalfile.c. Let's remove glocalfileprivate.h. --- gio/glocalfile.c | 1 - gio/glocalfile.h | 2 ++ gio/glocalfileprivate.h | 30 ------------------------------ gio/gunixmounts.c | 2 +- 4 files changed, 3 insertions(+), 32 deletions(-) delete mode 100644 gio/glocalfileprivate.h diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 9caa35b1c..1effea5fa 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -51,7 +51,6 @@ #include "gfileattribute.h" #include "glocalfile.h" -#include "glocalfileprivate.h" #include "glocalfileinfo.h" #include "glocalfileenumerator.h" #include "glocalfileinputstream.h" diff --git a/gio/glocalfile.h b/gio/glocalfile.h index 960cfef1f..f3ec4f294 100644 --- a/gio/glocalfile.h +++ b/gio/glocalfile.h @@ -51,6 +51,8 @@ gboolean g_local_file_is_remote (const gchar *filename); GFile * g_local_file_new_from_dirname_and_basename (const char *dirname, const char *basename); +gchar *_g_local_file_find_topdir_for (const char *file_path); + G_END_DECLS #endif /* __G_LOCAL_FILE_H__ */ diff --git a/gio/glocalfileprivate.h b/gio/glocalfileprivate.h deleted file mode 100644 index 6b77305e7..000000000 --- a/gio/glocalfileprivate.h +++ /dev/null @@ -1,30 +0,0 @@ -/* GIO - GLib Input, Output and Streaming Library - * - * Copyright (C) 2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, see . - * - * Author: Ondrej Holy - */ - -#ifndef __G_LOCAL_FILE_PRIVATE_H__ -#define __G_LOCAL_FILE_PRIVATE_H__ - -G_BEGIN_DECLS - -gchar *_g_local_file_find_topdir_for (const char *file_path); - -G_END_DECLS - -#endif /* __G_LOCAL_FILE_PRIVATE_H__ */ diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c index 86aa22d66..0d3fa68b0 100644 --- a/gio/gunixmounts.c +++ b/gio/gunixmounts.c @@ -64,10 +64,10 @@ #endif #include "gunixmounts.h" -#include "glocalfileprivate.h" #include "gfile.h" #include "gfilemonitor.h" #include "glibintl.h" +#include "glocalfile.h" #include "gthemedicon.h" #include "gcontextspecificgroup.h" From 706dc6b5aa8e57c8621d7017fdbcf35e0c059602 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 15 Jun 2020 17:14:30 +0200 Subject: [PATCH 3/6] glocalfile: Fix G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE outside home The G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE currently works only for locations in the home directory. Let's make it work also for files outside the home directory. --- gio/glocalfile.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 1effea5fa..cc4d44898 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -112,6 +112,10 @@ G_DEFINE_TYPE_WITH_CODE (GLocalFile, g_local_file, G_TYPE_OBJECT, static char *find_mountpoint_for (const char *file, dev_t dev, gboolean resolve_basename_symlink); +#ifndef G_OS_WIN32 +static gboolean is_remote_fs (const gchar *filename); +#endif + static void g_local_file_finalize (GObject *object) { @@ -1111,11 +1115,13 @@ g_local_file_query_filesystem_info (GFile *file, get_mount_info (info, local->filename, attribute_matcher); #endif /* G_OS_WIN32 */ } - + +#ifndef G_OS_WIN32 if (g_file_attribute_matcher_matches (attribute_matcher, - G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE)) - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, - g_local_file_is_remote (local->filename)); + G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE)) + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, + is_remote_fs (local->filename)); +#endif g_file_attribute_matcher_unref (attribute_matcher); From f489f6c4eebc83200bbe862dbe3cc0658239eff2 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 15 Jun 2020 17:24:37 +0200 Subject: [PATCH 4/6] glocalfile: Do not call statfs/statvfs several times statfs/statvfs is called several times when querying filesystem info. This is because the G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE attribute is set over is_remote_fs function, which calls statfs/statvfs again. Let's use the already known fstype instead of redundant statfs/statvfs calls. This also changes g_local_file_is_remote implementation to use g_local_file_query_filesystem_info to obtain fstype, which allows to remove duplicated code from is_remote_fs function. --- gio/glocalfile.c | 54 ++++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/gio/glocalfile.c b/gio/glocalfile.c index cc4d44898..121d5e9ed 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -113,7 +113,7 @@ G_DEFINE_TYPE_WITH_CODE (GLocalFile, g_local_file, G_TYPE_OBJECT, static char *find_mountpoint_for (const char *file, dev_t dev, gboolean resolve_basename_symlink); #ifndef G_OS_WIN32 -static gboolean is_remote_fs (const gchar *filename); +static gboolean is_remote_fs_type (const gchar *fsname); #endif static void @@ -1120,7 +1120,7 @@ g_local_file_query_filesystem_info (GFile *file, if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE)) g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, - is_remote_fs (local->filename)); + is_remote_fs_type (fstype)); #endif g_file_attribute_matcher_unref (attribute_matcher); @@ -2524,43 +2524,8 @@ g_local_file_is_remote (const gchar *filename) #else static gboolean -is_remote_fs (const gchar *filename) +is_remote_fs_type (const gchar *fsname) { - const char *fsname = NULL; - -#ifdef USE_STATFS - struct statfs statfs_buffer; - int statfs_result = 0; - -#if STATFS_ARGS == 2 - statfs_result = statfs (filename, &statfs_buffer); -#elif STATFS_ARGS == 4 - statfs_result = statfs (filename, &statfs_buffer, sizeof (statfs_buffer), 0); -#endif - -#elif defined(USE_STATVFS) - struct statvfs statfs_buffer; - int statfs_result = 0; - - statfs_result = statvfs (filename, &statfs_buffer); -#else - return FALSE; -#endif - - if (statfs_result == -1) - return FALSE; - -#ifdef USE_STATFS -#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) - fsname = statfs_buffer.f_fstypename; -#else - fsname = get_fs_type (statfs_buffer.f_type); -#endif - -#elif defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_BASETYPE) - fsname = statfs_buffer.f_basetype; -#endif - if (fsname != NULL) { if (strcmp (fsname, "nfs") == 0) @@ -2584,7 +2549,18 @@ g_local_file_is_remote (const gchar *filename) { if (g_once_init_enter (&initialized)) { - remote_home = is_remote_fs (home); + GFile *file; + GFileInfo *info; + const gchar *fs_type = NULL; + + file = _g_local_file_new (home); + info = g_local_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, NULL, NULL); + if (info != NULL) + fs_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE); + remote_home = is_remote_fs_type (fs_type); + g_clear_object (&info); + g_object_unref (file); + g_once_init_leave (&initialized, TRUE); } return remote_home; From a8f97cbe8e013767712bc724f4bf7f0f6106f5e3 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 15 Jun 2020 17:44:26 +0200 Subject: [PATCH 5/6] glocalfile: Rename g_local_file_is_remote The g_local_file_is_remote function is misleading as it works only for NFS filesystem types and only for locations in home directorly. Let's rename it to g_local_file_is_nfs_home to make it obvious. --- gio/glocalfile.c | 4 ++-- gio/glocalfile.h | 2 +- gio/glocalfilemonitor.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 121d5e9ed..0ad39853f 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -2516,7 +2516,7 @@ g_local_file_move (GFile *source, #ifdef G_OS_WIN32 gboolean -g_local_file_is_remote (const gchar *filename) +g_local_file_is_nfs_home (const gchar *filename) { return FALSE; } @@ -2538,7 +2538,7 @@ is_remote_fs_type (const gchar *fsname) } gboolean -g_local_file_is_remote (const gchar *filename) +g_local_file_is_nfs_home (const gchar *filename) { static gboolean remote_home; static gsize initialized; diff --git a/gio/glocalfile.h b/gio/glocalfile.h index f3ec4f294..ac0ad9d73 100644 --- a/gio/glocalfile.h +++ b/gio/glocalfile.h @@ -46,7 +46,7 @@ GFile * _g_local_file_new (const char *filename); const char * _g_local_file_get_filename (GLocalFile *file); -gboolean g_local_file_is_remote (const gchar *filename); +gboolean g_local_file_is_nfs_home (const gchar *filename); GFile * g_local_file_new_from_dirname_and_basename (const char *dirname, const char *basename); diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c index 3212beff7..4f1660d16 100644 --- a/gio/glocalfilemonitor.c +++ b/gio/glocalfilemonitor.c @@ -878,7 +878,7 @@ g_local_file_monitor_new_for_path (const gchar *pathname, GLocalFileMonitor *monitor; gboolean is_remote_fs; - is_remote_fs = g_local_file_is_remote (pathname); + is_remote_fs = g_local_file_is_nfs_home (pathname); monitor = g_local_file_monitor_new (is_remote_fs, is_directory, error); @@ -900,7 +900,7 @@ g_local_file_monitor_new_in_worker (const gchar *pathname, GLocalFileMonitor *monitor; gboolean is_remote_fs; - is_remote_fs = g_local_file_is_remote (pathname); + is_remote_fs = g_local_file_is_nfs_home (pathname); monitor = g_local_file_monitor_new (is_remote_fs, is_directory, error); From 92c9960521a23fcd239ac55fb3bd0cb07f22d18e Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 15 Jun 2020 17:43:49 +0200 Subject: [PATCH 6/6] glocalfile: Add SMB on the list of remote filesystems The G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE is set to TRUE only for NFS filesystem types currently. Let's add also SMB filesystem types. This also changes g_local_file_is_nfs_home function logic to handle only NFS filesystems. --- gio/glocalfile.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 0ad39853f..4bb9948d8 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -2532,6 +2532,12 @@ is_remote_fs_type (const gchar *fsname) return TRUE; if (strcmp (fsname, "nfs4") == 0) return TRUE; + if (strcmp (fsname, "cifs") == 0) + return TRUE; + if (strcmp (fsname, "smb") == 0) + return TRUE; + if (strcmp (fsname, "smb2") == 0) + return TRUE; } return FALSE; @@ -2540,7 +2546,7 @@ is_remote_fs_type (const gchar *fsname) gboolean g_local_file_is_nfs_home (const gchar *filename) { - static gboolean remote_home; + static gboolean remote_home = FALSE; static gsize initialized; const gchar *home; @@ -2557,7 +2563,8 @@ g_local_file_is_nfs_home (const gchar *filename) info = g_local_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, NULL, NULL); if (info != NULL) fs_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE); - remote_home = is_remote_fs_type (fs_type); + if (g_strcmp0 (fs_type, "nfs") == 0 || g_strcmp0 (fs_type, "nfs4") == 0) + remote_home = TRUE; g_clear_object (&info); g_object_unref (file);