diff --git a/configure.ac b/configure.ac index f4b3e6c8..618e18af 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,7 @@ AM_CONDITIONAL(MACOS, [test "x$macos" = xyes]) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([void *]) +AC_CHECK_SIZEOF([fsblkcnt_t],,[#include ]) # runstatedir not available for autoconf <= 2.69 if test "x$runstatedir" = "x" ; then diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index a92e7b2f..fa3b44b3 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -467,6 +467,22 @@ GNOME 3 versions later than 3.29.92. Do not use this for any other reason. This setting will be removed in a later version of xrdp, when GNOME 3 is no longer supported. +.TP +\fBFuseRootReportMaxFree\fR=\fI[false|true]\fR +The existing FUSE implementation reports free space on remote drives +in a way which can confuse some file managers if they check for free +space at the FUSE mountpoint before copying files. KDE Dolphin is +affected by this, and will report 'no space available' when trying to +copy to remote drives. + +Setting this option will cause the FUSE fileystem to report a +very large amount of free space for the root of the FUSE mountpoint. +This will allow Dolphin to copy files to remote drives, but introduces +a risk that the remote filesystem will run out of space during the copy. + +This setting will be removed in a later version of xrdp, when remote drives +receive unique mountpoints. + .TP \fBSoundNumSilentFramesAAC\fR=\fInumber\fR Sets the \fInumber\fR of silent frames which are sent to client before close diff --git a/sesman/chansrv/chansrv_config.c b/sesman/chansrv/chansrv_config.c index 14bd43b2..5953f24f 100644 --- a/sesman/chansrv/chansrv_config.c +++ b/sesman/chansrv/chansrv_config.c @@ -44,6 +44,7 @@ #define DEFAULT_FUSE_DIRECT_IO 0 #define DEFAULT_FILE_UMASK 077 #define DEFAULT_USE_NAUTILUS3_FLIST_FORMAT 0 +#define DEFAULT_FUSE_ROOT_REPORT_MAX_FREE 0 #define DEFAULT_NUM_SILENT_FRAMES_AAC 4 #define DEFAULT_NUM_SILENT_FRAMES_MP3 2 #define DEFAULT_MSEC_DO_NOT_SEND 1000 @@ -252,6 +253,10 @@ read_config_chansrv(log_func_t logmsg, { cfg->use_nautilus3_flist_format = g_text2bool(value); } + else if (g_strcasecmp(name, "FuseRootReportMaxFree") == 0) + { + cfg->fuse_root_report_max_free = g_text2bool(value); + } else if (g_strcasecmp(name, "SoundNumSilentFramesAAC") == 0) { cfg->num_silent_frames_aac = strtoul(value, NULL, 0); @@ -339,6 +344,7 @@ new_config(void) cfg->fuse_direct_io = DEFAULT_FUSE_DIRECT_IO; cfg->file_umask = DEFAULT_FILE_UMASK; cfg->use_nautilus3_flist_format = DEFAULT_USE_NAUTILUS3_FLIST_FORMAT; + cfg->fuse_root_report_max_free = DEFAULT_FUSE_ROOT_REPORT_MAX_FREE; cfg->num_silent_frames_aac = DEFAULT_NUM_SILENT_FRAMES_AAC; cfg->num_silent_frames_mp3 = DEFAULT_NUM_SILENT_FRAMES_MP3; cfg->msec_do_not_send = DEFAULT_MSEC_DO_NOT_SEND; @@ -446,6 +452,8 @@ config_dump(struct config_chansrv *config) g_writeln(" FileMask: 0%o", config->file_umask); g_writeln(" Nautilus 3 Flist Format: %s", g_bool2text(config->use_nautilus3_flist_format)); + g_writeln(" FuseRootReportMaxFree: %s", + g_bool2text(config->fuse_root_report_max_free)); g_writeln(" LogFilePath : %s", (config->log_file_path[0]) ? config->log_file_path : ""); } diff --git a/sesman/chansrv/chansrv_config.h b/sesman/chansrv/chansrv_config.h index 031bd487..e9ecbb73 100644 --- a/sesman/chansrv/chansrv_config.h +++ b/sesman/chansrv/chansrv_config.h @@ -47,6 +47,9 @@ struct config_chansrv /** Whether to use nautilus3-compatible file lists for the clipboard */ int use_nautilus3_flist_format; + /** Whether to report max free space for the FUSE mountpoint */ + int fuse_root_report_max_free; + /** Number of silent frames to send before SNDC_CLOSE is sent, setting from sesman.ini */ unsigned int num_silent_frames_aac; unsigned int num_silent_frames_mp3; diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 579a1c84..bcab4dba 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -2791,6 +2791,22 @@ static void xfuse_cb_statfs(fuse_req_t req, fuse_ino_t ino) { /* specified file is a local resource */ struct statvfs vfs_stats = {0}; + if (g_cfg->fuse_root_report_max_free) + { + // Report an 95% free max-size filesystem + vfs_stats.f_bsize = 0x1000; + vfs_stats.f_frsize = vfs_stats.f_bsize; +#if SIZEOF_FSBLKCNT_T < 8 + vfs_stats.f_blocks = (fsblkcnt_t) -1; +#else + // Max-size is taken from XFS (8 * 2^60 bytes). Using -1 + // as a value does not work here. + vfs_stats.f_blocks = (fsblkcnt_t)8 * 0x10000 * 0x10000 * 0x10000; +#endif + vfs_stats.f_bfree = vfs_stats.f_blocks - vfs_stats.f_blocks / 20; + vfs_stats.f_bavail = vfs_stats.f_bfree; + vfs_stats.f_namemax = XFS_MAXFILENAMELEN; + } fuse_reply_statfs(req, &vfs_stats); } else diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index ae9c6b0a..6f6c167b 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -200,6 +200,9 @@ FileUmask=077 ; and up, and you wish to cut-paste files between Nautilus and Windows. Do ; not use this setting for GNOME 4, or other file managers #UseNautilus3FlistFormat=true +; Uncomment this line if your file manager erroneously reports +; 'No free space' when trying to copy any files to remote drives. +#FuseRootReportMaxFree=true ; sound redirection ; workaround for Microsoft mstsc.exe to suppress noise. ; SoundNumSilentFramesAAC | SoundNumSilentFramesMP3 silent frames are sent before SNDC_CLOSE is sent.