fuse: added support for detecting files/directories deleted locally

This commit is contained in:
Laxmikant Rashinkar 2013-08-09 19:43:45 -07:00
parent 474d17d556
commit 23433c9c7e
2 changed files with 139 additions and 7 deletions

View File

@ -125,6 +125,13 @@ void xfuse_devredir_cb_file_close(void *vp) {}
g_writeln (_params); \ g_writeln (_params); \
} }
#define log_always(_params...) \
{ \
g_write("[%10.10u]: FUSE %s: %d : ALWAYS: ", \
g_time3(), __func__, __LINE__); \
g_writeln (_params); \
}
#define log_info(_params...) \ #define log_info(_params...) \
{ \ { \
if (LOG_INFO <= LOG_LEVEL) \ if (LOG_INFO <= LOG_LEVEL) \
@ -249,6 +256,7 @@ static int xfuse_does_file_exist(int parent, char *name);
static int xfuse_delete_file(int parent, char *name); static int xfuse_delete_file(int parent, char *name);
static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode); static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode);
static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode); static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode);
static int xfuse_recursive_delete_dir_with_xinode(XRDP_INODE *xinode);
static void xfuse_update_xrdpfs_size(); static void xfuse_update_xrdpfs_size();
static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size, static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi); off_t off, struct fuse_file_info *fi);
@ -331,6 +339,10 @@ int clipboard_request_file_data(int stream_id, int lindex, int offset,
static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi); int to_set, struct fuse_file_info *fi);
/* misc calls */
static void xfuse_mark_as_stale(int pinode);
static void xfuse_delete_stale_entries(int pinode);
/***************************************************************************** /*****************************************************************************
** ** ** **
** public functions - can be called from any code path ** ** public functions - can be called from any code path **
@ -1245,6 +1257,52 @@ static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode)
return 0; return 0;
} }
/**
* Recursively delete dir with specified inode
*****************************************************************************/
static int xfuse_recursive_delete_dir_with_xinode(XRDP_INODE *xinode)
{
XRDP_INODE *xip;
int i;
/* make sure it is not a file */
if ((xinode == NULL) || (xinode->mode & S_IFREG))
return -1;
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
{
if ((xip = g_xrdp_fs.inode_table[i]) == NULL)
continue;
/* look for child inodes */
if (xip->parent_inode == xinode->inode)
{
/* got one */
if (xip->mode & S_IFREG)
{
/* regular file */
g_xrdp_fs.inode_table[xip->parent_inode]->nentries--;
g_xrdp_fs.inode_table[xip->inode] = NULL;
free(xip);
}
else
{
/* got another dir */
xfuse_recursive_delete_dir_with_xinode(xip);
}
}
}
/* our parent will have one less dir */
g_xrdp_fs.inode_table[xinode->parent_inode]->nentries--;
g_xrdp_fs.inode_table[xinode->inode] = NULL;
free(xinode);
return 0;
}
static void xfuse_update_xrdpfs_size() static void xfuse_update_xrdpfs_size()
{ {
void *vp; void *vp;
@ -1365,7 +1423,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it", log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
fip->inode, xinode->name); fip->inode, xinode->name);
free(xinode); free(xinode);
xinode = xip; xip->stale = 0;
return; return;
} }
@ -1407,8 +1465,6 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
goto done; goto done;
} }
log_debug("fip->req=%p", fip->req);
if (IoStatus != 0) if (IoStatus != 0)
{ {
/* command failed */ /* command failed */
@ -1425,6 +1481,9 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
fuse_reply_err(fip->req, EBADF); fuse_reply_err(fip->req, EBADF);
goto done; goto done;
} }
xfuse_delete_stale_entries(fip->inode);
#if 0 #if 0
memset(&b, 0, sizeof(struct dirbuf)); memset(&b, 0, sizeof(struct dirbuf));
#else #else
@ -2096,7 +2155,10 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
do_remote_lookup: do_remote_lookup:
xfuse_mark_as_stale((int) ino);
log_debug("did not find entry; redirecting call to dev_redir"); log_debug("did not find entry; redirecting call to dev_redir");
device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path); device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
log_debug("dev_id=%d ino=%d full_path=%s", device_id, ino, full_path); log_debug("dev_id=%d ino=%d full_path=%s", device_id, ino, full_path);
@ -2925,4 +2987,73 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
fuse_reply_attr(req, &st, 1.0); /* LK_TODO just faking for now */ fuse_reply_attr(req, &st, 1.0); /* LK_TODO just faking for now */
} }
/******************************************************************************
* miscellaneous functions
*****************************************************************************/
/**
* Mark all files with matching parent inode as stale
*
* @param pinode the parent inode
*****************************************************************************/
static void
xfuse_mark_as_stale(int pinode)
{
int i;
XRDP_INODE *xinode;
if ((pinode < FIRST_INODE) || (pinode >= g_xrdp_fs.num_entries))
return;
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
{
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
continue;
/* match parent inode */
if (xinode->parent_inode != pinode)
continue;
/* got a match */
xinode->stale = 1;
}
}
/**
* Delete all files with matching parent inode that are marked as stale
*
* @param pinode the parent inode
*****************************************************************************/
static void
xfuse_delete_stale_entries(int pinode)
{
int i;
XRDP_INODE *xinode;
if ((pinode < FIRST_INODE) || (pinode >= g_xrdp_fs.num_entries))
return;
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
{
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
continue;
/* match parent inode */
if (xinode->parent_inode != pinode)
continue;
/* got a match, but is it stale? */
if (!xinode->stale)
continue;
/* ok to delete */
if (xinode->mode & S_IFREG)
xfuse_delete_file_with_xinode(xinode);
else
xfuse_recursive_delete_dir_with_xinode(xinode);
}
}
#endif /* end else #ifndef XRDP_FUSE */ #endif /* end else #ifndef XRDP_FUSE */

View File

@ -41,6 +41,7 @@ struct xrdp_inode
int lindex; /* used in clipboard operations */ int lindex; /* used in clipboard operations */
int is_loc_resource; /* this is not a redirected resource */ int is_loc_resource; /* this is not a redirected resource */
int close_in_progress; /* close cmd sent to client */ int close_in_progress; /* close cmd sent to client */
int stale; /* mark file as stale, ok to remove */
}; };
typedef struct xrdp_inode XRDP_INODE; // LK_TODO use this instead of using struct xrdp_inode typedef struct xrdp_inode XRDP_INODE; // LK_TODO use this instead of using struct xrdp_inode