diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 178d1ded..62ee050a 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -638,6 +638,7 @@ int xfuse_create_share(tui32 device_id, const char *dirname) } else { + xinode->is_redirected = 1; xinode->device_id = device_id; result = 0; } @@ -654,7 +655,7 @@ int xfuse_create_share(tui32 device_id, const char *dirname) 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 { - if (parent_xinode->device_id == 0) + if (!parent_xinode->is_redirected) { /* File cannot be remote - we either know about it or we don't */ 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); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ //XFUSE_HANDLE *fh; @@ -1764,12 +1765,13 @@ static void xfuse_cb_rename(fuse_req_t req, 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); } - else if (old_xinode->device_id == 0) + else if (!old_xinode->is_redirected) { /* specified file is a local resource */ 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); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ //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"); fuse_reply_err(req, EINVAL); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ 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); fuse_reply_err(req, ENOENT); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ 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 */ make_fuse_attr_reply(req, xinode); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* Update the local fs */ 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); 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) { diff --git a/sesman/chansrv/chansrv_xfs.c b/sesman/chansrv/chansrv_xfs.c index a5f009d2..5e75650c 100644 --- a/sesman/chansrv/chansrv_xfs.c +++ b/sesman/chansrv/chansrv_xfs.c @@ -344,6 +344,7 @@ xfs_create_xfs_fs(mode_t umask, uid_t uid, gid_t gid) xino1->pub.ctime = xino1->pub.atime; strcpy(xino1->pub.name, "."); xino1->pub.generation = xfs->generation; + xino1->pub.is_redirected = 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; strcpy(xino2->pub.name, ".delete-pending"); xino2->pub.generation = xfs->generation; + xino2->pub.is_redirected = 0; xino2->pub.device_id = 0; 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; strcpy(xino->pub.name, name); xino->pub.generation = xfs->generation; + xino->pub.is_redirected = parent->pub.is_redirected; xino->pub.device_id = parent->pub.device_id; xino->pub.lindex = 0; @@ -816,35 +819,35 @@ xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum) /* ------------------------------------------------------------------------ */ 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; 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 - * 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) + if ((xino = xfs->inode_table[inum]) != NULL && + xino->pub.is_redirected != 0 && + xino->pub.device_id == device_id && + (xino->pub.mode & S_IFREG) != 0) { - if ((xino = xfs->inode_table[inum]) != NULL && - xino->pub.device_id == device_id && - (xino->pub.mode & S_IFREG) != 0) - { - xino->open_count = 0; - } + xino->open_count = 0; } + } - /* Now we can be sure everything will be deleted correctly */ - for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum) + /* Now we can be sure everything will be deleted correctly */ + 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 && - xino->pub.device_id == device_id) - { - xfs_remove_entry(xfs, xino->pub.inum); - } + xfs_remove_entry(xfs, xino->pub.inum); } } } diff --git a/sesman/chansrv/chansrv_xfs.h b/sesman/chansrv/chansrv_xfs.h index 17dc7b4f..76fa1682 100644 --- a/sesman/chansrv/chansrv_xfs.h +++ b/sesman/chansrv/chansrv_xfs.h @@ -49,9 +49,8 @@ typedef struct xfs_inode time_t ctime; /* Time of last status change. */ char name[XFS_MAXFILENAMELEN + 1]; /* Short name */ tui32 generation; /* Changes if inode is reused */ - tui32 device_id; /* for file system redirection - * Non-redirected devices are guaranteed - * to have a device_id or zero */ + char is_redirected; /* file is on redirected device */ + tui32 device_id; /* device ID of redirected device */ int lindex; /* used in clipboard operations */ } XFS_INODE; @@ -271,17 +270,15 @@ unsigned int 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 * - * The specified device_id must be non-zero so that the root - * filesystem is not deleted! - * * @param device_id Device ID */ 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