|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT VFS PATCH v2 1/4] Fix dentry referecing and file closing
Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx>
On 6/29/19 2:12 PM, Mihai Pogonaru wrote:
> Increase the refcount of the vfscore_file's dentry when opening it.
> This is the OSv behaviour since each vfscore_file has an intrusive_ptr
> ref to its dentry, which increases dentry's refcount on creation and
> decreases dentry's refcount on deletion. We must increase the dentry's
> refcount since we might end up with files pointing to deleted dentries,
> if the actual file/directory the dentry refers gets deleted (so the
> dentry's refcount hits 0 and it gets freed).
>
> We must also decrease the refcount of the dentry on file closing.
>
> The statement "Dentry stays forever in the dentry cache. Unless the
> file/directory it refers to gets deleted/renamed" doesn't hold for
> file systems that do not save their structures on permanent mediums
> (like LWIP's sockets abstraction) so the dentry refcount is equal to
> the number of vfscore_file's pointing at it (so the dentry gets
> deleted as soon as the last file is closed).
>
> Right now the vfscore_file is never freed, excepting the LWIP socket's
> file which is freed inside sock_net_close along with its dentry and
> vnode. This should not be the expected behaviour from a underlying
> file system (ramfs provides a good example of expected behaviour).
> As such, we must free the vfscore_file when closing it and release its
> dentry so the dentry and vnode freeing will be handled by vfs as well.
>
> This patch also makes fdrop return 0 if the file's refcount hits
> 0 or return 1 otherwise. This is the OSv behaviour and the return
> of an error from fdrop is never checked.
>
> Signed-off-by: Mihai Pogonaru <pogonarumihai@xxxxxxxxx>
> ---
> lib/vfscore/file.c | 18 ++++++++++++++----
> lib/vfscore/fops.c | 7 ++++---
> lib/vfscore/syscalls.c | 3 +++
> 3 files changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/lib/vfscore/file.c b/lib/vfscore/file.c
> index e56f16dc..e7627e96 100644
> --- a/lib/vfscore/file.c
> +++ b/lib/vfscore/file.c
> @@ -42,15 +42,25 @@
>
> int fdrop(struct vfscore_file *fp)
> {
> - int ret = 0;
> int prev = ukarch_dec(&fp->f_count);
>
> if (prev == 0)
> UK_CRASH("Unbalanced fhold/fdrop");
>
> - if (prev == 1)
> - ret = vfs_close(fp);
> - return ret;
> + if (prev == 1) {
> + /*
> + * we free the file even in case of an error
> + * so release the dentry too
> + */
> + if (vfs_close(fp) != 0)
> + drele(fp->f_dentry);
> +
> + free(fp);
> +
> + return 1;
> + }
> +
> + return 0;
> }
> void fhold(struct vfscore_file *fp)
> {
> diff --git a/lib/vfscore/fops.c b/lib/vfscore/fops.c
> index 8f5c2e1b..0cef2c12 100644
> --- a/lib/vfscore/fops.c
> +++ b/lib/vfscore/fops.c
> @@ -53,9 +53,10 @@ int vfs_close(struct vfscore_file *fp)
> if (error)
> return error;
>
> - /* Dentry stays forever in the dentry cache. Unless the
> - * file/directory it refers to gets deleted/renamed */
> + /* Release the dentry */
> + drele(fp->f_dentry);
> fp->f_dentry = NULL;
> +
> return 0;
> }
>
> @@ -103,7 +104,7 @@ int vfs_write(struct vfscore_file *fp, struct uio *uio,
> int flags)
> ioflags |= IO_SYNC;
>
> if ((flags & FOF_OFFSET) == 0)
> - uio->uio_offset = fp->f_offset;
> + uio->uio_offset = fp->f_offset;
>
> error = VOP_WRITE(vp, uio, ioflags);
> if (!error) {
> diff --git a/lib/vfscore/syscalls.c b/lib/vfscore/syscalls.c
> index 385d90c0..f9666c4c 100644
> --- a/lib/vfscore/syscalls.c
> +++ b/lib/vfscore/syscalls.c
> @@ -204,6 +204,8 @@ sys_open(char *path, int flags, mode_t mode, struct
> vfscore_file **fpp)
> }
> fp->f_flags = flags;
>
> + // OSv was using a intrusive_ptr which was increasing the refcount
> + dref(dp);
> // change to std::move once dp is a dentry_ref
> fp->f_dentry = dp;
> dp = NULL;
> @@ -214,6 +216,7 @@ sys_open(char *path, int flags, mode_t mode, struct
> vfscore_file **fpp)
> // Note direct delete of fp instead of fdrop(fp). fp was never
> // returned so cannot be in use, and because it wasn't opened
> // it cannot be close()ed.
> + drele(fp->f_dentry);
> free(fp);
> return error;
> }
>
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |