[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH 7/7] lib/9pfs: Simplify the logic for removes
The logic for unlinking is simplified, either: - there are no open files, remove now; - there are open files, defer until all open files are closed This is now possible since successive open and closes update the dentry reference count correctly, so VOP_INACTIVE is called in time to free the fid before the qid starts being reused on the server-side (and we get an inode collision). This also means that on unmounting, releasing all non-root dentries and calling vfscore_release_mp_dentries() for m_covered and m_root is enough to ensure all fids are clunked before disconnecting. Signed-off-by: Cristian Banu <cristb@xxxxxxxxx> --- lib/9pfs/9pfs_vfsops.c | 7 +++---- lib/9pfs/9pfs_vnops.c | 37 +++++++++++-------------------------- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/lib/9pfs/9pfs_vfsops.c b/lib/9pfs/9pfs_vfsops.c index accb3a5..5293b22 100644 --- a/lib/9pfs/9pfs_vfsops.c +++ b/lib/9pfs/9pfs_vfsops.c @@ -169,11 +169,10 @@ static void uk_9pfs_release_tree_fids(struct dentry *d) { struct dentry *p; - uk_list_for_each_entry(p, &d->d_child_list, d_child_link) + uk_list_for_each_entry(p, &d->d_child_list, d_child_link) { uk_9pfs_release_tree_fids(p); - - if (d->d_vnode->v_data) - uk_9pfs_free_vnode_data(d->d_vnode); + drele(p); + } } static int uk_9pfs_unmount(struct mount *mp, int flags __unused) diff --git a/lib/9pfs/9pfs_vnops.c b/lib/9pfs/9pfs_vnops.c index 6d3ece3..c81c82a 100644 --- a/lib/9pfs/9pfs_vnops.c +++ b/lib/9pfs/9pfs_vnops.c @@ -147,7 +147,7 @@ void uk_9pfs_free_vnode_data(struct vnode *vp) struct uk_9pdev *dev = UK_9PFS_MD(vp->v_mount)->dev; struct uk_9pfs_node_data *nd = UK_9PFS_ND(vp); - if (nd->nb_open_files > 0) + if (!vp->v_data) return; if (nd->removed) @@ -158,20 +158,6 @@ void uk_9pfs_free_vnode_data(struct vnode *vp) vp->v_data = NULL; } -/* - * The closing variant of the function will enforce freeing the associated - * resources only if the vnode was removed via an unlink/rmdir operation. - */ -static void uk_9pfs_free_vnode_data_closing(struct vnode *vp) -{ - struct uk_9pfs_node_data *nd = UK_9PFS_ND(vp); - - if (!nd->removed) - return; - - uk_9pfs_free_vnode_data(vp); -} - static int uk_9pfs_open(struct vfscore_file *file) { struct uk_9pdev *dev = UK_9PFS_MD(file->f_dentry->d_mount)->dev; @@ -222,7 +208,6 @@ static int uk_9pfs_close(struct vnode *vn __unused, struct vfscore_file *file) uk_9pfid_put(fd->fid); free(fd); UK_9PFS_ND(file->f_dentry->d_vnode)->nb_open_files--; - uk_9pfs_free_vnode_data_closing(file->f_dentry->d_vnode); return 0; } @@ -327,22 +312,22 @@ static int uk_9pfs_remove_generic(struct vnode *dvp, struct vnode *vp) { struct uk_9pdev *dev = UK_9PFS_MD(dvp->v_mount)->dev; struct uk_9pfs_node_data *nd = UK_9PFS_ND(vp); - int rc = 0; - - if (!nd->removed && !nd->nb_open_files) - rc = uk_9p_remove(dev, nd->fid); - else - nd->removed = true; - - uk_9pfs_free_vnode_data(vp); - return -rc; + return -uk_9p_remove(dev, nd->fid); } static int uk_9pfs_remove(struct vnode *dvp, struct vnode *vp, char *name __unused) { - return uk_9pfs_remove_generic(dvp, vp); + struct uk_9pfs_node_data *nd = UK_9PFS_ND(vp); + int rc = 0; + + if (!nd->nb_open_files) + rc = uk_9pfs_remove_generic(dvp, vp); + else + nd->removed = true; + + return rc; } static int uk_9pfs_mkdir(struct vnode *dvp, char *name, mode_t mode) -- 2.26.2
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |