File indexing completed on 2024-05-12 03:54:55
0001 /* 0002 This software is a contribution of the LiMux project of the city of Munich. 0003 SPDX-FileCopyrightText: 2021 Robert Hoffmann <robert@roberthoffmann.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 #ifndef KNETWORKMOUNTS_H 0008 #define KNETWORKMOUNTS_H 0009 0010 #include <memory> 0011 0012 #include <QObject> 0013 #include <kcoreaddons_export.h> 0014 0015 /** 0016 * \class KNetworkMounts knetworkmounts.h <KNetworkMounts> 0017 * 0018 * Performance control on network mounts. 0019 * 0020 * This class provides methods for deciding whether operations 0021 * on slow network mounts should be performed or not. 0022 * 0023 * Configuration is read from a configuration file network_mounts in 0024 * the user's QStandardPaths::ConfigLocation. This file can be filled by using 0025 * the network mounts performance configuration module or directly via @ref setEnabled, 0026 * @ref setPaths, @ref addPath and @ref setOption 0027 * @code 0028 * KNetworkMounts::self()->setEnabled(true); 0029 * KNetworkMounts::self()->setOption(KNetworkMounts::LowSideEffectsOptimizations, true); 0030 * KNetworkMounts::self()->addPath(path1, KNetworkMounts::NfsPaths); 0031 * KNetworkMounts::self()->addPath(path2, KNetworkMounts::NfsPaths); 0032 * KNetworkMounts::self()->setPaths(listOfPaths, KNetworkMounts::SmbPaths); 0033 * @endcode 0034 * 0035 * Use KNetworkMounts like this to check if the given url is on a 0036 * configured slow path and the KNetworkMountOption LowSideEffectsOptimizations 0037 * is enabled: 0038 * @code 0039 * if (KNetworkMounts::self()->isOptionEnabledForPath(url.toLocalFile(), 0040 * KNetworkMounts::LowSideEffectsOptimizations)) 0041 * { 0042 * // skip operations which are slow on the given url if 0043 * // KNetworkMountOption LowSideEffectsOptimizations is enabled 0044 * } else { 0045 * // given url is not configured being slow or the KNetworkMountOption 0046 * // LowSideEffectsOptimizations is not enabled 0047 * } 0048 * @endcode 0049 * 0050 * If called for the first time, this creates a singleton instance and reads 0051 * the config file. Subsequent calls just use this instance without reading 0052 * the config file again. 0053 * 0054 * @author Robert Hoffmann <robert@roberthoffmann.de> 0055 * 0056 * @since 5.85 0057 **/ 0058 class KCOREADDONS_EXPORT KNetworkMounts : public QObject 0059 { 0060 Q_OBJECT 0061 0062 public: 0063 /** 0064 * Returns (and creates if necessary) the singleton instance 0065 * 0066 * @return the singleton instance 0067 */ 0068 static KNetworkMounts *self(); 0069 0070 /** 0071 * The KNetworkMountOption enum 0072 * 0073 * Uses are: 0074 */ 0075 enum KNetworkMountOption { 0076 LowSideEffectsOptimizations, ///< Don't run KDiskFreeSpaceInfo if slow path.<br> 0077 ///< Don't check for manually mounted drives.<br> 0078 ///< Don't check with QFileInfo::isWritable if it is writable, if not yet known, return true.<br> 0079 ///< Don't check with QFileInfo::isReadable if it is readable, return false.<br> 0080 ///< Don't check for desktop files just return false.<br> 0081 ///< Ignore .hidden files on slow paths.<br> 0082 ///< Don't read mime comment from .desktop or .directory files.<br> 0083 ///< Don't get the size with QFileInfo::size, just return 0, if not yet known.<br> 0084 ///< Don't determine mime type from file content, use file extension.<br> 0085 ///< Don't check for desktop files just return false.<br> 0086 ///< Don't call KFileSystemType::fileSystemType to check if the filesystem is slow, just return true.<br> 0087 ///< Don't count files/directories in subdirectories.<br> 0088 ///< Don't calculate sizes of subdirectories.<br> 0089 ///< Avoid check for dir at Kate startup 0090 MediumSideEffectsOptimizations, ///< Don't return project for dir, avoid QFileInfo().absoluteDir()<br> 0091 ///< Don't search for .kateconfig recursively<br> 0092 ///< Ignore recent files on slow paths 0093 StrongSideEffectsOptimizations, ///< Turn off symbolic link resolution 0094 KDirWatchDontAddWatches, ///< Disables dir watching completely for slow paths, avoids stat() calls on added dirs and subdirs 0095 SymlinkPathsUseCache ///< Cache resolved symlink paths 0096 }; 0097 Q_ENUM(KNetworkMountOption) 0098 0099 /** 0100 * The KNetworkMountsType enum 0101 */ 0102 enum KNetworkMountsType { 0103 NfsPaths, ///< NFS paths 0104 SmbPaths, ///< SMB paths 0105 SymlinkDirectory, ///< Paths to directories which contain symbolic links to network mounts 0106 SymlinkToNetworkMount, ///< Paths which are symbolic links to network mounts 0107 Any ///< Any slow path type. Do not use with @ref setPaths or @ref addPath 0108 }; 0109 Q_ENUM(KNetworkMountsType) 0110 0111 /** 0112 * Query if @p path is configured to be a slow path of type @p type 0113 * 0114 * @param path the path to query 0115 * @param type the type to query. If omitted, any type matches 0116 * @return @c true if @p path is a configured slow path of type @p type 0117 * 0118 * This function is also used to determine the filesystem type in @ref KFileSystemType::fileSystemType 0119 * (KFileSystemType::Smb or KFileSystemType::Nfs) without an expensive call to stafs(). For this 0120 * to work the types of paths need to be correctly assigned in @ref setPath or @ref addPath 0121 */ 0122 bool isSlowPath(const QString &path, KNetworkMountsType type = Any); 0123 0124 /** 0125 * Query if @p path is configured to be a slow path and @p option is enabled 0126 * 0127 * @param path the path to query 0128 * @param option the option to query 0129 * @return @c true if @p path is a configured slow path and option @p option is enabled 0130 */ 0131 bool isOptionEnabledForPath(const QString &path, KNetworkMountOption option); 0132 0133 /** 0134 * Query if the performance optimizations are switched on 0135 * 0136 * @return @c true if on, @c false otherwise 0137 */ 0138 bool isEnabled() const; 0139 0140 /** 0141 * Switch the performance optimizations on or off 0142 * 0143 * @param value the value to set 0144 */ 0145 void setEnabled(bool value); 0146 0147 /** 0148 * Query a performance option 0149 * 0150 * @param option the option to query 0151 * @param defaultValue the value to return if the option is not configured 0152 * @return @c true if option is on, @c false if not 0153 * @see KNetworkMountOption 0154 */ 0155 bool isOptionEnabled(const KNetworkMountOption option, const bool defaultValue = false) const; 0156 0157 /** 0158 * Switch a performance option on or off 0159 * 0160 * @param option the option to change 0161 * @param value the value to set 0162 * @see KNetworkMountOption 0163 */ 0164 void setOption(const KNetworkMountOption option, const bool value); 0165 0166 /** 0167 * Query the configured paths for which optimizations are to take place 0168 * 0169 * @return a list of paths 0170 */ 0171 QStringList paths(KNetworkMountsType type = Any) const; 0172 0173 /** 0174 * Set the paths for which optimizations are to take place 0175 * 0176 * @param paths the paths to set 0177 * @param type the type of paths. Do not use @ref Any 0178 * @see KNetworkMountsType 0179 */ 0180 void setPaths(const QStringList &paths, KNetworkMountsType type); 0181 0182 /** 0183 * Add a path for which optimizations are to take place 0184 * 0185 * @param path the path to add 0186 * @param type the type of the path. Do not use @ref Any 0187 * @see KNetworkMountsType 0188 */ 0189 void addPath(const QString &path, KNetworkMountsType type); 0190 0191 /** 0192 * Resolves a @p path that may contain symbolic links to mounted network shares. 0193 * 0194 * A symlink path is either a directory which contains symbolic links to slow network mounts 0195 * (@ref SymlinkDirectory) or a direct symbolic link to a slow network mount (@ref 0196 * SymlinkToNfsOrSmbPaths). 0197 * 0198 * Example: 0199 * There are some Samba shares mounted below /mnt. These are @ref paths of type @ref SmbPaths 0200 * @code 0201 * /mnt/server1/share1 0202 * /mnt/server1/share2 0203 * /mnt/server2/share3 0204 * @endcode 0205 * 0206 * A (logged in) user may have symbolic links to them in his home directory below netshares. The 0207 * directory /home/user/netshares is a @ref SymlinkDirectory: 0208 * @code 0209 * /home/user/netshares/share1 -> /mnt/server1/share1 0210 * /home/user/netshares/share2 -> /mnt/server1/share2 0211 * /home/user/netshares/share3 -> /mnt/server2/share3 0212 * @endcode 0213 * 0214 * There is a direct symbolic link from /home/user/share1 to /mnt/server1/share1. This is of type 0215 * @ref SymlinkToNfsOrSmbPaths: 0216 * @code 0217 * /home/user/share1 -> /mnt/server1/share1 0218 * @endcode 0219 * 0220 * Both types of symbolic links from symlink paths to the real mounted shares are resolved even if 0221 * KNetworkMountOption @ref StrongSideEffectsOptimizations is enabled. 0222 0223 * If the setup is like above a @p path 0224 * @code 0225 * /home/user/netshares/share1/Documents/file.txt 0226 * @endcode 0227 * 0228 * would be resolved to 0229 * @code 0230 * /mnt/server1/share1/Documents/file.txt 0231 * @endcode 0232 * 0233 * and a @p path 0234 * @code 0235 * /home/user/share1/Documents/file.txt 0236 * @endcode 0237 * 0238 * would also be resolved to 0239 * @code 0240 * /mnt/server1/share1/Documents/file.txt 0241 * @endcode 0242 * 0243 * Resolved paths are cached in a hash. 0244 * 0245 * @param path the path to resolve 0246 * @return the resolved path or @p path if @p path is not a symlink path or no symlink found 0247 * @see KNetworkMountsType 0248 * @see clearCache 0249 * @see isSlowPath 0250 */ 0251 QString canonicalSymlinkPath(const QString &path); 0252 0253 /** 0254 * Clears the canonical symlink path cache 0255 * 0256 * Call this if directory structures on mounted network drives changed. Don't enable the 0257 * cache (@ref SymlinkPathsUseCache) if this happens often and the drives are usually accessed 0258 * via the symlinks. This method exists mainly for the KCM. 0259 * @see canonicalSymlinkPath 0260 */ 0261 void clearCache(); 0262 0263 /** 0264 * Synchronizes to config file 0265 * 0266 * QSettings synchronization also takes place automatically at regular intervals and from 0267 * QSettings destructor, see QSettings::sync() documentation. 0268 * 0269 * Calls QSettings::sync() 0270 */ 0271 void sync(); 0272 0273 private: 0274 /// Creates a new KNetworkMounts object 0275 KCOREADDONS_NO_EXPORT KNetworkMounts(); 0276 0277 /// Destructor 0278 KCOREADDONS_NO_EXPORT ~KNetworkMounts() override; 0279 0280 std::unique_ptr<class KNetworkMountsPrivate> const d; 0281 }; 0282 0283 #endif // KNETWORKMOUNTS_H