file system redirection:

o touch <file> was not working - fixed
    o echo "this is a string" > filename was not working - fixed
    o echo "this is a string" >> filename was not working - fixed
    o vi was not working - working now but swap files are not
      being deleted automatically - work in progress
This commit is contained in:
Laxmikant Rashinkar 2013-05-18 19:44:16 -07:00
parent 262bb7e813
commit 315ef8ad71
4 changed files with 135 additions and 52 deletions

View File

@ -116,7 +116,7 @@ void xfuse_devredir_cb_file_close(void *vp) {}
#define LOG_ERROR 0
#define LOG_INFO 1
#define LOG_DEBUG 2
#define LOG_LEVEL LOG_DEBUG
#define LOG_LEVEL LOG_ERROR
#define log_error(_params...) \
{ \
@ -308,8 +308,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
fuse_file_info *fi);
static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
fuse_file_info *fi);
static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi);
@ -378,19 +378,19 @@ int xfuse_init()
/* setup FUSE callbacks */
g_memset(&g_xfuse_ops, 0, sizeof(g_xfuse_ops));
g_xfuse_ops.lookup = xfuse_cb_lookup;
g_xfuse_ops.readdir = xfuse_cb_readdir;
g_xfuse_ops.mkdir = xfuse_cb_mkdir;
g_xfuse_ops.rmdir = xfuse_cb_rmdir;
g_xfuse_ops.unlink = xfuse_cb_unlink;
g_xfuse_ops.rename = xfuse_cb_rename;
g_xfuse_ops.open = xfuse_cb_open;
g_xfuse_ops.flush = xfuse_cb_flush;
g_xfuse_ops.read = xfuse_cb_read;
g_xfuse_ops.write = xfuse_cb_write;
g_xfuse_ops.create = xfuse_cb_create;
g_xfuse_ops.getattr = xfuse_cb_getattr;
g_xfuse_ops.setattr = xfuse_cb_setattr;
g_xfuse_ops.lookup = xfuse_cb_lookup;
g_xfuse_ops.readdir = xfuse_cb_readdir;
g_xfuse_ops.mkdir = xfuse_cb_mkdir;
g_xfuse_ops.rmdir = xfuse_cb_rmdir;
g_xfuse_ops.unlink = xfuse_cb_unlink;
g_xfuse_ops.rename = xfuse_cb_rename;
g_xfuse_ops.open = xfuse_cb_open;
g_xfuse_ops.release = xfuse_cb_release;
g_xfuse_ops.read = xfuse_cb_read;
g_xfuse_ops.write = xfuse_cb_write;
g_xfuse_ops.create = xfuse_cb_create;
g_xfuse_ops.getattr = xfuse_cb_getattr;
g_xfuse_ops.setattr = xfuse_cb_setattr;
fuse_opt_add_arg(&args, "xrdp-chansrv");
fuse_opt_add_arg(&args, g_fuse_root_path);
@ -1723,6 +1723,9 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 DeviceId, tui32 FileId)
goto done;
}
log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p DeviceId=%d FileId=%d",
fip, fip->fi, DeviceId, FileId);
if (fip->fi != NULL)
{
if ((fh = calloc(1, sizeof(XFUSE_HANDLE))) == NULL)
@ -1739,6 +1742,8 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 DeviceId, tui32 FileId)
fh->FileId = FileId;
fip->fi->fh = (uint64_t) ((long) fh);
log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
fip, fip->fi, fip->fi->fh);
}
if (fip->invoke_fuse)
@ -1793,6 +1798,9 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 DeviceId, tui32 FileId)
e.attr.st_ctime = xinode->ctime;
e.generation = 1;
/* update open count */
xinode->nopen++;
if (fip->mode == S_IFDIR)
fuse_reply_entry(fip->req, &e);
else
@ -1830,6 +1838,9 @@ void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length)
if (fip == NULL)
return;
log_debug("+++ XFUSE_INFO=%p, XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
fip, fip->fi, fip->fi->fh);
fuse_reply_write(fip->req, length);
/* update file size */
@ -1944,6 +1955,9 @@ void xfuse_devredir_cb_file_close(void *vp)
if (fip == NULL)
return;
log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
fip, fip->fi, fip->fi->fh);
if ((xinode = g_xrdp_fs.inode_table[fip->inode]) == NULL)
fuse_reply_err(fip->req, EBADF);
@ -1952,11 +1966,17 @@ void xfuse_devredir_cb_file_close(void *vp)
if (xinode->nopen > 0)
xinode->nopen--;
/* LK_TODO */
#if 0
if ((xinode->nopen == 0) && fip->fi && fip->fi->fh)
{
printf("LK_TODO: ################################ fi=%p fi->fh=%p\n",
fip->fi, fip->fi->fh);
free((char *) (tintptr) (fip->fi->fh));
fip->fi->fh = NULL;
}
#endif
fuse_reply_err(fip->req, 0);
}
@ -2562,6 +2582,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
strncpy(fip->name, name, 1024);
fip->name[1023] = 0;
log_debug("+++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p", fip, fip->fi);
/* LK_TODO need to handle open permissions */
/* we want path minus 'root node of the share' */
@ -2642,6 +2664,9 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
fip->invoke_fuse = 1;
fip->device_id = device_id;
fip->fi = fi;
log_debug("LK_TODO: fip->fi = %p", fip->fi);
strncpy(fip->name, full_path, 1024);
fip->name[1023] = 0;
fip->reply_type = RT_FUSE_REPLY_OPEN;
@ -2670,13 +2695,14 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
}
}
static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
fuse_file_info *fi)
static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
fuse_file_info *fi)
{
XFUSE_INFO *fip = NULL;
XFUSE_HANDLE *handle = (XFUSE_HANDLE *) (tintptr) (fi->fh);
tui32 FileId;
log_debug("ino=%d", (int) ino);
log_debug("entered: ino=%d fi=%p fi->fh=%p", (int) ino, fi, fi->fh);
if (!xfuse_is_inode_valid(ino))
{
@ -2695,6 +2721,16 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
/* specified file resides on redirected share */
log_debug("nopen=%d", xinode->nopen);
/* if file is not opened, just return */
if (xinode->nopen == 0)
{
log_debug("cannot close because file not opened");
fuse_reply_err(req, 0);
return;
}
if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
{
log_error("system out of memory");
@ -2708,6 +2744,13 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
fip->device_id = handle->DeviceId;
fip->fi = fi;
log_debug(" +++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
fip, fip->fi, fip->fi->fh);
FileId = handle->FileId;
free(handle);
fip->fi->fh = NULL;
if (devredir_file_close((void *) fip, fip->device_id, handle->FileId))
{
log_error("failed to send devredir_close_file() cmd");
@ -2823,12 +2866,16 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
fuse_reply_err(req, ENOMEM);
return;
}
fusep->req = req;
fusep->inode = ino;
fusep->invoke_fuse = 1;
fusep->device_id = fh->DeviceId;
fusep->fi = fi;
log_debug("+++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
fusep, fusep->fi, fusep->fi->fh);
dev_redir_file_write(fusep, fh->DeviceId, fh->FileId, buf, size, off);
log_debug("exiting");
}
@ -2843,7 +2890,8 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi)
{
XRDP_INODE *xinode;
XRDP_INODE *xinode;
struct stat st;
log_debug("entered to_set=0x%x", to_set);
@ -2906,7 +2954,17 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
log_debug("FUSE_SET_ATTR_MTIME_NOW");
}
fuse_reply_attr(req, attr, 1.0); /* LK_TODO just faking for now */
memset(&st, 0, sizeof(st));
st.st_ino = xinode->inode;
st.st_mode = xinode->mode;
st.st_size = xinode->size;
st.st_uid = xinode->uid;
st.st_gid = xinode->gid;
st.st_atime = xinode->atime;
st.st_mtime = xinode->mtime;
st.st_ctime = xinode->ctime;
fuse_reply_attr(req, &st, 1.0); /* LK_TODO just faking for now */
}
#endif /* end else #ifndef XRDP_FUSE */

View File

@ -56,7 +56,7 @@
#define LOG_DEBUG 2
#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_DEBUG
#define LOG_LEVEL LOG_ERROR
#endif
#define log_error(_params...) \
@ -742,7 +742,7 @@ void dev_redir_proc_device_iocompletion(struct stream *s)
{
/* we were trying to create a request to enumerate a dir */
/* that does not exist; let FUSE know */
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data)
{
xfuse_devredir_cb_enum_dir_done(fuse_data->data_ptr,
@ -764,7 +764,7 @@ void dev_redir_proc_device_iocompletion(struct stream *s)
xstream_rd_u32_le(s, irp->FileId);
log_debug("got CID_CREATE_OPEN_REQ IoStatus=0x%x FileId=%d",
IoStatus, irp->FileId);
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
xfuse_devredir_cb_open_file(fuse_data->data_ptr,
DeviceId, irp->FileId);
if (irp->type == S_IFDIR)
@ -774,14 +774,14 @@ void dev_redir_proc_device_iocompletion(struct stream *s)
case CID_READ:
log_debug("got CID_READ");
xstream_rd_u32_le(s, Length);
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length);
break;
case CID_WRITE:
log_debug("got CID_WRITE");
xstream_rd_u32_le(s, Length);
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
break;
@ -794,7 +794,7 @@ void dev_redir_proc_device_iocompletion(struct stream *s)
case CID_FILE_CLOSE:
log_debug("got CID_FILE_CLOSE");
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
xfuse_devredir_cb_file_close(fuse_data->data_ptr);
devredir_irp_delete(irp);
break;
@ -840,7 +840,10 @@ void dev_redir_proc_device_iocompletion(struct stream *s)
done:
if (fuse_data)
{
log_debug("free FUSE_DATA=%p", fuse_data);
free(fuse_data);
}
log_debug("exiting");
}
@ -880,7 +883,7 @@ void dev_redir_proc_query_dir_response(IRP *irp,
(IoStatus == STATUS_NO_MORE_FILES))
{
status = (IoStatus == STATUS_NO_MORE_FILES) ? 0 : IoStatus;
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
xfuse_devredir_cb_enum_dir_done(fuse_data->data_ptr, status);
irp->completion_type = CID_CLOSE;
dev_redir_send_drive_close_request(RDPDR_CTYP_CORE,
@ -940,7 +943,7 @@ void dev_redir_proc_query_dir_response(IRP *irp,
if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL)
{
log_error("system out of memory");
fuse_data = dev_redir_fuse_data_peek(irp);
fuse_data = devredir_fuse_data_peek(irp);
xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, NULL);
return;
}
@ -953,7 +956,7 @@ void dev_redir_proc_query_dir_response(IRP *irp,
xinode->ctime = WINDOWS_TO_LINUX_TIME(CreationTime);
/* add this entry to xrdp file system */
fuse_data = dev_redir_fuse_data_peek(irp);
fuse_data = devredir_fuse_data_peek(irp);
xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, xinode);
}
@ -990,7 +993,7 @@ int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
irp->completion_type = CID_CREATE_DIR_REQ;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
dev_redir_fuse_data_enqueue(irp, fusep);
devredir_fuse_data_enqueue(irp, fusep);
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
CreateOptions = CO_FILE_DIRECTORY_FILE | CO_FILE_SYNCHRONOUS_IO_NONALERT;
@ -1041,7 +1044,7 @@ int dev_redir_file_open(void *fusep, tui32 device_id, char *path,
irp->CompletionId = g_completion_id++;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
dev_redir_fuse_data_enqueue(irp, fusep);
devredir_fuse_data_enqueue(irp, fusep);
if (mode & O_CREAT)
{
@ -1090,7 +1093,8 @@ int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId)
{
IRP *irp;
log_debug("entered");
log_debug("entered: fusep=%p device_id=%d FileId=%d",
fusep, device_id, FileId);
#if 0
if ((irp = devredir_irp_new()) == NULL)
@ -1106,7 +1110,7 @@ int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId)
#endif
irp->completion_type = CID_FILE_CLOSE;
irp->DeviceId = device_id;
dev_redir_fuse_data_enqueue(irp, fusep);
devredir_fuse_data_enqueue(irp, fusep);
return dev_redir_send_drive_close_request(RDPDR_CTYP_CORE,
PAKID_CORE_DEVICE_IOREQUEST,
@ -1136,7 +1140,7 @@ int devredir_rmdir_or_file(void *fusep, tui32 device_id, char *path, int mode)
irp->completion_type = CID_RMDIR_OR_FILE;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
dev_redir_fuse_data_enqueue(irp, fusep);
devredir_fuse_data_enqueue(irp, fusep);
//DesiredAccess = DA_DELETE | DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE;
DesiredAccess = 0x00100080; /* got this value from windows */
@ -1179,7 +1183,7 @@ int dev_redir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
}
irp->completion_type = CID_READ;
dev_redir_fuse_data_enqueue(irp, fusep);
devredir_fuse_data_enqueue(irp, fusep);
devredir_insert_DeviceIoRequest(s,
DeviceId,
FileId,
@ -1219,7 +1223,7 @@ int dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
}
irp->completion_type = CID_WRITE;
dev_redir_fuse_data_enqueue(irp, fusep);
devredir_fuse_data_enqueue(irp, fusep);
devredir_insert_DeviceIoRequest(s,
DeviceId,
FileId,
@ -1252,8 +1256,9 @@ int dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
* @return FUSE_DATA on success, or NULL on failure
*****************************************************************************/
void *dev_redir_fuse_data_peek(IRP *irp)
void *devredir_fuse_data_peek(IRP *irp)
{
log_debug("returning %p", irp->fd_head);
return irp->fd_head;
}
@ -1263,12 +1268,15 @@ void *dev_redir_fuse_data_peek(IRP *irp)
* @return FUSE_DATA on success, NULL on failure
*****************************************************************************/
void *dev_redir_fuse_data_dequeue(IRP *irp)
void *devredir_fuse_data_dequeue(IRP *irp)
{
FUSE_DATA *head;
if ((irp == NULL) || (irp->fd_head == NULL))
{
log_debug("+++ returning NULL");
return NULL;
}
if (irp->fd_head->next == NULL)
{
@ -1276,13 +1284,16 @@ void *dev_redir_fuse_data_dequeue(IRP *irp)
head = irp->fd_head;
irp->fd_head = NULL;
irp->fd_tail = NULL;
log_debug("+++ returning FUSE_DATA=%p containing FUSE_INFO=%p",
head, head->data_ptr);
return head;
}
/* more than one element in queue */
head = irp->fd_head;
irp->fd_head = head->next;
log_debug("+++ returning FUSE_DATA=%p containing FUSE_INFO=%p",
head, head->data_ptr);
return head;
}
@ -1292,7 +1303,7 @@ void *dev_redir_fuse_data_dequeue(IRP *irp)
* @return 0 on success, -1 on failure
*****************************************************************************/
int dev_redir_fuse_data_enqueue(IRP *irp, void *vp)
int devredir_fuse_data_enqueue(IRP *irp, void *vp)
{
FUSE_DATA *fd;
FUSE_DATA *tail;
@ -1311,6 +1322,8 @@ int dev_redir_fuse_data_enqueue(IRP *irp, void *vp)
/* queue is empty, insert at head */
irp->fd_head = fd;
irp->fd_tail = fd;
log_debug("+++ inserted FUSE_DATA=%p containing FUSE_INFO=%p at head",
fd, vp);
return 0;
}
@ -1318,6 +1331,8 @@ int dev_redir_fuse_data_enqueue(IRP *irp, void *vp)
tail = irp->fd_tail;
tail->next = fd;
irp->fd_tail = fd;
log_debug("+++ inserted FUSE_DATA=%p containing FUSE_INFO=%p at tail",
fd, vp);
return 0;
}
@ -1407,7 +1422,7 @@ void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus)
if (IoStatus != NT_STATUS_SUCCESS)
{
FUSE_DATA *fuse_data = dev_redir_fuse_data_dequeue(irp);
FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data)
{
xfuse_devredir_cb_rmdir_or_file(fuse_data->data_ptr, IoStatus);
@ -1440,7 +1455,7 @@ void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus)
{
FUSE_DATA *fuse_data;
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data)
{
xfuse_devredir_cb_rmdir_or_file(fuse_data->data_ptr, IoStatus);
@ -1474,7 +1489,7 @@ void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus)
{
log_debug("rename returned with IoStatus=0x%x", IoStatus);
FUSE_DATA *fuse_data = dev_redir_fuse_data_dequeue(irp);
FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data)
{
xfuse_devredir_cb_rename_file(fuse_data->data_ptr, IoStatus);
@ -1519,7 +1534,7 @@ void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus)
log_debug("entered");
fuse_data = dev_redir_fuse_data_dequeue(irp);
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data)
{
xfuse_devredir_cb_rename_file(fuse_data->data_ptr, IoStatus);

View File

@ -27,9 +27,9 @@
#define USE_SHORT_NAMES_IN_DIR_LISTING
void *dev_redir_fuse_data_peek(IRP *irp);
void *dev_redir_fuse_data_dequeue(IRP *irp);
int dev_redir_fuse_data_enqueue(IRP *irp, void *vp);
void *devredir_fuse_data_peek(IRP *irp);
void *devredir_fuse_data_dequeue(IRP *irp);
int devredir_fuse_data_enqueue(IRP *irp, void *vp);
int APP_CC dev_redir_init(void);
int APP_CC dev_redir_deinit(void);

View File

@ -31,7 +31,7 @@
#define LOG_DEBUG 2
#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_DEBUG
#define LOG_LEVEL LOG_ERROR
#endif
#define log_error(_params...) \
@ -95,6 +95,7 @@ IRP * devredir_irp_new()
irp->prev = irp_last;
}
log_debug("new IRP=%p", irp);
return irp;
}
@ -108,12 +109,12 @@ int devredir_irp_delete(IRP *irp)
{
IRP *lirp = g_irp_head;
log_debug("=== entered; completion_id=%d type=%d",
irp->CompletionId, irp->completion_type);
if ((irp == NULL) || (lirp == NULL))
return -1;
log_debug("irp=%p completion_id=%d type=%d",
irp, irp->CompletionId, irp->completion_type);
devredir_irp_dump(); // LK_TODO
while (lirp)
@ -173,11 +174,15 @@ IRP *devredir_irp_find(tui32 completion_id)
while (irp)
{
if (irp->CompletionId == completion_id)
{
log_debug("returning irp=%p", irp);
return irp;
}
irp = irp->next;
}
log_debug("returning irp=NULL");
return NULL;
}
@ -188,11 +193,15 @@ IRP * devredir_irp_find_by_fileid(tui32 FileId)
while (irp)
{
if (irp->FileId == FileId)
{
log_debug("returning irp=%p", irp);
return irp;
}
irp = irp->next;
}
log_debug("returning irp=NULL");
return NULL;
}
@ -212,6 +221,7 @@ IRP * devredir_irp_get_last()
irp = irp->next;
}
log_debug("returning irp=%p", irp);
return irp;
}