Skip to content

Commit

Permalink
Merge pull request #3304 from matt335672/add_statfs_to_fuse
Browse files Browse the repository at this point in the history
Add support for statvfs() to FUSE
  • Loading branch information
matt335672 authored Dec 13, 2024
2 parents 83cf04b + 6a49ff9 commit 31a09f5
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 15 deletions.
1 change: 1 addition & 0 deletions common/ms-erref.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum NTSTATUS
STATUS_NO_MORE_FILES = 0x80000006,

STATUS_UNSUCCESSFUL = 0xc0000001,
STATUS_INFO_LENGTH_MISMATCH = 0xc0000004,
STATUS_NO_SUCH_FILE = 0xc000000f,
STATUS_ACCESS_DENIED = 0xc0000022,
STATUS_OBJECT_NAME_INVALID = 0xc0000033,
Expand Down
22 changes: 21 additions & 1 deletion common/ms-fscc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
/*
* File information classes (section 2.4)
*/
enum FS_INFORMATION_CLASS
enum FILE_INFORMATION_CLASS
{
FileAllocationInformation = 19, /* Set */
FileBasicInformation = 4, /* Query, Set */
Expand All @@ -52,6 +52,26 @@ enum FS_INFORMATION_CLASS
#define FILE_STD_INFORMATION_SIZE 22
#define FILE_END_OF_FILE_INFORMATION_SIZE 8

/*
* File System information classes (section 2.5)
*/
enum FILE_SYSTEM_INFORMATION_CLASS
{
FileFsVolumeInformation = 1,
FileFsSizeInformation = 3,
FileFsDeviceInformation = 4,
FileFsAttributeInformation = 5,
FileFsFullSizeInformation = 7
};

/*
* Size of structs above without trailing RESERVED fields (MS-RDPEFS
* 2.2.3.3.6)
*/
#define FILE_FS_SIZE_INFORMATION_SIZE 24
#define FILE_FS_DEVICE_INFORMATION_SIZE 8
#define FILE_FS_FULL_SIZE_INFORMATION_SIZE 32

/* Windows file attributes (section 2.6) */
#define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define W_FILE_ATTRIBUTE_READONLY 0x00000001
Expand Down
90 changes: 90 additions & 0 deletions sesman/chansrv/chansrv_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ void xfuse_devredir_cb_rename_file(struct state_rename *fip,
void xfuse_devredir_cb_file_close(struct state_close *fip)
{}

void xfuse_devredir_cb_statfs(struct state_statfs *fip,
const struct statvfs *fss,
enum NTSTATUS IoStatus)
{}

int xfuse_path_in_xfuse_fs(const char *path)
{
return 0;
Expand Down Expand Up @@ -303,6 +308,15 @@ struct state_close
fuse_ino_t inum; /* inum of file to open */
};

/*
* Record type used to maintain state when running a statfs
*/
struct state_statfs
{
fuse_req_t req; /* Original FUSE request from statfs */
};


struct xfuse_handle
{
tui32 DeviceId;
Expand Down Expand Up @@ -409,6 +423,8 @@ static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);

static void xfuse_cb_statfs(fuse_req_t req, fuse_ino_t ino);

/* miscellaneous functions */
static void xfs_inode_to_fuse_entry_param(const XFS_INODE *xinode,
struct fuse_entry_param *e);
Expand Down Expand Up @@ -611,6 +627,7 @@ xfuse_init(void)
g_xfuse_ops.setattr = xfuse_cb_setattr;
g_xfuse_ops.opendir = xfuse_cb_opendir;
g_xfuse_ops.releasedir = xfuse_cb_releasedir;
g_xfuse_ops.statfs = xfuse_cb_statfs;

fuse_opt_add_arg(&args, "xrdp-chansrv");
fuse_opt_add_arg(&args, "-o");
Expand Down Expand Up @@ -1570,6 +1587,26 @@ void xfuse_devredir_cb_file_close(struct state_close *fip)
free(fip);
}

void xfuse_devredir_cb_statfs(struct state_statfs *fip,
const struct statvfs *fss,
enum NTSTATUS IoStatus)
{
int status;
if (IoStatus != STATUS_SUCCESS)
{
status =
(IoStatus == STATUS_ACCESS_DENIED) ? EACCES :
/* default */ EIO ;
fuse_reply_err(fip->req, status);
}
else
{
fuse_reply_statfs(fip->req, fss);
}

free(fip);
}

/*
* Determine is a file is in the FUSE filesystem
*
Expand Down Expand Up @@ -2686,6 +2723,59 @@ static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino,
fuse_reply_err(req, 0);
}

/*****************************************************************************/
static void xfuse_cb_statfs(fuse_req_t req, fuse_ino_t ino)
{
XFS_INODE *xinode;

LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: ino=%ld", ino);

if (!(xinode = xfs_get(g_xfs, ino)))
{
LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
fuse_reply_err(req, ENOENT);
}
else if (!xinode->is_redirected)
{
/* specified file is a local resource */
struct statvfs vfs_stats = {0};
fuse_reply_statfs(req, &vfs_stats);
}
else
{
/* specified file resides on redirected share */

struct state_statfs *fip = g_new0(struct state_statfs, 1);
char *full_path = xfs_get_full_path(g_xfs, ino);
if (full_path == NULL || fip == NULL)
{
LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
fuse_reply_err(req, ENOMEM);
free(full_path);
free(fip);
}
else
{
const char *cptr;
fip->req = req;

/* get devredir to statfs the filesystem for the file
*
* If this call succeeds, further request processing happens in
* xfuse_devredir_cb_statfs()
*/
cptr = filename_on_device(full_path);
if (devredir_statfs(fip, xinode->device_id, cptr))
{
LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_statfs() cmd");
fuse_reply_err(req, EREMOTEIO);
free(fip);
}
free(full_path);
}
}
}

/******************************************************************************
* miscellaneous functions
*****************************************************************************/
Expand Down
6 changes: 6 additions & 0 deletions sesman/chansrv/chansrv_fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ struct state_write;
struct state_remove;
struct state_rename;
struct state_close;
struct statvfs; // OS structure defined in <sys/statvfs.h>
struct state_statfs;


/* functions that are invoked from devredir */
Expand Down Expand Up @@ -114,6 +116,10 @@ void xfuse_devredir_cb_rename_file(struct state_rename *fip,

void xfuse_devredir_cb_file_close(struct state_close *fip);

void xfuse_devredir_cb_statfs(struct state_statfs *fip,
const struct statvfs *fss,
enum NTSTATUS IoStatus);

/*
* Returns true if a filesystem path lies in the FUSE filesystem
*
Expand Down
14 changes: 7 additions & 7 deletions sesman/chansrv/chansrv_xfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
#ifndef _CHANSRV_XFS
#define _CHANSRV_XFS

/* Skip this include if there's no FUSE */
/* Maximum length of filename supported (in bytes).
* This is a sensible limit to a filename length. It is not used by
* this module to allocate long-lived storage, so it can be increased
* if necessary */
#define XFS_MAXFILENAMELEN 1023

/* Skip the rest of this include if there's no FUSE */
#ifdef XRDP_FUSE

#include <stddef.h>
Expand All @@ -29,12 +35,6 @@

#include "arch.h"

/* Maximum length of filename supported (in bytes).
* This is a sensible limit to a filename length. It is not used by
* this module to allocate long-lived storage, so it can be increased
* if necessary */
#define XFS_MAXFILENAMELEN 1023

/*
* Incomplete types for the public interface
*/
Expand Down
Loading

0 comments on commit 31a09f5

Please sign in to comment.