Allow a redirected drive device_id to be zero (Guacamole support)

This commit is contained in:
matt335672 2020-03-03 16:16:09 +00:00
parent a3d429b4f7
commit a2266f23f6
3 changed files with 40 additions and 38 deletions

View File

@ -638,6 +638,7 @@ int xfuse_create_share(tui32 device_id, const char *dirname)
} }
else else
{ {
xinode->is_redirected = 1;
xinode->device_id = device_id; xinode->device_id = device_id;
result = 0; result = 0;
} }
@ -654,7 +655,7 @@ int xfuse_create_share(tui32 device_id, const char *dirname)
void xfuse_delete_share(tui32 device_id) void xfuse_delete_share(tui32 device_id)
{ {
xfs_delete_entries_with_device_id(g_xfs, device_id); xfs_delete_redirected_entries_with_device_id(g_xfs, device_id);
} }
/** /**
@ -1448,7 +1449,7 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
} }
else else
{ {
if (parent_xinode->device_id == 0) if (!parent_xinode->is_redirected)
{ {
/* File cannot be remote - we either know about it or we don't */ /* File cannot be remote - we either know about it or we don't */
if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) != NULL) if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) != NULL)
@ -1683,7 +1684,7 @@ static void xfuse_cb_unlink(fuse_req_t req, fuse_ino_t parent,
fuse_reply_err(req, ENOTEMPTY); fuse_reply_err(req, ENOTEMPTY);
} }
else if (xinode->device_id == 0) else if (!xinode->is_redirected)
{ {
/* specified file is a local resource */ /* specified file is a local resource */
//XFUSE_HANDLE *fh; //XFUSE_HANDLE *fh;
@ -1764,12 +1765,13 @@ static void xfuse_cb_rename(fuse_req_t req,
fuse_reply_err(req, EINVAL); fuse_reply_err(req, EINVAL);
} }
else if (new_parent_xinode->device_id != old_xinode->device_id) else if (new_parent_xinode->is_redirected != old_xinode->is_redirected ||
new_parent_xinode->device_id != old_xinode->device_id)
{ {
fuse_reply_err(req, EXDEV); fuse_reply_err(req, EXDEV);
} }
else if (old_xinode->device_id == 0) else if (!old_xinode->is_redirected)
{ {
/* specified file is a local resource */ /* specified file is a local resource */
log_debug("LK_TODO: this is still a TODO"); log_debug("LK_TODO: this is still a TODO");
@ -1875,7 +1877,7 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
{ {
fuse_reply_err(req, ENOTDIR); fuse_reply_err(req, ENOTDIR);
} }
else if (xinode->device_id == 0) else if (!xinode->is_redirected)
{ {
/* specified file is a local resource */ /* specified file is a local resource */
//XFUSE_HANDLE *fh; //XFUSE_HANDLE *fh;
@ -1960,7 +1962,7 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
log_debug("Invalid access mode specified"); log_debug("Invalid access mode specified");
fuse_reply_err(req, EINVAL); fuse_reply_err(req, EINVAL);
} }
else if (xinode->device_id == 0) else if (!xinode->is_redirected)
{ {
/* specified file is a local resource */ /* specified file is a local resource */
if ((fi->flags & O_ACCMODE) != O_RDONLY) if ((fi->flags & O_ACCMODE) != O_RDONLY)
@ -2039,7 +2041,7 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
log_error("inode %ld is not valid", ino); log_error("inode %ld is not valid", ino);
fuse_reply_err(req, ENOENT); fuse_reply_err(req, ENOENT);
} }
else if (xinode->device_id == 0) else if (!xinode->is_redirected)
{ {
/* specified file is a local resource */ /* specified file is a local resource */
fuse_reply_err(req, 0); fuse_reply_err(req, 0);
@ -2305,7 +2307,7 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
/* No changes have been made */ /* No changes have been made */
make_fuse_attr_reply(req, xinode); make_fuse_attr_reply(req, xinode);
} }
else if (xinode->device_id == 0) else if (!xinode->is_redirected)
{ {
/* Update the local fs */ /* Update the local fs */
update_inode_file_attributes(&attrs, change_mask, xinode); update_inode_file_attributes(&attrs, change_mask, xinode);
@ -2371,7 +2373,7 @@ static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
log_error("inode %ld is not valid", ino); log_error("inode %ld is not valid", ino);
fuse_reply_err(req, ENOENT); fuse_reply_err(req, ENOENT);
} }
else if (xinode->device_id == 0) else if (!xinode->is_redirected)
{ {
if ((fi->fh = (tintptr) xfs_opendir(g_xfs, ino)) == 0) if ((fi->fh = (tintptr) xfs_opendir(g_xfs, ino)) == 0)
{ {

View File

@ -344,6 +344,7 @@ xfs_create_xfs_fs(mode_t umask, uid_t uid, gid_t gid)
xino1->pub.ctime = xino1->pub.atime; xino1->pub.ctime = xino1->pub.atime;
strcpy(xino1->pub.name, "."); strcpy(xino1->pub.name, ".");
xino1->pub.generation = xfs->generation; xino1->pub.generation = xfs->generation;
xino1->pub.is_redirected = 0;
xino1->pub.device_id = 0; xino1->pub.device_id = 0;
/* /*
@ -365,6 +366,7 @@ xfs_create_xfs_fs(mode_t umask, uid_t uid, gid_t gid)
xino2->pub.ctime = xino2->pub.atime; xino2->pub.ctime = xino2->pub.atime;
strcpy(xino2->pub.name, ".delete-pending"); strcpy(xino2->pub.name, ".delete-pending");
xino2->pub.generation = xfs->generation; xino2->pub.generation = xfs->generation;
xino2->pub.is_redirected = 0;
xino2->pub.device_id = 0; xino2->pub.device_id = 0;
xino2->parent = NULL; xino2->parent = NULL;
@ -469,6 +471,7 @@ xfs_add_entry(struct xfs_fs *xfs, fuse_ino_t parent_inum,
xino->pub.ctime = xino->pub.atime; xino->pub.ctime = xino->pub.atime;
strcpy(xino->pub.name, name); strcpy(xino->pub.name, name);
xino->pub.generation = xfs->generation; xino->pub.generation = xfs->generation;
xino->pub.is_redirected = parent->pub.is_redirected;
xino->pub.device_id = parent->pub.device_id; xino->pub.device_id = parent->pub.device_id;
xino->pub.lindex = 0; xino->pub.lindex = 0;
@ -816,35 +819,35 @@ xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum)
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
void void
xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id) xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
tui32 device_id)
{ {
fuse_ino_t inum; fuse_ino_t inum;
XFS_INODE_ALL *xino; XFS_INODE_ALL *xino;
if (device_id != 0) /* Using xfs_remove_entry() is convenient, but it recurses
* in to directories. To make sure all entries are removed, set the
* open_count of all affected files to 0 first
*/
for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
{ {
/* Using xfs_remove_entry() is convenient, but it recurses if ((xino = xfs->inode_table[inum]) != NULL &&
* in to directories. To make sure all entries are removed, set the xino->pub.is_redirected != 0 &&
* open_count of all affected files to 0 first xino->pub.device_id == device_id &&
*/ (xino->pub.mode & S_IFREG) != 0)
for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
{ {
if ((xino = xfs->inode_table[inum]) != NULL && xino->open_count = 0;
xino->pub.device_id == device_id &&
(xino->pub.mode & S_IFREG) != 0)
{
xino->open_count = 0;
}
} }
}
/* Now we can be sure everything will be deleted correctly */ /* Now we can be sure everything will be deleted correctly */
for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum) for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
{
if ((xino = xfs->inode_table[inum]) != NULL &&
xino->pub.is_redirected != 0 &&
xino->pub.device_id == device_id)
{ {
if ((xino = xfs->inode_table[inum]) != NULL && xfs_remove_entry(xfs, xino->pub.inum);
xino->pub.device_id == device_id)
{
xfs_remove_entry(xfs, xino->pub.inum);
}
} }
} }
} }

View File

@ -49,9 +49,8 @@ typedef struct xfs_inode
time_t ctime; /* Time of last status change. */ time_t ctime; /* Time of last status change. */
char name[XFS_MAXFILENAMELEN + 1]; /* Short name */ char name[XFS_MAXFILENAMELEN + 1]; /* Short name */
tui32 generation; /* Changes if inode is reused */ tui32 generation; /* Changes if inode is reused */
tui32 device_id; /* for file system redirection char is_redirected; /* file is on redirected device */
* Non-redirected devices are guaranteed tui32 device_id; /* device ID of redirected device */
* to have a device_id or zero */
int lindex; /* used in clipboard operations */ int lindex; /* used in clipboard operations */
} XFS_INODE; } XFS_INODE;
@ -271,17 +270,15 @@ unsigned int
xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum); xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
/* /*
* Deletes all entries with the matching device id * Deletes all redirected entries with the matching device id
* *
* Files are deleted even if they are open * Files are deleted even if they are open
* *
* The specified device_id must be non-zero so that the root
* filesystem is not deleted!
*
* @param device_id Device ID * @param device_id Device ID
*/ */
void void
xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id); xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
tui32 device_id);
/* /*
* Check an entry move will be successful * Check an entry move will be successful